Пример #1
0
/*		New object
**		----------
*/
PUBLIC HTStream* HTMosaicHTMLPresent ARGS5(
	HTPresentation *,	pres,
	HTParentAnchor *,	anchor,
	HTStream *,		sink,
        HTFormat,               format_in,
        int,                    compressed)
{
  HTStream* me = (HTStream*)malloc(sizeof(*me));

#ifndef DISABLE_TRACE
  if (www2Trace)
    fprintf (stderr, "[HTMosaicHTMLPresent] Hi there!  Compressed is %d\n",
             compressed);
#endif

  me->isa = &HTMosaicHTML;
  me->text = HText_new();
  me->interrupted = 0;
  me->compressed = compressed;
  HText_beginAppend(me->text);

  return (HTStream*) me;
}
Пример #2
0
/*	Free an HTML object
**	-------------------
**
**	Note that the SGML parsing context is freed, but the created
**	object is not,
**	as it takes on an existence of its own unless explicitly freed.
*/
PRIVATE void HTFWriter_free ARGS1(HTStream *, me)
{
  HText *text;
  static char *envbuf1=NULL;
  static char *envbuf2=NULL;

  /* I dunno if this is necessary... */
  if (me->interrupted)
    {
      free (me->fnam);
      free (me);
      return;
    }

  if (me->write_error)
    {
/*
      char *cmd = (char *)malloc ((strlen (me->fnam) + 32));
      sprintf (cmd, "/bin/rm -f %s &", me->fnam);
      system (cmd);
      free (cmd);
*/
/*ddt*/unlink(me->fnam);
      
      HTProgress ("Insufficient temporary disk space; could not transfer data.");

      free (me->fnam);
      free (me);
      return;
    }

  fflush (me->fp);
  fclose (me->fp);

  /* We do want to be able to handle compressed inlined images,
     but we don't want transparent uncompression to take place
     in binary transfer mode. */
  if (!binary_transfer && me->compressed != COMPRESSED_NOT)
    {
#ifndef DISABLE_TRACE
      if (www2Trace)
        fprintf (stderr, "[HTFWriter] Hi there; compressed is %d, fnam is '%s'\n",
                 me->compressed, me->fnam);
#endif
      HTCompressedFileToFile (me->fnam, me->compressed);
    }

  if (force_dump_to_file)
    {
      if (!binary_transfer)
        goto done;
    }

  /* Now, me->end_command can either be something starting with
     "<mosaic-internal-reference" or it can be a real command.
     Deal with appropriately. */
  if (me->end_command)
    {
	/* Check for forced dump condition.  The left paren comes
		from the construction of me->end_command as a compound shell
		command below. */
	if (strstr (me->end_command, "mosaic-internal-dump")) {
		rename_binary_file (me->fnam);
        }
	else if (!strstr (me->end_command, "mosaic-internal-reference")) {
		if (imageViewInternal && supportedImageType(me->mime_type)) {
			char *newHTML="<html>\n<head>\n<title>Mosaic's Internal Image Display</title>\n</head>\n<body>\n<img align=center src=\"%s\">\n</body>\n</html>\n";
			char *buf;

			buf=(char *)calloc((strlen(currentURL)+strlen(newHTML)+5),sizeof(char));
			sprintf(buf,newHTML,currentURL);

			text=HText_new();
			HText_beginAppend(text);
			HText_appendText(text,buf);
			HText_endAppend(text);

			free(buf);

			buf=(char *)calloc((strlen(currentURL)+strlen(me->fnam)+5),sizeof(char));
			sprintf(buf,"%s\n%s",me->fnam,currentURL);
			ImageResolve(NULL,buf,0);

			free(buf);

			goto done;
		}

		HTProgress("Spawning external viewer.");

		/*
		 * Have to dance around putenv since it makes "envbuf*" part
		 *   of the actual environment string...*sigh* What a mess!
		 */
		if (envbuf1) {
			envbuf2=(char *)calloc((strlen(currentURL)+
						strlen("MOSAIC_CURRENT_URL=")+
						2),
					       sizeof(char));
			sprintf(envbuf2,"MOSAIC_CURRENT_URL=%s",currentURL);
			putenv(envbuf2);
			free(envbuf1);
			envbuf1=NULL;
		}
		else if (envbuf2) {
			envbuf1=(char *)calloc((strlen(currentURL)+
						strlen("MOSAIC_CURRENT_URL=")+
						2),
					       sizeof(char));
			sprintf(envbuf1,"MOSAIC_CURRENT_URL=%s",currentURL);
			putenv(envbuf1);
			free(envbuf2);
			envbuf2=NULL;
		}
		else { /* Likely it is the first time */
			envbuf1=(char *)calloc((strlen(currentURL)+
						strlen("MOSAIC_CURRENT_URL=")+
						2),
					       sizeof(char));
			sprintf(envbuf1,"MOSAIC_CURRENT_URL=%s",currentURL);
			putenv(envbuf1);
		}

		system (me->end_command);

		if (envbuf1) {
			envbuf2=(char *)calloc((strlen("MOSAIC_CURRENT_URL=")+
						2),
					       sizeof(char));
			sprintf(envbuf2,"MOSAIC_CURRENT_URL=");
			putenv(envbuf2);
			free(envbuf1);
			envbuf1=NULL;
		}
		else if (envbuf2) {
			envbuf1=(char *)calloc((strlen("MOSAIC_CURRENT_URL=")+
						2),
					       sizeof(char));
			sprintf(envbuf1,"MOSAIC_CURRENT_URL=");
			putenv(envbuf1);
			free(envbuf2);
			envbuf2=NULL;
		}
		else { /* Likely it is the first time */
			envbuf1=(char *)calloc((strlen("MOSAIC_CURRENT_URL=")+
						2),
					       sizeof(char));
			sprintf(envbuf1,"MOSAIC_CURRENT_URL=");
			putenv(envbuf1);
		}
	}
	else {
          /* Internal reference, aka HDF file.  Just close output file. */
	}
    }
  else
    {
      /* No me->end_command; just close the file. */
    }

  /* Construct dummy HText thingie so Mosaic knows
     not to try to access this "document". */
  text = HText_new ();
  HText_beginAppend (text);
  /* If it's a real internal reference, tell Mosaic. */
  if (me->end_command) {
	if (strstr (me->end_command, "mosaic-internal-reference")) {
          HText_appendText (text, me->end_command);
	}
	else {
		HText_appendText (text, "<mosaic-access-override>\n");
	}
	free (me->end_command);
  }
  else {
      /* No me->end_command; just override the access. */
      HText_appendText (text, "<mosaic-access-override>\n");
  }
  HText_endAppend (text);

 done:
  if (binary_transfer)
    rename_binary_file (me->fnam);

 really_done:
  free (me->fnam);
  if (me->mime_type) {
	free(me->mime_type);
  }
  free (me);

  return;
}
Пример #3
0
PRIVATE void parse_menu ARGS2 (
                               CONST char *,	arg,
                               HTParentAnchor *,anAnchor)
{
  char gtype;
  char ch;
  char line[BIG];
  char address[BIG];
  char *name, *selector;		/* Gopher menu fields */
  char *host;
  char *port;
  char *p = line;
  
  
#define TAB 		'\t'
#define HEX_ESCAPE 	'%'
  
  if (!HTAnchor_title(anAnchor))
    HTAnchor_setTitle(anAnchor, arg);/* Tell user something's happening */
  
  node_anchor = anAnchor;
  HT = HText_new(anAnchor);
  
  HText_beginAppend(HT);
  HText_appendText(HT, "Select one of:<P>\n<UL>");
  /* HText_appendText(HT, "Select one of:<P>\n<UL>"); */
  
  while ((ch=NEXT_CHAR) != (char)EOF) 
    {
      if (ch != '\n') 
        {
          *p = ch;		/* Put character in line */
          if (p< &line[BIG-1]) p++;
        } 
      else 
        {
          *p++ = 0;		/* Terminate line */
          p = line;		/* Scan it to parse it */
          port = 0;		/* Flag "not parsed" */
          if (TRACE) fprintf(stderr, "HTGopher: Menu item: %s\n", line);
          gtype = *p++;
          
          /* Break on line with a dot by itself */
          if ((gtype=='.') && ((*p=='\r') || (*p==0))) break;
          
          if (gtype && *p) 
            {
              name = p;
              selector = strchr(name, TAB);
              if (selector) {
                *selector++ = 0;	/* Terminate name */
                host = strchr(selector, TAB);
                if (host) {
                  *host++ = 0;	/* Terminate selector */
                  port = strchr(host, TAB);
                  if (port) {
                    char *junk;
                    port[0] = ':';	/* delimit host a la W3 */
                    junk = strchr(port, 13 /* was TAB */);
                    if (junk) *junk++ = 0;	/* Chop port */
                    if ((port[1]=='0') && (!port[2]))
                      port[0] = 0;	/* 0 means none */
                  } /* no port */
                } /* host ok */
              } /* selector ok */
            } /* gtype and name ok */
          
          if (gtype == GOPHER_WWW) 
            {	/* Gopher pointer to W3 */
              HText_appendText(HT, "<LI> ");
              write_anchor(name, selector);
              HText_appendText(HT, "\n");
              /* HText_appendParagraph(HT); */
            } 
          else if (port) 
            {		/* Other types need port */
              if (gtype == GOPHER_TELNET) 
                {
                  if (*selector) 
                    sprintf(address, "telnet://%s@%s/",
                            selector, host);
                  else 
                    sprintf(address, "telnet://%s/", host);
                }
              else if (gtype == GOPHER_TN3270) 
                {
                  if (*selector) 
                    sprintf(address, "tn3270://%s@%s/",
                            selector, host);
                  else 
                    sprintf(address, "tn3270://%s/", host);
                }
              else 
                {			/* If parsed ok */
                  char *q;
                  char *p;
                  sprintf(address, "gopher://%s/%c", host, gtype);
                  q = address+ strlen(address);
                  for(p=selector; *p; p++) {	/* Encode selector string */
                    /* fprintf (stderr, "Checking %d (%c) for acceptable.\n",
                     *p, *p); */
                    if (acceptable[*p]) *q++ = *p;
                    else {
                      *q++ = HEX_ESCAPE;	/* Means hex coming */
                      *q++ = hex[(TOASCII(*p)) >> 4];
                      *q++ = hex[(TOASCII(*p)) & 15];
                    }
                  }
                  *q++ = 0;			/* terminate address */
                }
              /* HText_appendText(HT, "        "); */ /* Prettier JW/TBL */
              HText_appendText(HT, "<LI> ");
              /* Error response from Gopher doesn't deserve to
                 be a hyperlink. */
              if (strcmp (address, "gopher://error.host:1/0"))
                write_anchor(name, address);
              else
                HText_appendText(HT, name);
              HText_appendText(HT, "\n");
              /* HText_appendParagraph(HT); */
            } 
          else 
            { /* parse error */
              if (TRACE) fprintf(stderr,
                                 "HTGopher: Bad menu item.\n");
              HText_appendText(HT, line);
              HText_appendParagraph(HT);
            } /* parse error */
          
          p = line;	/* Start again at beginning of line */
          
        } /* if end of line */
      
    } /* Loop over characters */
Пример #4
0
/*	Load a document
**	---------------
**
** On entry,
**	addr		must point to the fully qualified hypertext reference.
**			This is the physsical address of the file
**
** On exit,
**	returns		<0		Error has occured.
**			HTLOADED	OK 
**
*/
PUBLIC int HTLoadFile ARGS4 (
	WWW_CONST char *,		addr,
	HTParentAnchor *,	anchor,
	HTFormat,		format_out,
	HTStream *,		sink
)
{
    char * filename;
    HTFormat format;
    int fd = -1;		/* Unix file descriptor number = INVALID */
    char * nodename = 0;
    char * newname=0;	/* Simplified name of file */
    HTAtom * encoding;	/* @@ not used yet */
    int compressed;
    extern char *HTgeticonname(HTFormat, char *);
    
/*	Reduce the filename to a basic form (hopefully unique!)
*/
    StrAllocCopy(newname, addr);
    filename=HTParse(newname, "", PARSE_PATH|PARSE_PUNCTUATION);
    nodename=HTParse(newname, "", PARSE_HOST);
    free(newname);
    
    format = HTFileFormat(filename, &encoding, WWW_PLAINTEXT, &compressed);


#ifdef vms
/* Assume that the file is in Unix-style syntax if it contains a '/'
   after the leading one @@ */
    {
	char * vmsname = strchr(filename + 1, '/') ?
	  vms_name(nodename, filename) : filename + 1;
	fd = open(vmsname, O_RDONLY, 0);
	
/*	If the file wasn't VMS syntax, then perhaps it is ultrix
*/
	if (fd<0) {
	    char ultrixname[INFINITY];
#ifndef DISABLE_TRACE
	    if (www2Trace) fprintf(stderr, "HTFile: Can't open as %s\n", vmsname);
#endif
	    sprintf(ultrixname, "%s::\"%s\"", nodename, filename);
	    fd = open(ultrixname, O_RDONLY, 0);
	    if (fd<0) {
#ifndef DISABLE_TRACE
		if (www2Trace) fprintf(stderr, 
				   "HTFile: Can't open as %s\n", ultrixname);
#endif
	    }
	}
    }
#else

    free(filename);
    
/*	For unix, we try to translate the name into the name of a transparently
**	mounted file.
**
**	Not allowed in secure (HTClienntHost) situations TBL 921019
*/
#ifndef NO_UNIX_IO
    /*  Need protection here for telnet server but not httpd server */
	 
    {		/* try local file system */
	char * localname = HTLocalName(addr);
	struct stat dir_info;

        if (!localname)
          goto suicide;
	
#ifdef GOT_READ_DIR

/*			  Multiformat handling
**
**	If needed, scan directory to find a good file.
**  Bug:  we don't stat the file to find the length
*/
	if ( (strlen(localname) > strlen(MULTI_SUFFIX))
	   && (0==strcmp(localname + strlen(localname) - strlen(MULTI_SUFFIX),
	                  MULTI_SUFFIX))) {
	    DIR *dp;

	    STRUCT_DIRENT * dirbuf;
	    float best = NO_VALUE_FOUND;	/* So far best is bad */
	    HTFormat best_rep = NULL;	/* Set when rep found */
	    STRUCT_DIRENT best_dirbuf;	/* Best dir entry so far */

	    char * base = strrchr(localname, '/');
	    int baselen;

	    if (!base || base == localname) goto forget_multi;
	    *base++ = 0;		/* Just got directory name */
	    baselen = strlen(base)- strlen(MULTI_SUFFIX);
	    base[baselen] = 0;	/* Chop off suffix */

	    dp = opendir(localname);
	    if (!dp) {
forget_multi:
		free(localname);
		return HTLoadError(sink, 500,
			"Multiformat: directory scan failed.");
	    }
	    
	    while (dirbuf = readdir(dp)) {
			/* while there are directory entries to be read */
		if (dirbuf->d_ino == 0) continue;
				/* if the entry is not being used, skip it */
		
		if (!strncmp(dirbuf->d_name, base, baselen)) {	
		    HTFormat rep = HTFileFormat(dirbuf->d_name, &encoding,
                                                WWW_PLAINTEXT, &compressed);
		    float value = HTStackValue(rep, format_out,
		    				HTFileValue(dirbuf->d_name),
						0.0  /* @@@@@@ */);
		    if (value != NO_VALUE_FOUND) {
#ifndef DISABLE_TRACE
		        if (www2Trace) fprintf(stderr,
				"HTFile: value of presenting %s is %f\n",
				HTAtom_name(rep), value);
#endif
			if  (value > best) {
			    best_rep = rep;
			    best = value;
			    best_dirbuf = *dirbuf;
		       }
		    }	/* if best so far */ 		    
		 } /* if match */  
		    
	    } /* end while directory entries left to read */
	    closedir(dp);
	    
	    if (best_rep) {
		format = best_rep;
		base[-1] = '/';		/* Restore directory name */
		base[0] = 0;
		StrAllocCat(localname, best_dirbuf.d_name);
		goto open_file;
		
	    } else { 			/* If not found suitable file */
		free(localname);
		return HTLoadError(sink, 403,	/* List formats? */
		   "Could not find suitable representation for transmission.");
	    }
	    /*NOTREACHED*/
	} /* if multi suffix */
/*
**	Check to see if the 'localname' is in fact a directory.  If it is
**	create a new hypertext object containing a list of files and 
**	subdirectories contained in the directory.  All of these are links
**      to the directories or files listed.
**      NB This assumes the existance of a type 'STRUCT_DIRENT', which will
**      hold the directory entry, and a type 'DIR' which is used to point to
**      the current directory being read.
*/
	
	
	if (stat(localname,&dir_info) == -1) {     /* get file information */
	                               /* if can't read file information */
#ifndef DISABLE_TRACE
	    if (www2Trace) fprintf(stderr, "HTFile: can't stat %s\n", localname);
#endif
	}  else {		/* Stat was OK */
		

	    if (((dir_info.st_mode) & S_IFMT) == S_IFDIR) {
		/* if localname is a directory */	

/*
**
** Read the localdirectory and present a nicely formatted list to the user
** Re-wrote most of the read directory code here, excepting for the checking
** access.
**
** Author: Charles Henrich ([email protected])   10-09-93
**
** This is still pretty messy, need to go through and clean it up at some point
**
*/

/* Define some parameters that everyone should already have */

#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif

#ifndef BUFSIZ
#define BUFSIZ 4096
#endif

                char filepath[MAXPATHLEN];
                char buffer[4096];
     
                char *ptr;
                char *dataptr;

                HText * HT;
                HTFormat format;
                HTAtom *pencoding;

		struct stat statbuf;
		STRUCT_DIRENT * dp;
		DIR *dfp;
 
                int cmpr;
                int count;

#ifndef DISABLE_TRACE
		if (www2Trace)
		    fprintf(stderr,"%s is a directory\n",localname);
#endif			
/*	Check directory access.
**	Selective access means only those directories containing a
**	marker file can be browsed
*/
		if (HTDirAccess == HT_DIR_FORBID) {
		    free(localname);
		    return HTLoadError(sink, 403,
		    "Directory browsing is not allowed.");
		}


		if (HTDirAccess == HT_DIR_SELECTIVE) {
		    char * enable_file_name = 
			malloc(strlen(localname)+ 1 +
			 strlen(HT_DIR_ENABLE_FILE) + 1);
		    strcpy(enable_file_name, localname);
		    strcat(enable_file_name, "/");
		    strcat(enable_file_name, HT_DIR_ENABLE_FILE);
		    if (stat(enable_file_name, &statbuf) != 0) {
			free(localname);
			return HTLoadError(sink, 403,
			"Selective access is not enabled for this directory.");
		    }
		}

 
		dfp = opendir(localname);
		if (!dfp) {
		    free(localname);
		    return HTLoadError(sink, 403, "This directory is not readable.");
		}

/* Suck the directory up into a list to be sorted */

                HTSortInit();

                for(dp=readdir(dfp);dp != NULL;dp=readdir(dfp))
                    {
                    ptr = malloc(strlen(dp->d_name)+1);
                    if(ptr == NULL)
                        {
		        return HTLoadError(sink, 403, "Ran out of memory in directory read!");
                        }
                    strcpy(ptr,dp->d_name);
                     
                    HTSortAdd(ptr);
                    }

                closedir(dfp);

/* Sort the dir list */

                HTSortSort();

/* Start a new HTML page */

                HT = HText_new();
                HText_beginAppend(HT);
                HText_appendText(HT, "<H1>Local Directory ");
                HText_appendText(HT, localname);
                HText_appendText(HT, "</H1>\n");
                HText_appendText(HT,"<DL>\n"); 

/* Sort the list and then spit it out in a nice form */

/* How this for a disgusting loop :) */

                for(count=0,dataptr=HTSortFetch(count); 
                    dataptr != NULL; 
                    free(dataptr), count++, dataptr=HTSortFetch(count))
                    {

/* We dont want to see . */

                    if(strcmp(dataptr,".") == 0) continue;
 
/* If its .. *and* the current directory is / dont show anything, otherwise
/* print out a nice Parent Directory entry.
/* */

                    if(strcmp(dataptr,"..") == 0)
                        {
                        if(strcmp(localname,"/") != 0)
                            {
                            strcpy(buffer,localname);

                            ptr = strrchr(buffer, '/');

                            if(ptr != NULL) *ptr='\0'; 

                            if(buffer[0] == '\0') strcpy(buffer,"/");

                            HText_appendText(HT,"<DD><A HREF=\"");
                            HText_appendText(HT, buffer);

                            HText_appendText(HT,"\"><IMG SRC=\"");
                            HText_appendText(HT, HTgeticonname(NULL, "directory"));

                            HText_appendText(HT,"\"> Parent Directory</a>");
                            continue;
                            }
                        else
                            {
                            continue;
                            }
                        }
                      
/* Get the filesize information from a stat, if we cant stat it, we probably */
/* cant read it either, so ignore it. */

                    sprintf(filepath,"%s/%s",localname, dataptr);

                    if(stat(filepath, &statbuf) == -1) continue;
     
                    HText_appendText(HT,"<DD><A HREF=\"");
                    HText_appendText (HT, localname);

                    if(localname[strlen(localname)-1] != '/') 
                        {
                        HText_appendText (HT, "/");
                        }

                    HText_appendText (HT, dataptr);
                    HText_appendText (HT, "\">");

/* If its a directory, dump out a dir icon, dont bother with anything else */
/* if it is a file try and figure out what type of file it is, and grab    */
/* the appropriate icon.  If we cant figure it out, call it text.  If its  */
/* a compressed file, call it binary no matter what                        */

                    if(statbuf.st_mode & S_IFDIR)
                        {
                        sprintf(buffer,"%s",dataptr);
                        HText_appendText(HT, "<IMG SRC=\"");
                        HText_appendText(HT, HTgeticonname(NULL, "directory"));
                        HText_appendText(HT, "\"> ");
                        }
                    else
                        {
                        sprintf(buffer,"%s (%d bytes)", 
                            dataptr, (int)statbuf.st_size);
              
                        format = HTFileFormat(dataptr, &pencoding, 
                                     WWW_SOURCE, &cmpr);

/* If its executable then call it application, else it might as well be text */

                        if(cmpr == 0)
                            {
                            HText_appendText(HT, "<IMG SRC=\"");
                            if((statbuf.st_mode & S_IXUSR) ||
                               (statbuf.st_mode & S_IXGRP) || 
                               (statbuf.st_mode & S_IXOTH))
                                {
                                HText_appendText(HT, 
                                    HTgeticonname(format, "application"));
                                }
                            else
                                {
                                HText_appendText(HT, 
                                    HTgeticonname(format, "text"));
                                }
                            HText_appendText(HT, "\"> ");
                            }
                        else
                            {
                            HText_appendText(HT, "<IMG SRC=\"");
                            HText_appendText(HT, HTgeticonname(NULL, "application"));
                            HText_appendText(HT, "\"> ");
                            }
                        }

/* Spit out the anchor */

                    HText_appendText (HT, buffer);
                    HText_appendText (HT, "</A>\n");
		    }

/* End of list, clean up and we are done */

            HText_appendText (HT, "</DL>\n");
            HText_endAppend (HT);
            free(localname);
            return HT_LOADED;
	    } /* end if localname is directory */
	
	} /* end if file stat worked */
	
/* End of directory reading section
*/
#endif
open_file:
	{
	    FILE * fp = fopen(localname,"r");
#ifndef DISABLE_TRACE
	    if(www2Trace) fprintf (stderr, "HTFile: Opening `%s' gives %p\n",
				localname, (void*)fp);
#endif
	    if (fp) {		/* Good! */
		if (HTEditable(localname)) {
		    HTAtom * put = HTAtom_for("PUT");
		    HTList * methods = HTAnchor_methods(anchor);
		    if (HTList_indexOf(methods, put) == (-1)) {
			HTList_addObject(methods, put);
		    }
		}
		free(localname);
		HTParseFile(format, format_out, anchor, fp, sink, compressed);
/*
This is closed elsewhere...SWP
		fclose(fp);
*/
		return HT_LOADED;
	    }  /* If succesfull open */
	}    /* scope of fp */
    }  /* local unix file system */    
#endif
#endif

/*	Now, as transparently mounted access has failed, we try FTP.
*/
  suicide:
/*
    return HTFTPLoad(addr, anchor, format_out, sink);
*/
  /* Sorry Charlie...if we are given a file:// URL and it fails, then it
	fails! Do NOT FTP!! */
    return HT_NOT_LOADED;
}