Diff
Not logged in

Differences From:

File src/cgi.c part of check-in [a48936e834] - Changes to the way new repositories are created. Also make the CGI output blob available to all modules through a function call. by drh on 2007-08-03 23:04:05. Also file src/cgi.c part of check-in [f5e8b1d736] - Merge in and correct the changes to the new repository initialization. Also fix other misc bugs seen while testing. by drh on 2007-08-04 00:08:17. [view]

To:

File src/cgi.c part of check-in [fb358ca492] - Progress toward getting ticketing working. We can enter a new ticket and display it. Cannot yet edit a ticket. by drh on 2007-11-24 19:33:46. Also file src/cgi.c part of check-in [d0305b305a] - Merged mainline into my branch to get the newest application. by aku on 2007-12-05 08:07:46. [view]

@@ -27,18 +27,25 @@
 ** formatting function and its cousins, and routines to encode and
 ** decode strings in HTML or HTTP.
 */
 #include "config.h"
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <time.h>
-#include <sys/times.h>
-#include <sys/time.h>
-#include <sys/wait.h>
+#ifdef __MINGW32__
+#  include <windows.h>           /* for Sleep once server works again */
+#  include <winsock2.h>          /* socket operations */
+#  define sleep Sleep            /* windows does not have sleep, but Sleep */
+#  include <ws2tcpip.h>
+#else
+#  include <sys/socket.h>
+#  include <netinet/in.h>
+#  include <arpa/inet.h>
+#  include <sys/times.h>
+#  include <sys/time.h>
+#  include <sys/wait.h>
+#  include <sys/select.h>
+#endif
+#include <time.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <sys/select.h>
 #include <unistd.h>
 #include "cgi.h"
 
 #if INTERFACE
@@ -144,9 +151,9 @@
   const char *zValue,   /* Value of the cookie.  Automatically escaped */
   const char *zPath,    /* Path cookie applies to.  NULL means "/" */
   int lifetime          /* Expiration of the cookie in seconds from now */
 ){
-  if( zPath==0 ) zPath = "/";
+  if( zPath==0 ) zPath = g.zTop;
   if( lifetime>0 ){
     lifetime += (int)time(0);
     blob_appendf(&extraHeader,
        "Set-Cookie: %s=%t; Path=%s; expires=%s; Version=1\r\n",
@@ -289,18 +296,25 @@
 void cgi_redirect(const char *zURL){
   char *zLocation;
   CGIDEBUG(("redirect to %s\n", zURL));
   if( strncmp(zURL,"http:",5)==0 || strncmp(zURL,"https:",6)==0 || *zURL=='/' ){
-    cgi_panic("invalid redirect URL: %s", zURL);
-  }
-  zLocation = mprintf("Location: %s/%s\r\n", g.zBaseURL, zURL);
+    zLocation = mprintf("Location: %s\r\n", zURL);
+  }else{
+    zLocation = mprintf("Location: %s/%s\r\n", g.zBaseURL, zURL);
+  }
   cgi_append_header(zLocation);
   cgi_reset_content();
   cgi_printf("<html>\n<p>Redirect to %h</p>\n</html>\n", zURL);
   cgi_set_status(302, "Moved Temporarily");
   free(zLocation);
   cgi_reply();
   exit(0);
+}
+void cgi_redirectf(const char *zFormat, ...){
+  va_list ap;
+  va_start(ap, zFormat);
+  cgi_redirect(vmprintf(zFormat, ap));
+  va_end(ap);
 }
 
 /*
 ** Information about all query parameters and cookies are stored
@@ -323,9 +337,9 @@
 **
 ** zName and zValue are not copied and must not change or be
 ** deallocated after this routine returns.
 */
-static void cgi_set_parameter_nocopy(const char *zName, const char *zValue){
+void cgi_set_parameter_nocopy(const char *zName, const char *zValue){
   if( nAllocQP<=nUsedQP ){
     nAllocQP = nAllocQP*2 + 10;
     aParamQP = realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) );
     if( aParamQP==0 ) exit(1);
@@ -345,8 +359,20 @@
 ** Copies are made of both the zName and zValue parameters.
 */
 void cgi_set_parameter(const char *zName, const char *zValue){
   cgi_set_parameter_nocopy(mprintf("%s",zName), mprintf("%s",zValue));
+}
+
+/*
+** Replace a parameter with a new value.
+*/
+void cgi_replace_parameter(const char *zName, const char *zValue){
+  int i;
+  for(i=0; i<nUsedQP; i++){
+    if( strcmp(aParamQP[i].zName,zName)==0 ){
+      aParamQP[i].zValue = zValue;
+    }
+  }
 }
 
 /*
 ** Add a query parameter.  The zName portion is fixed but a copy
@@ -703,8 +729,20 @@
   return zDefault;
 }
 
 /*
+** Return the name of the i-th CGI parameter.  Return NULL if there
+** are fewer than i registered CGI parmaeters.
+*/
+const char *cgi_parameter_name(int i){
+  if( i>=0 && i<nUsedQP ){
+    return aParamQP[i].zName;
+  }else{
+    return 0;
+  }
+}
+
+/*
 ** Print CGI debugging messages.
 */
 void cgi_debug(const char *zFormat, ...){
   va_list ap;
@@ -896,25 +934,15 @@
   cgi_printf("%*s</select>\n", in, "");
 }
 
 /*
-** This function implements the callback from vxprintf.
-**
-** This routine sends nNewChar characters of text in zNewText to
-** CGI reply content buffer.
-*/
-static void sout(void *NotUsed, const char *zNewText, int nNewChar){
-  cgi_append_content(zNewText, nNewChar);
-}
-
-/*
 ** This routine works like "printf" except that it has the
 ** extra formatting capabilities such as %h and %t.
 */
 void cgi_printf(const char *zFormat, ...){
   va_list ap;
   va_start(ap,zFormat);
-  vxprintf(sout,0,zFormat,ap);
+  vxprintf(&cgiContent,zFormat,ap);
   va_end(ap);
 }
 
 /*
@@ -921,9 +949,9 @@
 ** This routine works like "vprintf" except that it has the
 ** extra formatting capabilities such as %h and %t.
 */
 void cgi_vprintf(const char *zFormat, va_list ap){
-  vxprintf(sout,0,zFormat,ap);
+  vxprintf(&cgiContent,zFormat,ap);
 }
 
 
 /*
@@ -949,9 +977,9 @@
     "<html><body><h1>Internal Server Error</h1>\n"
     "<plaintext>"
   );
   va_start(ap, zFormat);
-  vxprintf(sout,0,zFormat,ap);
+  vxprintf(&cgiContent,zFormat,ap);
   va_end(ap);
   cgi_reply();
   exit(1);
 }
@@ -1017,9 +1045,9 @@
   for(i=0; zToken[i] && zToken[i]!='?'; i++){}
   if( zToken[i] ) zToken[i++] = 0;
   cgi_setenv("PATH_INFO", zToken);
   cgi_setenv("QUERY_STRING", &zToken[i]);
-  if( getpeername(fileno(stdin), (struct sockaddr*)&remoteName, &size)>=0 ){
+  if( getpeername(fileno(stdin), (struct sockaddr*)&remoteName, (socklen_t*)&size)>=0 ){
     char *zIpAddr = inet_ntoa(remoteName.sin_addr);
     cgi_setenv("REMOTE_ADDR", zIpAddr);
 
     /* Set the Global.zIpAddr variable to the server we are talking to.
@@ -1077,8 +1105,12 @@
 ** out of this procedure call.  The child will handle the request.
 ** The parent never returns from this procedure.
 */
 void cgi_http_server(int iPort){
+#ifdef __MINGW32__
+  fprintf(stderr,"server not yet available in windows version of fossil\n");
+  exit(1);
+#else
   int listener;                /* The server socket */
   int connection;              /* A socket for each individual connection */
   fd_set readfds;              /* Set of file descriptors for select() */
   size_t lenaddr;              /* Length of the inaddr structure */
@@ -1116,9 +1148,9 @@
     FD_ZERO(&readfds);
     FD_SET( listener, &readfds);
     if( select( listener+1, &readfds, 0, 0, &delay) ){
       lenaddr = sizeof(inaddr);
-      connection = accept(listener, (struct sockaddr*)&inaddr, &lenaddr);
+      connection = accept(listener, (struct sockaddr*)&inaddr, (socklen_t*) &lenaddr);
       if( connection>=0 ){
         child = fork();
         if( child!=0 ){
           if( child>0 ) nchildren++;
@@ -1143,8 +1175,9 @@
     }
   }
   /* NOT REACHED */
   exit(1);
+#endif
 }
 
 /*
 ** Name of days and months.