From: Zoran V. <vas...@us...> - 2005-10-08 12:06:21
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7712/nsd Modified Files: adpeval.c adprequest.c binder.c config.c conn.c driver.c fastpath.c init.c log.c modload.c nsconf.c nsmain.c pidfile.c rollfile.c tclcmds.c tclfile.c tclimg.c urlopen.c Log Message: Applied TclVFS changes. Use (where possible) Tcl_FS wrappers when handling files on the filesystem. Index: init.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/init.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** init.c 10 Jun 2005 17:58:39 -0000 1.4 --- init.c 8 Oct 2005 12:06:07 -0000 1.5 *************** *** 52,55 **** --- 52,59 ---- * Side effects: * Numerous. + * Also, note that this one is called prior getting the Tcl library + * initialized by calling Tcl_FindExecutable() in nsmain(). + * Therefore, no Tcl VFS calls to the filesystem should be done in + * any of the NsInitX() below. * *---------------------------------------------------------------------- Index: urlopen.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/urlopen.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** urlopen.c 10 Jun 2005 17:58:41 -0000 1.3 --- urlopen.c 8 Oct 2005 12:06:07 -0000 1.4 *************** *** 1,7 **** /* ! * The contents of this file are subject to the AOLserver Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at ! * http://aolserver.com/. * * Software distributed under the License is distributed on an "AS IS" --- 1,7 ---- /* ! * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at ! * http://mozilla.org/. * * Software distributed under the License is distributed on an "AS IS" *************** *** 31,35 **** * urlopen.c -- * ! * Make outgoing HTTP requests. */ --- 31,35 ---- * urlopen.c -- * ! * Make outgoing HTTP requests. */ *************** *** 42,50 **** typedef struct Stream { ! SOCKET sock; ! int error; ! int cnt; char *ptr; ! char buf[BUFSIZE+1]; } Stream; --- 42,50 ---- typedef struct Stream { ! SOCKET sock; ! int error; ! int cnt; char *ptr; ! char buf[BUFSIZE+1]; } Stream; *************** *** 62,73 **** * Ns_FetchPage -- * ! * Fetch a page off of this very server. Url must reference a ! * file in the filesystem. * * Results: ! * NS_OK or NS_ERROR. * * Side effects: ! * The file contents will be put into the passed-in dstring. * *---------------------------------------------------------------------- --- 62,73 ---- * Ns_FetchPage -- * ! * Fetch a page off of this very server. Url must reference a ! * file in the filesystem. * * Results: ! * NS_OK or NS_ERROR. * * Side effects: ! * The file contents will be put into the passed-in dstring. * *---------------------------------------------------------------------- *************** *** 77,96 **** Ns_FetchPage(Ns_DString *dsPtr, char *url, char *server) { ! Ns_DString path; ! int fd; ! int nread; ! char buf[1024]; ! Ns_DStringInit(&path); ! Ns_UrlToFile(&path, server, url); ! fd = open(path.string, O_RDONLY|O_BINARY); ! Ns_DStringFree(&path); ! if (fd < 0) { ! return NS_ERROR; } ! while ((nread = read(fd, buf, sizeof(buf))) > 0) { ! Ns_DStringNAppend(dsPtr, buf, nread); } ! close(fd); return NS_OK; } --- 77,106 ---- Ns_FetchPage(Ns_DString *dsPtr, char *url, char *server) { ! Ns_DString ds; ! Tcl_Channel chan = NULL; ! int nread, fd = -1; ! char buf[1024]; ! Ns_DStringInit(&ds); ! Ns_UrlToFile(&ds, server, url); ! fd = open(ds.string, O_RDONLY|O_BINARY); ! if (fd == -1) { ! chan = Tcl_OpenFileChannel(NULL, ds.string, "r", 0); } ! Ns_DStringFree(&ds); ! if (fd >= 0) { ! while ((nread = read(fd, buf, sizeof(buf))) > 0) { ! Ns_DStringNAppend(dsPtr, buf, nread); ! } ! close(fd); ! } else if (chan) { ! while ((nread = Tcl_Read(chan, buf, sizeof(buf))) > 0) { ! Ns_DStringNAppend(dsPtr, buf, nread); ! } ! Tcl_Close(NULL, chan); ! } else { ! return NS_ERROR; } ! return NS_OK; } *************** *** 102,114 **** * Ns_FetchURL -- * ! * Open up an HTTP connection to an arbitrary URL. * * Results: ! * NS_OK or NS_ERROR. * * Side effects: ! * Page contents will be appended to the passed-in dstring. ! * Headers returned to us will be put into the passed-in Ns_Set. ! * The set name will be changed to a copy of the HTTP status line. * *---------------------------------------------------------------------- --- 112,124 ---- * Ns_FetchURL -- * ! * Open up an HTTP connection to an arbitrary URL. * * Results: ! * NS_OK or NS_ERROR. * * Side effects: ! * Page contents will be appended to the passed-in dstring. ! * Headers returned to us will be put into the passed-in Ns_Set. ! * The set name will be changed to a copy of the HTTP status line. * *---------------------------------------------------------------------- *************** *** 118,127 **** Ns_FetchURL(Ns_DString *dsPtr, char *url, Ns_Set *headers) { ! SOCKET sock; ! char *p; Ns_DString ds; ! Stream stream; Ns_Request *request; ! int status, n; unsigned int tosend; --- 128,137 ---- Ns_FetchURL(Ns_DString *dsPtr, char *url, Ns_Set *headers) { ! SOCKET sock; ! char *p; Ns_DString ds; ! Stream stream; Ns_Request *request; ! int status, n; unsigned int tosend; *************** *** 137,141 **** request = Ns_ParseRequest(ds.string); if (request == NULL || request->protocol == NULL || ! !STREQ(request->protocol, "http") || request->host == NULL) { Ns_Log(Notice, "urlopen: invalid url '%s'", url); goto done; --- 147,151 ---- request = Ns_ParseRequest(ds.string); if (request == NULL || request->protocol == NULL || ! !STREQ(request->protocol, "http") || request->host == NULL) { Ns_Log(Notice, "urlopen: invalid url '%s'", url); goto done; *************** *** 146,152 **** sock = Ns_SockConnect(request->host, request->port); if (sock == INVALID_SOCKET) { ! Ns_Log(Error, "urlopen: failed to connect to '%s': '%s'", ! url, ns_sockstrerror(ns_sockerrno)); ! goto done; } --- 156,162 ---- sock = Ns_SockConnect(request->host, request->port); if (sock == INVALID_SOCKET) { ! Ns_Log(Error, "urlopen: failed to connect to '%s': '%s'", ! url, ns_sockstrerror(ns_sockerrno)); ! goto done; } *************** *** 167,175 **** if (n == SOCKET_ERROR) { Ns_Log(Error, "urlopen: failed to send data to '%s': '%s'", ! url, ns_sockstrerror(ns_sockerrno)); goto done; } tosend -= n; ! p += n; } --- 177,185 ---- if (n == SOCKET_ERROR) { Ns_Log(Error, "urlopen: failed to send data to '%s': '%s'", ! url, ns_sockstrerror(ns_sockerrno)); goto done; } tosend -= n; ! p += n; } *************** *** 184,218 **** stream.sock = sock; if (!GetLine(&stream, &ds)) { ! goto done; } if (headers != NULL && strncmp(ds.string, "HTTP", 4) == 0) { ! if (headers->name != NULL) { ! ns_free(headers->name); ! } ! headers->name = Ns_DStringExport(&ds); } do { ! if (!GetLine(&stream, &ds)) { ! goto done; ! } ! if (ds.length > 0 ! && headers != NULL ! && Ns_ParseHeader(headers, ds.string, Preserve) != NS_OK) { ! goto done; ! } } while (ds.length > 0); ! /* * Without any check on limit or total size, foolishly read * the remaining content into the dstring. */ ! do { ! Ns_DStringNAppend(dsPtr, stream.ptr, stream.cnt); } while (FillBuf(&stream)); if (!stream.error) { ! status = NS_OK; } ! done: if (request != NULL) { --- 194,228 ---- stream.sock = sock; if (!GetLine(&stream, &ds)) { ! goto done; } if (headers != NULL && strncmp(ds.string, "HTTP", 4) == 0) { ! if (headers->name != NULL) { ! ns_free(headers->name); ! } ! headers->name = Ns_DStringExport(&ds); } do { ! if (!GetLine(&stream, &ds)) { ! goto done; ! } ! if (ds.length > 0 ! && headers != NULL ! && Ns_ParseHeader(headers, ds.string, Preserve) != NS_OK) { ! goto done; ! } } while (ds.length > 0); ! /* * Without any check on limit or total size, foolishly read * the remaining content into the dstring. */ ! do { ! Ns_DStringNAppend(dsPtr, stream.ptr, stream.cnt); } while (FillBuf(&stream)); if (!stream.error) { ! status = NS_OK; } ! done: if (request != NULL) { *************** *** 223,226 **** --- 233,237 ---- } Ns_DStringFree(&ds); + return status; } *************** *** 232,242 **** * NsTclGetUrlObjCmd -- * ! * Implements ns_geturl. * * Results: ! * Tcl result. * * Side effects: ! * See docs. * *---------------------------------------------------------------------- --- 243,253 ---- * NsTclGetUrlObjCmd -- * ! * Implements ns_geturl. * * Results: ! * Tcl result. * * Side effects: ! * See docs. * *---------------------------------------------------------------------- *************** *** 244,250 **** int ! NsTclGetUrlObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ! NsInterp *itPtr = arg; Ns_DString ds; Ns_Set *headers; --- 255,262 ---- int ! NsTclGetUrlObjCmd(ClientData arg, Tcl_Interp *interp, int objc, ! Tcl_Obj *CONST objv[]) { ! NsInterp *itPtr = arg; Ns_DString ds; Ns_Set *headers; *************** *** 264,293 **** } Ns_DStringInit(&ds); ! url = Tcl_GetString(objv[1]); if (url[1] == '/') { ! status = Ns_FetchPage(&ds, Tcl_GetString(objv[1]), itPtr->servPtr->server); } else { ! status = Ns_FetchURL(&ds, Tcl_GetString(objv[1]), headers); } if (status != NS_OK) { ! Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not fetch: ", ! Tcl_GetString(objv[1]), NULL); ! if (headers != NULL) { ! Ns_SetFree(headers); ! } ! goto done; } if (objc == 3) { Ns_TclEnterSet(interp, headers, NS_TCL_SET_DYNAMIC); if (Tcl_ObjSetVar2(interp, objv[2], NULL, Tcl_GetObjResult(interp), ! TCL_LEAVE_ERR_MSG) == NULL) { ! goto done; ! } } Tcl_SetResult(interp, ds.string, TCL_VOLATILE); code = TCL_OK; - done: Ns_DStringFree(&ds); return code; } --- 276,305 ---- } Ns_DStringInit(&ds); ! url = Tcl_GetString(objv[1]); if (url[1] == '/') { ! status = Ns_FetchPage(&ds, url, itPtr->servPtr->server); } else { ! status = Ns_FetchURL(&ds, url, headers); } if (status != NS_OK) { ! Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not fetch: ", ! Tcl_GetString(objv[1]), NULL); ! if (headers != NULL) { ! Ns_SetFree(headers); ! } ! goto done; } if (objc == 3) { Ns_TclEnterSet(interp, headers, NS_TCL_SET_DYNAMIC); if (Tcl_ObjSetVar2(interp, objv[2], NULL, Tcl_GetObjResult(interp), ! TCL_LEAVE_ERR_MSG) == NULL) { ! goto done; ! } } Tcl_SetResult(interp, ds.string, TCL_VOLATILE); code = TCL_OK; done: Ns_DStringFree(&ds); + return code; } *************** *** 299,309 **** * FillBuf -- * ! * Fill the socket stream buffer. * * Results: ! * 1 if fill ok, 0 otherwise. * * Side effects: ! * None. * *---------------------------------------------------------------------- --- 311,321 ---- * FillBuf -- * ! * Fill the socket stream buffer. * * Results: ! * 1 if fill ok, 0 otherwise. * * Side effects: ! * None. * *---------------------------------------------------------------------- *************** *** 317,330 **** n = recv(sPtr->sock, sPtr->buf, BUFSIZE, 0); if (n <= 0) { ! if (n < 0) { ! Ns_Log(Error, "urlopen: " ! "failed to fill socket stream buffer: '%s'", strerror(errno)); ! sPtr->error = 1; ! } ! return 0; } sPtr->buf[n] = '\0'; sPtr->ptr = sPtr->buf; sPtr->cnt = n; return 1; } --- 329,345 ---- n = recv(sPtr->sock, sPtr->buf, BUFSIZE, 0); if (n <= 0) { ! if (n < 0) { ! Ns_Log(Error, "urlopen: " ! "failed to fill socket stream buffer: '%s'", ! strerror(errno)); ! sPtr->error = 1; ! } ! return 0; } + sPtr->buf[n] = '\0'; sPtr->ptr = sPtr->buf; sPtr->cnt = n; + return 1; } *************** *** 336,347 **** * GetLine -- * ! * Copy the next line from the stream to a dstring, trimming ! * the \n and \r. * * Results: ! * 1 or 0. * * Side effects: ! * The dstring is truncated on entry. * *---------------------------------------------------------------------- --- 351,362 ---- * GetLine -- * ! * Copy the next line from the stream to a dstring, trimming ! * the \n and \r. * * Results: ! * 1 or 0. * * Side effects: ! * The dstring is truncated on entry. * *---------------------------------------------------------------------- *************** *** 356,379 **** Ns_DStringTrunc(dsPtr, 0); do { ! if (sPtr->cnt > 0) { ! eol = strchr(sPtr->ptr, '\n'); ! if (eol == NULL) { ! n = sPtr->cnt; ! } else { ! *eol++ = '\0'; ! n = eol - sPtr->ptr; ! } ! Ns_DStringNAppend(dsPtr, sPtr->ptr, n - 1); ! sPtr->ptr += n; ! sPtr->cnt -= n; ! if (eol != NULL) { ! n = dsPtr->length; ! if (n > 0 && dsPtr->string[n-1] == '\r') { ! Ns_DStringTrunc(dsPtr, n-1); ! } ! return 1; ! } ! } } while (FillBuf(sPtr)); return 0; } --- 371,395 ---- Ns_DStringTrunc(dsPtr, 0); do { ! if (sPtr->cnt > 0) { ! eol = strchr(sPtr->ptr, '\n'); ! if (eol == NULL) { ! n = sPtr->cnt; ! } else { ! *eol++ = '\0'; ! n = eol - sPtr->ptr; ! } ! Ns_DStringNAppend(dsPtr, sPtr->ptr, n - 1); ! sPtr->ptr += n; ! sPtr->cnt -= n; ! if (eol != NULL) { ! n = dsPtr->length; ! if (n > 0 && dsPtr->string[n-1] == '\r') { ! Ns_DStringTrunc(dsPtr, n-1); ! } ! return 1; ! } ! } } while (FillBuf(sPtr)); + return 0; } Index: adprequest.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/adprequest.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** adprequest.c 2 Oct 2005 22:23:09 -0000 1.7 --- adprequest.c 8 Oct 2005 12:06:07 -0000 1.8 *************** *** 105,109 **** */ ! if (access(file, R_OK) != 0) { return Ns_ConnReturnNotFound(conn); } --- 105,109 ---- */ ! if (access(file, R_OK) != 0 && Tcl_Access(file, R_OK) != 0) { return Ns_ConnReturnNotFound(conn); } Index: pidfile.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/pidfile.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pidfile.c 10 Jun 2005 17:58:39 -0000 1.2 --- pidfile.c 8 Oct 2005 12:06:07 -0000 1.3 *************** *** 1,7 **** /* ! * The contents of this file are subject to the AOLserver Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at ! * http://aolserver.com/. * * Software distributed under the License is distributed on an "AS IS" --- 1,7 ---- /* ! * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at ! * http://mozilla.org/. * * Software distributed under the License is distributed on an "AS IS" *************** *** 32,36 **** * pidfile.c -- * ! * Implement the PID file routines. */ --- 32,36 ---- * pidfile.c -- * ! * Implement the PID file routines. */ *************** *** 49,61 **** *---------------------------------------------------------------------- * ! * NsCreatePidFile, NsRemovePidFile -- * ! * Create/remove file with current pid. * * Results: ! * None. * * Side effects: ! * None. * *---------------------------------------------------------------------- --- 49,61 ---- *---------------------------------------------------------------------- * ! * NsCreatePidFile -- * ! * Create file with current pid. * * Results: ! * None. * * Side effects: ! * None. * *---------------------------------------------------------------------- *************** *** 65,95 **** NsCreatePidFile(char *procname) { ! int fd, n; ! char buf[10]; ! char *file = GetFile(procname); ! fd = open(file, O_WRONLY|O_TRUNC|O_CREAT, 0644); ! if (fd < 0) { Ns_Log(Error, "pidfile: failed to open pid file '%s': '%s'", ! file, strerror(errno)); } else { ! sprintf(buf, "%d\n", nsconf.pid); ! n = strlen(buf); ! if (write(fd, buf, (size_t)n) != n) { ! Ns_Log(Error, "pidfile: write() failed: '%s'", strerror(errno)); ! } ! close(fd); } } void NsRemovePidFile(char *procname) { ! char *file = GetFile(procname); ! if (unlink(file) != 0) { Ns_Log(Error, "pidfile: failed to remove '%s': '%s'", ! file, strerror(errno)); } } --- 65,118 ---- NsCreatePidFile(char *procname) { ! Tcl_Channel chan; ! int towrite; ! char *file, buf[10]; ! file = GetFile(procname); ! chan = Tcl_OpenFileChannel(NULL, file, "w", 0644); ! if (chan == NULL) { Ns_Log(Error, "pidfile: failed to open pid file '%s': '%s'", ! file, strerror(Tcl_GetErrno())); } else { ! sprintf(buf, "%d\n", nsconf.pid); ! towrite = strlen(buf); ! if (Tcl_WriteChars(chan, buf, towrite) != towrite) { ! Ns_Log(Error, "pidfile: failed to write pid file '%s': '%s'", ! file, strerror(Tcl_GetErrno())); ! } ! Tcl_Close(NULL, chan); } } + + /* + *---------------------------------------------------------------------- + * + * NsRemovePidFile -- + * + * Remove file with current pid. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ void NsRemovePidFile(char *procname) { ! Tcl_Obj *path; ! char *file; ! file = GetFile(procname); ! path = Tcl_NewStringObj(file, -1); ! Tcl_IncrRefCount(path); ! if (Tcl_FSDeleteFile(path) != 0) { Ns_Log(Error, "pidfile: failed to remove '%s': '%s'", ! file, strerror(Tcl_GetErrno())); } + Tcl_DecrRefCount(path); } *************** *** 97,113 **** GetFile(char *procname) { static char *file; if (file == NULL) { file = Ns_ConfigGetValue(NS_CONFIG_PARAMETERS, "pidfile"); ! if (file == NULL) { Ns_DString ds; ! ! Ns_DStringInit(&ds); ! Ns_HomePath(&ds, "log/nspid.", NULL); ! Ns_DStringAppend(&ds, procname); ! file = Ns_DStringExport(&ds); ! } } return file; } --- 120,140 ---- GetFile(char *procname) { + /* + * FIXME: MT-UNSAFE + */ + static char *file; if (file == NULL) { file = Ns_ConfigGetValue(NS_CONFIG_PARAMETERS, "pidfile"); ! if (file == NULL) { Ns_DString ds; ! Ns_DStringInit(&ds); ! Ns_HomePath(&ds, "log/nspid.", NULL); ! Ns_DStringAppend(&ds, procname); ! file = Ns_DStringExport(&ds); ! } } + return file; } Index: tclimg.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclimg.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** tclimg.c 13 Jun 2005 06:14:26 -0000 1.3 --- tclimg.c 8 Oct 2005 12:06:07 -0000 1.4 *************** *** 1,7 **** /* ! * The contents of this file are subject to the AOLserver Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at ! * http://aolserver.com/. * * Software distributed under the License is distributed on an "AS IS" --- 1,7 ---- /* ! * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at ! * http://mozilla.org/. * * Software distributed under the License is distributed on an "AS IS" *************** *** 54,64 **** * NsTclGifSizeObjCmd -- * ! * Implements ns_gifsize, returning a list of width and height. * * Results: ! * Tcl result. * * Side effects: ! * See docs. * *---------------------------------------------------------------------- --- 54,64 ---- * NsTclGifSizeObjCmd -- * ! * Implements ns_gifsize, returning a list of width and height. * * Results: ! * Tcl result. * * Side effects: ! * See docs. * *---------------------------------------------------------------------- *************** *** 66,86 **** int ! NsTclGifSizeObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ! int fd; ! unsigned char buf[0x300]; ! int depth, colormap, dx, dy, status; if (objc != 2) { ! Tcl_WrongNumArgs(interp, 1, objv, "gif"); return TCL_ERROR; } ! fd = open(Tcl_GetString(objv[1]), O_RDONLY|O_BINARY); ! if (fd == -1) { ! Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not open \"", ! Tcl_GetString(objv[1]), ! "\": ", Tcl_PosixError(interp), NULL); return TCL_ERROR; } status = TCL_ERROR; --- 66,91 ---- int ! NsTclGifSizeObjCmd(ClientData arg, Tcl_Interp *interp, int objc, ! Tcl_Obj *CONST objv[]) { ! unsigned char buf[0x300], count; ! char *file; ! int depth, colormap, dx, dy, status; ! Tcl_Channel chan; if (objc != 2) { ! Tcl_WrongNumArgs(interp, 1, objv, "gif_file"); return TCL_ERROR; } ! file = Tcl_GetString(objv[1]); ! chan = Tcl_OpenFileChannel(interp, file, "r", 0); ! if (chan == NULL) { return TCL_ERROR; } + if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") + != TCL_OK) { + return TCL_ERROR; + } + status = TCL_ERROR; *************** *** 89,117 **** */ ! if (read(fd, buf, 6) != 6) { readfail: ! Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "could not read \"", ! Tcl_GetString(objv[1]), ! "\": ", Tcl_PosixError(interp), NULL); ! goto done; } if (strncmp((char *) buf, "GIF87a", 6) && ! strncmp((char *) buf, "GIF89a", 6)) { ! badfile: ! Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "invalid gif file: ", ! Tcl_GetString(objv[1]), NULL); goto done; } ! if (read(fd, buf, 7) != 7) { ! goto readfail; } ! depth = 1 << ((buf[4] & 0x7) + 1); colormap = (buf[4] & 0x80 ? 1 : 0); if (colormap) { ! if (read(fd, buf, (size_t)(3*depth)) != (3*depth)) { goto readfail; } --- 94,120 ---- */ ! if (Tcl_Read(chan, buf, 6) != 6) { readfail: ! Tcl_AppendResult(interp, "could not read \"", file, "\": ", ! Tcl_PosixError(interp), NULL); ! goto done; } if (strncmp((char *) buf, "GIF87a", 6) && ! strncmp((char *) buf, "GIF89a", 6)) { ! badfile: ! Tcl_AppendResult(interp, "bad gif file \"", file, "\"", NULL); goto done; } ! if (Tcl_Read(chan, buf, 7) != 7) { ! goto readfail; } ! depth = 1 << ((buf[4] & 0x7) + 1); colormap = (buf[4] & 0x80 ? 1 : 0); if (colormap) { ! if (Tcl_Read(chan, buf, (size_t)(3*depth)) != (3*depth)) { goto readfail; } *************** *** 119,134 **** outerloop: ! if (read(fd, buf, 1) != 1) { goto readfail; } if (buf[0] == '!') { ! unsigned char count; ! ! if (read(fd, buf, 1) != 1) { goto readfail; } ! innerloop: ! if (read(fd, (char *) &count, 1) != 1) { goto readfail; } --- 122,135 ---- outerloop: ! if (Tcl_Read(chan, buf, 1) != 1) { goto readfail; } if (buf[0] == '!') { ! if (Tcl_Read(chan, buf, 1) != 1) { goto readfail; } ! innerloop: ! if (Tcl_Read(chan, (char *) &count, 1) != 1) { goto readfail; } *************** *** 136,140 **** goto outerloop; } ! if (read(fd, buf, count) != count) { goto readfail; } --- 137,141 ---- goto outerloop; } ! if (Tcl_Read(chan, buf, count) != count) { goto readfail; } *************** *** 143,160 **** goto badfile; } ! ! if (read(fd,buf,9) != 9) { goto readfail; } ! dx = 0x100 * buf[5] + buf[4]; dy = 0x100 * buf[7] + buf[6]; ! if(AppendObjDims(interp, dx, dy) != TCL_OK) { return TCL_ERROR; ! }; status = TCL_OK; done: ! close(fd); return status; } --- 144,164 ---- goto badfile; } ! ! if (Tcl_Read(chan, buf, 9) != 9) { goto readfail; } ! dx = 0x100 * buf[5] + buf[4]; dy = 0x100 * buf[7] + buf[6]; ! ! if (AppendObjDims(interp, dx, dy) != TCL_OK) { return TCL_ERROR; ! } ! status = TCL_OK; done: ! Tcl_Close(interp, chan); ! return status; } *************** *** 166,176 **** * NsTclJpegSizeObjCmd -- * ! * Implements ns_jpegsize as obj command. * * Results: ! * Tcl result. * * Side effects: ! * See docs. * *---------------------------------------------------------------------- --- 170,180 ---- * NsTclJpegSizeObjCmd -- * ! * Implements ns_jpegsize as obj command. * * Results: ! * Tcl result. * * Side effects: ! * See docs. * *---------------------------------------------------------------------- *************** *** 178,198 **** int ! NsTclJpegSizeObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ! int code, w = 0, h = 0; Tcl_Channel chan; if (objc != 2) { ! Tcl_WrongNumArgs(interp, 1, objv, "file"); ! return TCL_ERROR; } ! ! chan = Tcl_OpenFileChannel(interp, Tcl_GetString(objv[1]), "r", 0); if (chan == NULL) { - /* Tcl function will leave error message in interp's result */ return TCL_ERROR; } ! if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") != TCL_OK) { ! /* Tcl function will leave error message in interp's result */ return TCL_ERROR; } --- 182,203 ---- int ! NsTclJpegSizeObjCmd(ClientData arg, Tcl_Interp *interp, int objc, ! Tcl_Obj *CONST objv[]) { ! char *file; ! int code, w = 0, h = 0; Tcl_Channel chan; if (objc != 2) { ! Tcl_WrongNumArgs(interp, 1, objv, "jpeg_file"); ! return TCL_ERROR; } ! file = Tcl_GetString(objv[1]); ! chan = Tcl_OpenFileChannel(interp, file, "r", 0); if (chan == NULL) { return TCL_ERROR; } ! if (Tcl_SetChannelOption(interp, chan, "-translation", "binary") ! != TCL_OK) { return TCL_ERROR; } *************** *** 200,210 **** Tcl_Close(interp, chan); if (code != TCL_OK) { ! Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "invalid jpeg file: ", ! Tcl_GetString(objv[1]), NULL); ! return TCL_ERROR; } ! if(AppendObjDims(interp, w, h) != TCL_OK) { ! return TCL_ERROR; ! }; return TCL_OK; } --- 205,215 ---- Tcl_Close(interp, chan); if (code != TCL_OK) { ! Tcl_AppendResult(interp, "invalid jpeg file \"", file, "\"", NULL); ! return TCL_ERROR; } ! if (AppendObjDims(interp, w, h) != TCL_OK) { ! return TCL_ERROR; ! } ! return TCL_OK; } *************** *** 221,245 **** if (ChanGetc(chan) == 0xFF && ChanGetc(chan) == M_SOI) { ! while (1) { ! i = JpegNextMarker(chan); ! if (i == EOF || i == M_SOS || i == M_EOI) { ! break; ! } if (0xC0 <= i && i <= 0xC3) { ! if (JpegRead2Bytes(chan) != EOF && ChanGetc(chan) != EOF ! && (h = JpegRead2Bytes(chan)) != EOF ! && (w = JpegRead2Bytes(chan)) != EOF) { ! *wPtr = w; ! *hPtr = h; ! return TCL_OK; ! } ! break; ! } ! numbytes = JpegRead2Bytes(chan); ! if (numbytes < 2 || Tcl_Seek(chan, numbytes - 2, SEEK_CUR) == -1) { ! break; ! } ! } } return TCL_ERROR; } --- 226,251 ---- if (ChanGetc(chan) == 0xFF && ChanGetc(chan) == M_SOI) { ! while (1) { ! i = JpegNextMarker(chan); ! if (i == EOF || i == M_SOS || i == M_EOI) { ! break; ! } if (0xC0 <= i && i <= 0xC3) { ! if (JpegRead2Bytes(chan) != EOF && ChanGetc(chan) != EOF ! && (h = JpegRead2Bytes(chan)) != EOF ! && (w = JpegRead2Bytes(chan)) != EOF) { ! *wPtr = w; ! *hPtr = h; ! return TCL_OK; ! } ! break; ! } ! numbytes = JpegRead2Bytes(chan); ! if (numbytes < 2 || Tcl_Seek(chan, numbytes - 2, SEEK_CUR) == -1) { ! break; ! } ! } } + return TCL_ERROR; } *************** *** 271,276 **** c2 = ChanGetc(chan); if (c1 == EOF || c2 == EOF) { ! return -1; } return (int)(((unsigned int) c1) << 8) + ((unsigned int) c2); } --- 277,283 ---- c2 = ChanGetc(chan); if (c1 == EOF || c2 == EOF) { ! return -1; } + return (int)(((unsigned int) c1) << 8) + ((unsigned int) c2); } *************** *** 311,326 **** c = ChanGetc(chan); while (c != EOF && c != 0xFF) { ! c = ChanGetc(chan); } if (c != EOF) { ! /* ! * Get marker code byte, swallowing any duplicate FF bytes. ! */ ! ! do { ! c = ChanGetc(chan); ! } while (c == 0xFF); } ! return c; } --- 318,332 ---- c = ChanGetc(chan); while (c != EOF && c != 0xFF) { ! c = ChanGetc(chan); } if (c != EOF) { ! /* ! * Get marker code byte, swallowing any duplicate FF bytes. ! */ ! do { ! c = ChanGetc(chan); ! } while (c == 0xFF); } ! return c; } *************** *** 349,354 **** if (Tcl_Read(chan, (char *) buf, 1) != 1) { ! return EOF; } return (int) buf[0]; } --- 355,361 ---- if (Tcl_Read(chan, (char *) buf, 1) != 1) { ! return EOF; } + return (int) buf[0]; } *************** *** 385,389 **** return TCL_ERROR; } ! Tcl_SetObjResult(interp, result); --- 392,396 ---- return TCL_ERROR; } ! Tcl_SetObjResult(interp, result); Index: rollfile.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/rollfile.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** rollfile.c 2 Oct 2005 22:23:10 -0000 1.4 --- rollfile.c 8 Oct 2005 12:06:07 -0000 1.5 *************** *** 1,7 **** /* ! * The contents of this file are subject to the AOLserver Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at ! * http://aolserver.com/. * * Software distributed under the License is distributed on an "AS IS" --- 1,7 ---- /* ! * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at ! * http://mozilla.org/. * * Software distributed under the License is distributed on an "AS IS" *************** *** 39,44 **** typedef struct File { ! time_t mtime; ! char name[4]; } File; --- 39,44 ---- typedef struct File { ! time_t mtime; ! Tcl_Obj *path; } File; *************** *** 47,51 **** */ ! static int AppendFile(Ns_DString *dsPtr, CONST char *dir, CONST char *tail); static int CmpFile(const void *p1, const void *p2); static int Rename(CONST char *from, CONST char *to); --- 47,51 ---- */ ! static int MatchFiles(CONST char *file, File **files); static int CmpFile(const void *p1, const void *p2); static int Rename(CONST char *from, CONST char *to); *************** *** 81,90 **** { char *first, *next, *dot; ! int num; ! int err; if (max < 0 || max > 999) { Ns_Log(Error, "rollfile: invalid max parameter '%d'; " ! "must be > 0 and < 999", max); return NS_ERROR; } --- 81,89 ---- { char *first, *next, *dot; ! int num, err; if (max < 0 || max > 999) { Ns_Log(Error, "rollfile: invalid max parameter '%d'; " ! "must be > 0 and < 999", max); return NS_ERROR; } *************** *** 93,107 **** sprintf(first, "%s.000", file); err = Exists(first); if (err > 0) { next = ns_strdup(first); num = 0; do { dot = strrchr(next, '.') + 1; sprintf(dot, "%03d", num++); } while ((err = Exists(next)) == 1 && num < max); ! num--; if (err == 1) { ! err = Unlink(next); } while (err == 0 && num-- > 0) { dot = strrchr(first, '.') + 1; --- 92,119 ---- sprintf(first, "%s.000", file); err = Exists(first); + if (err > 0) { next = ns_strdup(first); num = 0; + + /* + * Find the highest version + */ + do { dot = strrchr(next, '.') + 1; sprintf(dot, "%03d", num++); } while ((err = Exists(next)) == 1 && num < max); ! ! num--; /* After this, num holds the max version found */ ! if (err == 1) { ! err = Unlink(next); /* The excessive version */ } + + /* + * Shift *.010 -> *.011, *:009 -> *.010, etc + */ + while (err == 0 && num-- > 0) { dot = strrchr(first, '.') + 1; *************** *** 113,116 **** --- 125,129 ---- ns_free(next); } + if (err == 0) { err = Exists(file); *************** *** 119,122 **** --- 132,136 ---- } } + ns_free(first); *************** *** 124,127 **** --- 138,142 ---- return NS_ERROR; } + return NS_OK; } *************** *** 134,138 **** * * Purge files by date, keeping max files. The file parameter is ! * used a basename to select files to purge. Ns_RollFileByDate * is a poorly named wrapper for historical reasons (rolling * implies rotating filenames). --- 149,153 ---- * * Purge files by date, keeping max files. The file parameter is ! * used as a basename to select files to purge. Ns_RollFileByDate * is a poorly named wrapper for historical reasons (rolling * implies rotating filenames). *************** *** 156,241 **** Ns_PurgeFiles(CONST char *file, int max) { ! char *slash, *tail; ! DIR *dp; ! struct dirent *ent; ! File **files; ! int tlen, i, nfiles, status; ! Ns_DString dir, list; ! ! status = NS_ERROR; ! Ns_DStringInit(&dir); ! Ns_DStringInit(&list); /* ! * Determine the directory component. */ ! Ns_NormalizePath(&dir, file); ! slash = strrchr (dir.string, '/'); ! if (slash == NULL || slash[1] == '\0') { ! Ns_Log (Error, "rollfile: failed to purge files: invalid path '%s'", ! file); ! goto err; ! } ! *slash = '\0'; ! tail = slash + 1; ! tlen = strlen(tail); ! ! dp = opendir(dir.string); ! if (dp == NULL) { ! Ns_Log(Error, "rollfile: failed to purge files:opendir(%s) failed: '%s'", ! dir.string, strerror(errno)); ! goto err; ! } ! while ((ent = ns_readdir(dp)) != NULL) { ! if (strncmp(tail, ent->d_name, (size_t)tlen) != 0) { ! continue; ! } ! if (!AppendFile(&list, dir.string, ent->d_name)) { ! closedir(dp); ! goto err; ! } } - closedir(dp); ! nfiles = list.length / sizeof(File *); if (nfiles >= max) { ! files = (File **) list.string; ! qsort(files, (size_t)nfiles, sizeof(File *), CmpFile); ! for (i = max; i < nfiles; ++i) { ! if (Unlink(files[i]->name) != 0) { goto err; } } } - status = NS_OK; ! err: ! nfiles = list.length / sizeof(File *); if (nfiles > 0) { ! files = (File **) list.string; ! for (i = 0; i < nfiles; ++i) { ! ns_free(files[i]); } } - Ns_DStringFree(&list); - Ns_DStringFree(&dir); return status; } - /* *---------------------------------------------------------------------- * ! * AppendFile -- * ! * Append a file entry with mtime to the list kept in the dstring. * * Results: ! * 1 if file added, 0 otherwise. * * Side effects: ! * Allocates memory for entry. * *---------------------------------------------------------------------- --- 171,230 ---- Ns_PurgeFiles(CONST char *file, int max) { ! File *files, *fiPtr; ! int ii, nfiles, status = NS_ERROR; /* ! * Get all files matching "file*" pattern. */ ! nfiles = MatchFiles(file, &files); ! if (nfiles == -1) { ! Ns_Log(Error, "rollfile: failed to match files '%s': %s", ! file, strerror(Tcl_GetErrno())); } ! /* ! * Purge (any) excessive files after sorting them ! * on descening file mtime. ! */ ! if (nfiles >= max) { ! qsort(files, (size_t)nfiles, sizeof(File), CmpFile); ! for (ii = max, fiPtr = files + ii; ii < nfiles; ii++, fiPtr++) { ! if (Unlink(Tcl_GetString(fiPtr->path)) != 0) { goto err; } } } ! status = NS_OK; ! ! err: if (nfiles > 0) { ! for (ii = 0, fiPtr = files + ii; ii < nfiles; ii++, fiPtr++) { ! Tcl_DecrRefCount(fiPtr->path); } + ns_free(files); } return status; } /* *---------------------------------------------------------------------- * ! * MatchFiles -- * ! * Find plain files in the file's parent directory matching the ! * "filename*" pattern. * * Results: ! * Number of files found, or -1 on error. If any files found, ! * pointer to allocated array of File structures is left in ! * the passed "files" argument. * * Side effects: ! * Allocates the memory for files array which must be freed ! * by the caller. * *---------------------------------------------------------------------- *************** *** 243,263 **** static int ! AppendFile(Ns_DString *dsPtr, CONST char *dir, CONST char *tail) { ! File *fPtr; ! struct stat st; ! fPtr = ns_malloc(sizeof(File) + strlen(dir) + strlen(tail)); ! sprintf(fPtr->name, "%s/%s", dir, tail); ! if (stat(fPtr->name, &st) != 0) { ! Ns_Log(Error, "rollfile: failed to append to file '%s': '%s'", ! fPtr->name, strerror(errno)); ! ns_free(fPtr); ! return 0; } - fPtr->mtime = st.st_mtime; - Ns_DStringNAppend(dsPtr, (char *) &fPtr, sizeof(File *)); ! return 1; } --- 232,319 ---- static int ! MatchFiles(CONST char *filename, File **files) { ! Tcl_Obj *path, *pathElems, *parent, *patternObj; ! Tcl_Obj *matched, **matchElems; ! Tcl_GlobTypeData types; ! File *fiPtr; ! int numElems, code, ii, jj; ! char *pattern; ! /* ! * Obtain fully qualified path of the passed filename ! */ ! ! path = Tcl_NewStringObj(filename, -1); ! Tcl_IncrRefCount(path); ! if (Tcl_FSGetNormalizedPath(NULL, path) == NULL) { ! Tcl_DecrRefCount(path); ! return -1; } ! /* ! * Get the parent directory of the passed filename ! */ ! ! pathElems = Tcl_FSSplitPath(path, &numElems); ! parent = Tcl_FSJoinPath(pathElems, numElems - 1); ! Tcl_IncrRefCount(parent); ! ! /* ! * Construct the glob pattern for lookup. ! */ ! ! Tcl_ListObjIndex(NULL, pathElems, numElems - 1, &patternObj); ! Tcl_AppendToObj(patternObj, "*", 1); ! pattern = Tcl_GetString(patternObj); ! ! /* ! * Now, do the match on files only. ! */ ! ! memset(&types, 0, sizeof(Tcl_GlobTypeData)); ! types.type = TCL_GLOB_TYPE_FILE; ! ! matched = Tcl_NewObj(); ! Tcl_IncrRefCount(matched); ! ! code = Tcl_FSMatchInDirectory(NULL, matched, parent, pattern, &types); ! if (code != TCL_OK) { ! numElems = -1; ! } else { ! ! /* ! * Construct array of File's to pass to caller ! */ ! ! Tcl_ListObjGetElements(NULL, matched, &numElems, &matchElems); ! ! if (numElems > 0) { ! Tcl_StatBuf *stPtr; ! *files = ns_malloc(sizeof(File) * numElems); ! stPtr = Tcl_AllocStatBuf(); ! for (ii = 0, fiPtr = *files; ii < numElems; ii++, fiPtr++) { ! if (Tcl_FSStat(matchElems[ii], stPtr) != 0) { ! for (jj = 0, fiPtr = *files; jj < ii; jj++, fiPtr++) { ! Tcl_DecrRefCount(fiPtr->path); ! } ! ns_free(*files); ! numElems = -1; ! break; ! } ! fiPtr->mtime = stPtr->st_mtime; ! fiPtr->path = matchElems[ii]; ! Tcl_IncrRefCount(fiPtr->path); ! } ! Tcl_Free((char*)stPtr); ! } ! } ! ! Tcl_DecrRefCount(path); ! Tcl_DecrRefCount(parent); ! Tcl_DecrRefCount(pathElems); ! Tcl_DecrRefCount(matched); ! ! return numElems; } *************** *** 282,287 **** CmpFile(const void *arg1, const void *arg2) { ! File *f1Ptr = *((File **) arg1); ! File *f2Ptr = *((File **) arg2); if (f1Ptr->mtime < f2Ptr->mtime) { --- 338,343 ---- CmpFile(const void *arg1, const void *arg2) { ! File *f1Ptr = (File *) arg1; ! File *f2Ptr = (File *) arg2; if (f1Ptr->mtime < f2Ptr->mtime) { *************** *** 289,293 **** } else if (f1Ptr->mtime > f2Ptr->mtime) { return -1; ! } return 0; } --- 345,350 ---- } else if (f1Ptr->mtime > f2Ptr->mtime) { return -1; ! } ! return 0; } *************** *** 314,323 **** { int err; ! err = unlink(file); if (err != 0) { Ns_Log(Error, "rollfile: failed to delete file '%s': '%s'", ! file, strerror(errno)); } return err; } --- 371,385 ---- { int err; + Tcl_Obj *fileObj; ! fileObj = Tcl_NewStringObj(file, -1); ! Tcl_IncrRefCount(fileObj); ! err = Tcl_FSDeleteFile(fileObj); if (err != 0) { Ns_Log(Error, "rollfile: failed to delete file '%s': '%s'", ! file, strerror(Tcl_GetErrno())); } + Tcl_DecrRefCount(fileObj); + return err; } *************** *** 327,336 **** { int err; ! ! err = rename(from, to); if (err != 0) { Ns_Log(Error, "rollfile: failed to rename file '%s' to '%s': '%s'", ! from, to, strerror(errno)); } return err; } --- 389,409 ---- { int err; ! Tcl_Obj *fromObj, *toObj; ! ! fromObj = Tcl_NewStringObj(from, -1); ! Tcl_IncrRefCount(fromObj); ! ! toObj = Tcl_NewStringObj(to, -1); ! Tcl_IncrRefCount(toObj); ! ! err = Tcl_FSRenameFile(fromObj, toObj); ! ! Tcl_DecrRefCount(fromObj); ! Tcl_DecrRefCount(toObj); if (err != 0) { Ns_Log(Error, "rollfile: failed to rename file '%s' to '%s': '%s'", ! from, to, strerror(Tcl_GetErrno())); } + return err; } *************** *** 340,353 **** { int exists; ! ! if (access(file, F_OK) == 0) { exists = 1; ! } else if (errno == ENOENT) { exists = 0; } else { ! Ns_Log(Error, "rollfile: failed to determine if file '%s' exists: '%s'", ! file, strerror(errno)); exists = -1; } return exists; } --- 413,427 ---- { int exists; ! ! if (Tcl_Access(file, F_OK) == 0) { exists = 1; ! } else if (Tcl_GetErrno() == ENOENT) { exists = 0; } else { ! Ns_Log(Error, "rollfile: failed to determine if file '%s' " ! "exists: '%s'", file, strerror(Tcl_GetErrno())); exists = -1; } + return exists; } Index: config.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/config.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** config.c 4 Aug 2005 04:52:12 -0000 1.4 --- config.c 8 Oct 2005 12:06:07 -0000 1.5 *************** *** 486,493 **** * * Results: ! * Pointer to the config buffer of an ns_malloc'ed string. * * Side Effects: ! * Server aborts if file cannot be read for any reason. * *--------------------------------------------------------------------- --- 486,493 ---- * * Results: ! * Pointer to the config buffer in an ns_malloc'ed string. * * Side Effects: ! * Server aborts if the file cannot be read for any reason. * *--------------------------------------------------------------------- *************** *** 497,525 **** NsConfigRead(CONST char *file) { ! struct stat st; ! int fd; ! char *buf; ! size_t n; ! if (stat(file, &st) != 0) { ! Ns_Fatal("config: stat(%s) failed: %s", file, strerror(errno)); } ! if (S_ISREG(st.st_mode) == 0) { ! Ns_Fatal("config: not regular file: %s", file); } ! fd = open(file, O_RDONLY); ! if (fd < 0) { ! Ns_Fatal("config: open(%s) failed: %s", file, strerror(errno)); } ! n = st.st_size; ! buf = ns_malloc(n + 1); ! n = read(fd, buf, n); ! if (n < 0) { ! Ns_Fatal("config: read(%s) failed: %s", file, strerror(errno)); } ! buf[n] = '\0'; ! close(fd); ! return buf; } --- 497,544 ---- NsConfigRead(CONST char *file) { ! Tcl_Channel chan = NULL; ! Tcl_Obj *buf = NULL; ! char *call, *data, *conf = NULL; ! int length; ! /* ! * Open the channel for reading the config file ! */ ! ! chan = Tcl_OpenFileChannel(NULL, file, "r", 0); ! if (chan == NULL) { ! call = "open"; ! goto err; } ! ! /* ! * Slurp entire file in memory ! */ ! ! buf = Tcl_NewObj(); ! Tcl_IncrRefCount(buf); ! if (Tcl_ReadChars(chan, buf, -1, 0) == -1) { ! call = "read"; ! goto err; } ! ! Tcl_Close(NULL, chan); ! data = Tcl_GetStringFromObj(buf, &length); ! conf = strcpy(ns_malloc(length + 1), data); ! Tcl_DecrRefCount(buf); ! ! return conf; ! ! err: ! if (chan) { ! Tcl_Close(NULL, chan); } ! if (buf) { ! Tcl_DecrRefCount(buf); } ! Ns_Fatal("config: can't %s file '%s': '%s'", call, file, ! strerror(Tcl_GetErrno())); ! return NULL; /* Keep the compiler happy */ } Index: binder.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/binder.c,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** binder.c 6 Jul 2005 08:45:52 -0000 1.12 --- binder.c 8 Oct 2005 12:06:07 -0000 1.13 *************** *** 412,423 **** } if (file != NULL) { ! FILE *fp; ! fp = fopen(file, "r"); ! if (fp != NULL) { ! char line[1024]; ! while (fgets(line, sizeof(line), fp) != NULL) { ! PreBind(line); } ! fclose(fp); } } --- 412,430 ---- } if (file != NULL) { ! Tcl_Channel chan = Tcl_OpenFileChannel(NULL, file, "r", 0); ! if (chan == NULL) { ! Ns_Log(Error, "binder: can't open file '%s': '%s'", file, ! strerror(Tcl_GetErrno())); ! } else { ! Tcl_DString line; ! Tcl_DStringInit(&line); ! while(!Tcl_Eof(chan)) { ! Tcl_DStringSetLength(&line, 0); ! if (Tcl_Gets(chan, &line) > 0) { ! PreBind(Tcl_DStringValue(&line)); ! } } ! Tcl_DStringFree(&line); ! Tcl_Close(NULL, chan); } } Index: fastpath.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/fastpath.c,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** fastpath.c 2 Oct 2005 22:23:09 -0000 1.20 --- fastpath.c 8 Oct 2005 12:06:07 -0000 1.21 *************** *** 40,59 **** /* ! * The following structure defines the offsets parsed ! * from Range: request header */ ! #define MAX_RANGES (NS_CONN_MAXBUFS/3) typedef struct { ! int status; /* Return status updated, 206 or 416 */ [...1132 lines suppressed...] ! ! iovPtr += 2; ! result = Ns_ConnSend(conn, iovPtr, 1); ! if (result == NS_ERROR) { ! break; ! } ! } ! } + Ns_DStringFree(&ds); break; *************** *** 983,986 **** --- 1143,1147 ---- result = Ns_ConnClose(conn); } + return result; } Index: log.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/log.c,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** log.c 2 Oct 2005 22:39:06 -0000 1.8 --- log.c 8 Oct 2005 12:06:07 -0000 1.9 *************** *** 92,97 **** /* ! * Keep the following in sync with the ! * Ns_LogSeverity enum. */ --- 92,96 ---- /* ! * Keep the following in sync with the Ns_LogSeverity enum. */ *************** *** 109,113 **** }; - /* --- 108,111 ---- *************** *** 213,218 **** * Ns_LogRoll -- * ! * Signal handler for SIG_HUP which will roll the files. Also a ! * tasty snack from Stuckey's. * * Results: --- 211,215 ---- * Ns_LogRoll -- * ! * Signal handler for SIG_HUP which will roll the files. * * Results: *************** *** 237,240 **** --- 234,238 ---- } } + return NS_OK; } *************** *** 442,450 **** int ! NsTclLogRollObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { if (Ns_LogRoll() != NS_OK) { Tcl_SetResult(interp, "could not roll server log", TCL_STATIC); } return TCL_OK; } --- 440,450 ---- int ! NsTclLogRollObjCmd(ClientData arg, Tcl_Interp *interp, int objc, ! Tcl_Obj *CONST objv[]) { if (Ns_LogRoll() != NS_OK) { Tcl_SetResult(interp, "could not roll server log", TCL_STATIC); } + return TCL_OK; } *************** *** 469,473 **** int ! NsTclLogCtlObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { LogCache *cachePtr; --- 469,474 ---- int ! NsTclLogCtlObjCmd(ClientData arg, Tcl_Interp *interp, int objc, ! Tcl_Obj *CONST objv[]) { LogCache *cachePtr; *************** *** 475,482 **** static CONST char *opts[] = { ! "hold", "count", "get", "peek", "flush", "release", "truncate", NULL }; enum { ! CHoldIdx, CCountIdx, CGetIdx, CPeekIdx, CFlushIdx, CReleaseIdx, CTruncIdx }; --- 476,485 ---- static CONST char *opts[] = { ! "hold", "count", "get", "peek", "flush", "release", ! "truncate", NULL }; enum { ! CHoldIdx, CCountIdx, CGetIdx, CPeekIdx, CFlushIdx, CReleaseIdx, ! CTruncIdx }; *************** *** 527,530 **** --- 530,534 ---- break; } + return TCL_OK; } *************** *** 548,556 **** int ! NsTclLogObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ! Ns_LogSeverity severity; ! Ns_DString ds; ! int i; struct { --- 552,561 ---- int ! NsTclLogObjCmd(ClientData arg, Tcl_Interp *interp, int objc, ! Tcl_Obj *CONST objv[]) { ! Ns_LogSeverity severity; ! Ns_DString ds; ! int i; struct { *************** *** 579,583 **** severity = i; } else { ! Tcl_AppendResult(interp, "unknown severity: \"", Tcl_GetString(objv[1]), "\": should be notice, warning, error, " "fatal, bug, debug, dev or integer value", NULL); --- 584,589 ---- severity = i; } else { ! Tcl_AppendResult(interp, "unknown severity: \"", ! Tcl_GetString(objv[1]), "\": should be notice, warning, error, " "fatal, bug, debug, dev or integer value", NULL); *************** *** 680,685 **** Ns_DStringPrintf(&cachePtr->buffer, ".%ld]", usec); } ! Ns_DStringPrintf(&cachePtr->buffer, "[%d.%lu][%s] %s: ", ! Ns_InfoPid(), (unsigned long) Ns_ThreadId(), Ns_ThreadGetName(), severityStr); if (flags & LOG_EXPAND) { Ns_DStringAppend(&cachePtr->buffer, "\n "); --- 686,692 ---- Ns_DStringPrintf(&cachePtr->buffer, ".%ld]", usec); } ! Ns_DStringPrintf(&cachePtr->buffer, "[%d.%lu][%s] %s: ", Ns_InfoPid(), ! (unsigned long) Ns_ThreadId(), Ns_ThreadGetName(), ! severityStr); if (flags & LOG_EXPAND) { Ns_DStringAppend(&cachePtr->buffer, "\n "); *************** *** 774,787 **** LogReOpen(void) { ! int fd; ! int status; - status = NS_OK; fd = open(file, O_WRONLY|O_APPEND|O_CREAT, 0644); ! if (fd < 0) { ! Ns_Log(Error, "log: failed to re-open log file '%s': '%s'", file, strerror(errno)); status = NS_ERROR; } else { /* * Route stderr to the file --- 781,793 ---- LogReOpen(void) { ! int fd, status = NS_OK; fd = open(file, O_WRONLY|O_APPEND|O_CREAT, 0644); ! if (fd == -1) { ! Ns_Log(Error, "log: failed to re-open log file '%s': '%s'", file, strerror(errno)); status = NS_ERROR; } else { + /* * Route stderr to the file *************** *** 807,811 **** * Clean up dangling 'open' reference to the fd */ ! if (fd != STDERR_FILENO && fd != STDOUT_FILENO) { close(fd); --- 813,817 ---- * Clean up dangling 'open' reference to the fd */ ! if (fd != STDERR_FILENO && fd != STDOUT_FILENO) { close(fd); *************** *** 972,973 **** --- 978,980 ---- abort(); } + Index: tclfile.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclfile.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** tclfile.c 30 Jul 2005 04:06:02 -0000 1.5 --- tclfile.c 8 Oct 2005 12:06:07 -0000 1.6 *************** *** 36,44 **** #include "nsd.h" - #ifdef _WIN32 - #include <sys/utime.h> - #else - #include <utime.h> - #endif NS_RCSID("@(#) $Header$"); --- 36,39 ---- *************** *** 144,413 **** *---------------------------------------------------------------------- * - * NsTclCpFpObjCmd -- - * - * Implements ns_cpfp as obj command. - * - * Results: - * Tcl result. - * - * Side effects: - * See docs. - * - *---------------------------------------------------------------------- - */ - - int - NsTclCpFpObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) - { - Tcl_Channel in, out; - char buf[2048]; - char *p; - int tocopy, nread, nwrote, toread, ntotal; - - if (objc != 3 && objc != 4) { - Tcl_WrongNumArgs(interp, 1, objv, "inChan outChan ?ncopy?"); - return TCL_ERROR; - } - if (GetOpenChannel(interp, objv[1], 0, 1, &in) != TCL_OK || - GetOpenChannel(interp, objv[2], 1, 1, &out) != TCL_OK) { - return TCL_ERROR; - } - if (objc == 3) { - tocopy = -1; - } else { - if (Tcl_GetInt(interp, Tcl_GetString(objv[3]), &tocopy) != TCL_OK) { - return TCL_ERROR; - } - if (tocopy < 0) { - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "invalid length \"", - Tcl_GetString(objv[3]), - "\": must be >= 0", NULL); - return TCL_ERROR; - } - } - - ntotal = 0; - while (tocopy != 0) { - toread = sizeof(buf); - if (tocopy > 0 && toread > tocopy) { - toread = tocopy; - } - nread = Tcl_Read(in, buf, toread); - if (nread == 0) { - break; - } else if (nread < 0) { - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "read failed: ", - Tcl_PosixError(interp), NULL); - return TCL_ERROR; - } - if (tocopy > 0) { - tocopy -= nread; - } - p = buf; - while (nread > 0) { - nwrote = Tcl_Write(out, p, nread); - if (nwrote < 0) { - Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), ... [truncated message content] |