POSTing Mosaic patches

Jay C. Weber (weber@eit.COM)
Thu, 4 Aug 94 12:07:42 PDT


As promised, here are my patches to NCSA Mosaic for X-Windows version
2.4 that give it the ability to POST files when dereferencing anchors
with method=POST. This ability is a key enabler in building web
services that translate documents, support collaborative authoring,
etc.

As I understand the Mosaic license, you are free to grab the 2.4 source
from ftp.ncsa.uiuc.edu, apply these patches (presumably using the patch(1)
command), and try it out. The patches do modify the top-level Makefile,
in a couple of necessary ways and a couple of ways specific to my
environment. I'll recommend that you apply the patches and THEN modify
the Makefile to suit your environment.

In a subsequent message I'll include a CGI program that one can
use to test such POSTing.

I received more support than resistance to both modifying HTML 2.0
to include POSTing anchors, and adding something like my patch to
the official releases of NCSA Mosaic. That's great, but I don't
think there have been enough opinions expressed to bootstrap action.
Please give me feedback on your opinions and commitment to help (or
block!) getting this important capability into the hands of users.

Improvements, extentions welcome!

Jay

Here are the patches:

diff -r Mosaic-2.4/Makefile PostMosaic-2.4/Makefile
13c13
< RANLIB = /bin/true

---
> #RANLIB = /bin/true
15c15
< # RANLIB = ranlib
---
> RANLIB = ranlib
17c17
< CC = cc
---
> #CC = cc
19c19
< # CC = gcc
---
> CC = gcc
24c24
< knrflag = -cckr
---
> #knrflag = -cckr
40c40
< sysconfigflags =
---
> sysconfigflags = $(LOCALINC) -I/usr/local/include
43c43
< syslibs = -lPW -lsun -lmalloc
---
> #syslibs = -lPW -lsun -lmalloc
49c49
< # syslibs =
---
> syslibs =
72a73
> xinc = -I/usr/local/X11R5/include
75c76
< xlibs = -lXm_s -lXmu -lXt_s -lX11_s
---
> #xlibs = -lXm_s -lXmu -lXt_s -lX11_s
77c78
< # xlibs = /usr/lib/libXm.a /usr/lib/libXmu.a /usr/lib/libXt.a /usr/lib/libXext.a /usr/lib/libX11.a -lm
---
> xlibs = -L/usr/local/X11R5/lib -lXm -lXmu -lXt -lXext -lX11 -lm
115,121c116,122
< dtmmachtype = sgi
< dtmdirs = libdtm libnet
< dtmlibs = ../libnet/libnet.a ../libdtm/libdtm.a
< dtmflags = -DHAVE_DTM -I.. -I../libnet
< hdfdir = /hdf/install/sgi
< hdflibs = $(hdfdir)/lib/libnetcdf.a $(hdfdir)/lib/libdf.a
< hdfflags = -DHAVE_HDF -I$(hdfdir)/include
---
> #dtmmachtype = sgi
> #dtmdirs = libdtm libnet
> #dtmlibs = ../libnet/libnet.a ../libdtm/libdtm.a
> #dtmflags = -DHAVE_DTM -I.. -I../libnet
> #hdfdir = /hdf/install/sgi
> #hdflibs = $(hdfdir)/lib/libnetcdf.a $(hdfdir)/lib/libdf.a
> #hdfflags = -DHAVE_HDF -I$(hdfdir)/include
139,142c140,143
< waisroot = /X11/marca/freeWAIS-0.1-sgi
< waisflags = -DDIRECT_WAIS -I$(waisroot)/ir
< waislibdir = $(waisroot)/bin
< waislibs = $(waislibdir)/inv.a $(waislibdir)/wais.a $(waislibdir)/libftw.a -lm
---
> #waisroot = /X11/marca/freeWAIS-0.1-sgi
> #waisflags = -DDIRECT_WAIS -I$(waisroot)/ir
> #waislibdir = $(waisroot)/bin
> #waislibs = $(waislibdir)/inv.a $(waislibdir)/wais.a $(waislibdir)/libftw.a -lm
177c178
< customflags =
---
> customflags = -DPOST_ANCHORS
226c227
< 	cd libhtmlw; make CC=$(CC) RANLIB=$(RANLIB) CFLAGS="$(CFLAGS) $(knrflag) $(xinc) -DMOTIF -DXMOSAIC"
---
> 	cd libhtmlw; make CC=$(CC) RANLIB=$(RANLIB) CFLAGS="$(CFLAGS) $(knrflag) $(xinc) -DMOTIF -DXMOSAIC $(customflags)"
230c231
< 	cd libwww2; make CC=$(CC) RANLIB=$(RANLIB) CFLAGS="$(CFLAGS) $(knrflag) $(waisflags) $(PEM_FLAG)"
---
> 	cd libwww2; make CC=$(CC) RANLIB=$(RANLIB) CFLAGS="$(CFLAGS) $(knrflag) $(waisflags) $(PEM_FLAG) $(customflags)"
diff -r Mosaic-2.4/libhtmlw/HTML.c PostMosaic-2.4/libhtmlw/HTML.c
3735a3736,3738
> #ifdef POST_ANCHORS
> 				cbdata.method = eptr->anchorMethod;
> #endif
diff -r Mosaic-2.4/libhtmlw/HTML.h PostMosaic-2.4/libhtmlw/HTML.h
138a139,141
> #ifdef POST_ANCHORS
> 	char *method;
> #endif
247a251,253
> #ifdef POST_ANCHORS
> 	char *anchorMethod;
> #endif
367a374,376
> #ifdef POST_ANCHORS
> #define AT_METHOD       "method"
> #endif
diff -r Mosaic-2.4/libhtmlw/HTMLformat.c PostMosaic-2.4/libhtmlw/HTMLformat.c
265a266,269
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = ParseMarkTag(AnchorText,
> 					MT_ANCHOR, AT_METHOD);
> #endif
270a275,277
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = NULL;
> #endif
319a327,329
> #ifdef POST_ANCHORS
> 			eptr->anchorMethod = NULL;
> #endif
371a382,384
> #ifdef POST_ANCHORS
> 			eptr->anchorMethod = NULL;
> #endif
452a466,468
> #ifdef POST_ANCHORS
> 					eptr->anchorMethod = NULL;
> #endif
468a485,488
> #ifdef POST_ANCHORS
> 					eptr->anchorMethod = ParseMarkTag(AnchorText,
> 									  MT_ANCHOR, AT_METHOD);
> #endif
474a495,497
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = NULL;
> #endif
517a541,544
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = ParseMarkTag(AnchorText,
> 					MT_ANCHOR, AT_METHOD);
> #endif
522a550,552
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = NULL;
> #endif
656a687,690
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = ParseMarkTag(AnchorText,
> 					MT_ANCHOR, AT_METHOD);
> #endif
661a696,698
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = NULL;
> #endif
688a726,728
> #ifdef POST_ANCHORS
> 			eptr->anchorMethod = NULL;
> #endif
815a856,861
> #ifdef POST_ANCHORS
> 			if (eptr->anchorMethod != NULL)
> 			  {
> 			    free((char *)eptr->anchorMethod);
> 			  }
> #endif
821a868,871
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = ParseMarkTag(AnchorText,
> 					MT_ANCHOR, AT_METHOD);
> #endif
826a877,879
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = NULL;
> #endif
885a939,944
> #ifdef POST_ANCHORS
> 			if (eptr->anchorMethod != NULL)
> 			  {
> 			    free((char *)eptr->anchorMethod);
> 			  }
> #endif
887a947,949
> #ifdef POST_ANCHORS
> 			eptr->anchorMethod = NULL;
> #endif
949a1012,1017
> #ifdef POST_ANCHORS
> 			if (eptr->anchorMethod != NULL)
> 			  {
> 			    free((char *)eptr->anchorMethod);
> 			  }
> #endif
951a1020,1022
> #ifdef POST_ANCHORS
> 			eptr->anchorMethod = NULL;
> #endif
1029a1101,1106
> #ifdef POST_ANCHORS
> 			if (eptr->anchorMethod != NULL)
> 			  {
> 			    free((char *)eptr->anchorMethod);
> 			  }
> #endif
1044a1122,1124
> #ifdef POST_ANCHORS
> 					eptr->anchorMethod = NULL;
> #endif
1060a1141,1144
> #ifdef POST_ANCHORS
> 					eptr->anchorMethod = ParseMarkTag(AnchorText,
> 									  MT_ANCHOR, AT_METHOD);
> #endif
1066a1151,1153
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = NULL;
> #endif
1123a1211,1216
> #ifdef POST_ANCHORS
> 			if (eptr->anchorMethod != NULL)
> 			  {
> 			    free((char *)eptr->anchorMethod);
> 			  }
> #endif
1129a1223,1226
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = ParseMarkTag(AnchorText,
> 					MT_ANCHOR, AT_METHOD);
> #endif
1134a1232,1234
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = NULL;
> #endif
1274a1375,1380
> #ifdef POST_ANCHORS
> 			if (eptr->anchorMethod != NULL)
> 			  {
> 			    free((char *)eptr->anchorMethod);
> 			  }
> #endif
1280a1387,1390
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = ParseMarkTag(AnchorText,
> 					MT_ANCHOR, AT_METHOD);
> #endif
1285a1396,1398
> #ifdef POST_ANCHORS
> 				eptr->anchorMethod = NULL;
> #endif
1322a1436,1441
> #ifdef POST_ANCHORS
> 			if (eptr->anchorMethod != NULL)
> 			  {
> 			    free((char *)eptr->anchorMethod);
> 			  }
> #endif
1324a1444,1446
> #ifdef POST_ANCHORS
> 			eptr->anchorMethod = NULL;
> #endif
diff -r Mosaic-2.4/libwww2/HTTP.c PostMosaic-2.4/libwww2/HTTP.c
26a27,31
> #ifdef POST_ANCHORS
> #include <fcntl.h>
> #include <sys/types.h>
> #include <sys/stat.h>
> #endif
93a99,103
> #ifdef POST_ANCHORS
>   BOOL doing_post_file;
>   char *body;
>   int body_size;
> #endif
128a139,141
> #ifdef POST_ANCHORS
>   doing_post_file = NO;
> #endif
243a257,304
> #ifdef POST_ANCHORS
>       if (!strcasecmp(post_content_type, "autofile")) {
> 	struct stat buf;
> 	char *content_type;
> 
> 	content_type = HTFileMimeType(post_data, "application/octet-stream");
> 	sprintf (line, "Content-type: %s%c%c", content_type, CR, LF);
> 	StrAllocCat(command, line);
> 	if (stat(post_data, &buf) == 0) {
> 	  int content_length;
> 	  int fd;
> 
> 	  content_length = buf.st_size;
> 	  sprintf (line, "Content-length: %d%c%c", content_length, CR, LF);
> 	  StrAllocCat(command, line);
> 	  if ((fd=open(post_data, O_RDONLY)) >= 0) {
> 	    if (body = malloc(body_size=content_length)) {
> 	      read(fd, body, body_size);
> 	      doing_post_file = YES;
> 	    }
> 	    close(fd);
> 	  }
> 	}
>       }
>       else {
> 	sprintf (line, "Content-type: %s%c%c",
> 		 post_content_type ? post_content_type : "lose", CR, LF);
> 	StrAllocCat(command, line);
> 	{
> 	  int content_length;
> 	  if (!post_data)
> 	    content_length = 4; /* 4 == "lose" :-) */
> 	  else
> 	    content_length = strlen (post_data);
> 	  sprintf (line, "Content-length: %d%c%c",
> 		   content_length, CR, LF);
> 	  StrAllocCat(command, line);
> 	}
> 	
> 	StrAllocCat(command, crlf);	/* Blank line means "end" */
> 	
> 	if (post_data)
> 	  StrAllocCat(command, post_data);
> 	else
> 	  StrAllocCat(command, "lose");
> 	StrAllocCat(command, crlf);	/* Blank line means "end" */
>       }
> #else
263a325
> #endif
294a357,362
> #ifdef POST_ANCHORS
>   if(doing_post_file && body) {
>       status = NETWRITE(s, body, body_size);
>       free(body);
>   }
> #endif
diff -r Mosaic-2.4/src/gui-dialogs.c PostMosaic-2.4/src/gui-dialogs.c
68a69,75
> #ifdef POST_ANCHORS
> typedef struct _my_call {
>   char *my_url;
>   char *my_ref;
> } my_call;   
> #endif /* POST_ANCHORS */
> 
350a358,419
> 
> #ifdef POST_ANCHORS
> /* ---------------------- mo_post_get_file ----------------------- */
> 
> static my_call tmp;
> 
> static XmxCallback (post_get_file_cb)
> {
>   char *post_fname=NULL;
>   mo_window *win = mo_fetch_window_by_id (XmxExtractUniqid ((int)client_data));
> 
>   switch (XmxExtractToken ((int)client_data))
>     {
>     case 0:
>       
>       XtUnmanageChild (win->post_get_file);
>   
>       XmStringGetLtoR (((XmFileSelectionBoxCallbackStruct *)call_data)->value,
> 		       XmSTRING_DEFAULT_CHARSET,
> 		       &post_fname);
>   
>       mo_post_load_window_text(win, tmp.my_url, "autofile",
> 			       post_fname, tmp.my_ref);
> #ifdef NO_FREE_BUG
>       free (tmp.my_url);
>       free (tmp.my_ref);
> #endif
>       free (post_fname);
>       break;
>     }
>   return;
> }
> 
>   
> mo_status mo_post_get_file (mo_window *win, char *url, char *ref)
> {
>   char buf[128];
> 
>   strcpy(tmp.my_url=malloc(strlen(url)+1), url);
>   strcpy(tmp.my_ref=malloc(strlen(ref)+1), ref);
>   
>   XmxSetUniqid (win->id);
>   if (!win->post_get_file)
>     {
>       Widget frame, workarea, format_label;
> 
>       sprintf(buf, "Post File to %s", url);
>       win->post_get_file = XmxMakeFileSBDialog
>         (win->base, buf, 
>          "Name of local file to post:",
>          post_get_file_cb, 0);
>     }
>   else
>     {
>       XmFileSelectionDoSearch (win->post_get_file, NULL);
>     }
>   
>   XmxManageRemanage (win->post_get_file);
> 
>   return mo_succeed;
> }
> #endif
diff -r Mosaic-2.4/src/gui-documents.c PostMosaic-2.4/src/gui-documents.c
1009a1010,1024
> 
> #ifdef POST_ANCHORS
> mo_status mo_load_method_window_text (mo_window *win, char *url,
> 				      char *ref, char *method)
> {
>   if (method && !strncasecmp(method, "post", 4)) {
>     mo_post_get_file(win, url, ref);
>     return mo_succeed;
>   }
>   else {
>     return mo_load_window_text(win, url, ref);
>   }
> }
> 
> #endif /* POST_ANCHORS */
diff -r Mosaic-2.4/src/gui.c PostMosaic-2.4/src/gui.c
521a522,524
> #ifdef POST_ANCHORS
>   char *method;
> #endif
548a552,554
> #ifdef POST_ANCHORS
>   method = ((WbAnchorCallbackData *)call_data)->method;
> #endif
552a559,561
> #ifdef POST_ANCHORS
>     mo_load_method_window_text(win, href, reftext, method);
> #else
553a563
> #endif
572a583,585
> #ifdef POST_ANCHORS
> 	mo_load_method_window_text(win, url, reftext, method);
> #else
573a587
> #endif
1551a1566,1569
> #endif
> 
> #ifdef POST_ANCHORS
>   win->post_get_file=0;
diff -r Mosaic-2.4/src/mosaic.h PostMosaic-2.4/src/mosaic.h
240a241,243
> #ifdef POST_ANCHORS
>   Widget post_get_file;
> #endif
688a692,694
> #ifdef POST_ANCHORS
> extern mo_status mo_post_get_file(mo_window *, char *, char *);
> #endif