Example #1
0
PRIVATE void free_channel (HTChannel * ch)
{
    if (ch) {

        /* Close the input and output stream */
        if (ch->input) {
            (*ch->input->isa->close)(ch->input);
            ch->input = NULL;
        }
        if (ch->output) {
            (*ch->output->isa->close)(ch->output);
            ch->output = NULL;
        }

        /* Close the socket */
        if (ch->sockfd != INVSOC) {
            NETCLOSE(ch->sockfd);
            HTNet_decreaseSocket();
            HTTRACE(PROT_TRACE, "Channel..... Deleted %p, socket %d\n" _ ch _ ch->sockfd);
            ch->sockfd = INVSOC;
        }

        /* Close the file */
        if (ch->fp) {
            fclose(ch->fp);
            HTTRACE(PROT_TRACE, "Channel..... Deleted %p, file %p\n" _ ch _ ch->fp);
            ch->fp = NULL;
        }
        HT_FREE(ch);
    }
}
Example #2
0
PRIVATE int response ARGS1(CONST char *,command)
{
    int result;    
    char * p = response_text;
    if (command) {
        int status;
	int length = strlen(command);
	if (TRACE) fprintf(stderr, "NNTP command to be sent: %s", command);
#ifdef NOT_ASCII
	{
	    CONST char  * p;
	    char 	* q;
	    char ascii[LINE_LENGTH+1];
	    for(p = command, q=ascii; *p; p++, q++) {
		*q = TOASCII(*p);
	    }
            status = NETWRITE(s, ascii, length);
	}
#else
        status = NETWRITE(s, command, length);
#endif
	if (status<0){
	    if (TRACE) fprintf(stderr,
	        "HTNews: Unable to send command. Disconnecting.\n");
	    NETCLOSE(s);
	    s = -1;
	    return status;
	} /* if bad status */
    } /* if command to be sent */
    
    for(;;) {  
	if (((*p++=NEXT_CHAR) == '\n') || (p == &response_text[LINE_LENGTH])) {
	    *p++=0;				/* Terminate the string */
	    if (TRACE) fprintf(stderr, "NNTP Response: %s\n", response_text);
	    sscanf(response_text, "%d", &result);
	    return result;	    
	} /* if end of line */
	
	if (*(p-1) < 0) {
	    if (TRACE) fprintf(stderr,
	    	"HTNews: EOF on read, closing socket %d\n", s);
	    NETCLOSE(s);	/* End of file, close socket */
	    return s = -1;	/* End of file on response */
	}
    } /* Loop over characters */
}
Example #3
0
/*	Parse a socket given format and file number
**
**   This routine is responsible for creating and PRESENTING any
**   graphic (or other) objects described by the file.
**
**   The file number given is assumed to be a TELNET stream ie containing
**   CRLF at the end of lines which need to be stripped to LF for unix
**   when the format is textual.
**
*/
PUBLIC int HTParseSocket ARGS6(
	HTFormat,		format_in,
	HTFormat,		format_out,
	HTParentAnchor *,	anchor,
	int,			file_number,
	HTStream*,		sink,
        int,                    compressed)
{
  HTStream * stream;
  HTStreamClass targetClass;    
  int rv;
  
  stream = HTStreamStack(format_in,
                         format_out,
                         compressed,
                         sink, anchor);
  
  if (!stream) 
    {
      char buffer[1024];	/* @@@@@@@@ */
      sprintf(buffer, "Sorry, can't convert from %s to %s.",
              HTAtom_name(format_in), HTAtom_name(format_out));
#ifndef DISABLE_TRACE
      if (www2Trace) fprintf(stderr, "HTFormat: %s\n", buffer);
#endif
      return HTLoadError(sink, 501, buffer);
    }
    
  targetClass = *(stream->isa);	/* Copy pointers to procedures */
  rv = HTCopy(file_number, stream, 0);
  if (rv == -1)
    {
      /* handle_interrupt should have been done in HTCopy */
      /* (*targetClass.handle_interrupt)(stream); */
      return HT_INTERRUPTED;
    }

  (*targetClass.end_document)(stream);

  /* New thing: we force close the data socket here, so that if
     an external viewer gets forked off in the free method below,
     the connection doesn't remain upon until the child exits --
     which it does if we don't do this. */
  NETCLOSE (file_number);

  (*targetClass.free)(stream);
    
  return HT_LOADED;
}
Example #4
0
static int
echo_client(char *hostname, const int fd)
{
  /*
   * WRITE TEXT FROM FILE DESCRIPTOR INTO STDOUT
   */
  char buf[BUFSIZ];
  int  cc;
  D_PRINTF( "echo_client running\n" );

  while (getppid() != 1)
    {
      cc = NETREAD(fd, buf, sizeof(buf));
      if (cc > 0)
      {
    write(STDOUT_FILENO, buf, cc);
      }
  }
  D_PRINTF( "Exiting echo_client\n" );
  NETCLOSE(fd);
}
Example #5
0
/*
**	Closes a file descriptor whatever means are available on the current
**	platform. If we have unix file descriptors then use this otherwise use
**	the ANSI C file descriptors
**
**	returns		HT_ERROR	Error has occured or interrupted
**			HT_OK		if connected
**			HT_WOULD_BLOCK  if operation would have blocked
*/
PUBLIC int HTFileClose (HTNet * net)
{
    HTHost * host = HTNet_host(net);
    HTChannel * ch = HTHost_channel(host);
    int status = -1;
    if (net && ch) {
#ifdef NO_UNIX_IO
	FILE * fp = HTChannel_file(ch);
	if (fp) {
	    HTTRACE(PROT_TRACE, "Closing..... ANSI file %p\n" _ fp);
	    status = fclose(fp);
	    HTChannel_setFile(ch, NULL);
	}
#else
	SOCKET sockfd = HTChannel_socket(ch);
	if (sockfd != INVSOC) {
	    HTTRACE(PROT_TRACE, "Closing..... fd %d\n" _ sockfd);
	    status = NETCLOSE(sockfd);
	    HTChannel_setSocket(ch, INVSOC);
	}
#endif /* NO_UNIX_IO */
    }
    return status < 0 ? HT_ERROR : HT_OK;
}
Example #6
0
/*		Load by name					HTLoadFinger
 *		============
 */
int HTLoadFinger(const char *arg,
		 HTParentAnchor *anAnchor,
		 HTFormat format_out,
		 HTStream *stream)
{
    static char empty[1];

    char *username, *sitename;	/* Fields extracted from URL */
    char *slash, *at_sign;	/* Fields extracted from URL */
    char *command, *str, *param;	/* Buffers */
    int port;			/* Port number from URL */
    int status;			/* tcp return */
    int result = HT_LOADED;
    BOOL IsGopherURL = FALSE;
    const char *p1 = arg;

    CTRACE((tfp, "HTFinger: Looking for %s\n", (arg ? arg : "NULL")));

    if (!(arg && *arg)) {
	HTAlert(COULD_NOT_LOAD_DATA);
	return HT_NOT_LOADED;	/* Ignore if no name */
    }

    if (!initialized)
	initialized = initialize();
    if (!initialized) {
	HTAlert(gettext("Could not set up finger connection."));
	return HT_NOT_LOADED;	/* FAIL */
    }

    /*  Set up the host and command fields.
     */
    if (!strncasecomp(arg, "finger://", 9)) {
	p1 = arg + 9;		/* Skip "finger://" prefix */
    } else if (!strncasecomp(arg, "gopher://", 9)) {
	p1 = arg + 9;		/* Skip "gopher://" prefix */
	IsGopherURL = TRUE;
    }

    param = 0;
    sitename = StrAllocCopy(param, p1);
    if (param == 0) {
	HTAlert(COULD_NOT_LOAD_DATA);
	return HT_NOT_LOADED;
    } else if ((slash = StrChr(sitename, '/')) != NULL) {
	*slash++ = '\0';
	HTUnEscape(slash);
	if (IsGopherURL) {
	    if (*slash != '0') {
		HTAlert(COULD_NOT_LOAD_DATA);
		return HT_NOT_LOADED;	/* FAIL */
	    }
	    *slash++ = '\0';
	}
    }

    if ((at_sign = StrChr(sitename, '@')) != NULL) {
	if (IsGopherURL) {
	    HTAlert(COULD_NOT_LOAD_DATA);
	    return HT_NOT_LOADED;	/* FAIL */
	} else {
	    *at_sign++ = '\0';
	    username = sitename;
	    sitename = at_sign;
	    HTUnEscape(username);
	}
    } else if (slash) {
	username = slash;
    } else {
	username = empty;
    }

    if (*sitename == '\0') {
	HTAlert(gettext("Could not load data (no sitename in finger URL)"));
	result = HT_NOT_LOADED;	/* Ignore if no name */
    } else if (HTParsePort(sitename, &port) != NULL) {
	if (port != 79) {
	    HTAlert(gettext("Invalid port number - will only use port 79!"));
	    result = HT_NOT_LOADED;	/* Ignore if wrong port */
	}
    }

    if (result == HT_LOADED) {
	/* Load the string for making a connection/
	 */
	str = 0;
	HTSprintf0(&str, "lose://%s/", sitename);

	/* Load the command for the finger server.
	 */
	command = 0;
	if (at_sign && slash) {
	    if (*slash == 'w' || *slash == 'W') {
		HTSprintf0(&command, "/w %s%c%c", username, CR, LF);
	    } else {
		HTSprintf0(&command, "%s%c%c", username, CR, LF);
	    }
	} else if (at_sign) {
	    HTSprintf0(&command, "%s%c%c", username, CR, LF);
	} else if (*username == '/') {
	    if ((slash = StrChr((username + 1), '/')) != NULL) {
		*slash = ' ';
	    }
	    HTSprintf0(&command, "%s%c%c", username, CR, LF);
	} else if ((*username == 'w' || *username == 'W') &&
		   *(username + 1) == '/') {
	    if (*username + 2 != '\0') {
		*(username + 1) = ' ';
	    } else {
		*(username + 1) = '\0';
	    }
	    HTSprintf0(&command, "/%s%c%c", username, CR, LF);
	} else if ((*username == 'w' || *username == 'W') &&
		   *(username + 1) == '\0') {
	    HTSprintf0(&command, "/%s%c%c", username, CR, LF);
	} else if ((slash = StrChr(username, '/')) != NULL) {
	    *slash++ = '\0';
	    if (*slash == 'w' || *slash == 'W') {
		HTSprintf0(&command, "/w %s%c%c", username, CR, LF);
	    } else {
		HTSprintf0(&command, "%s%c%c", username, CR, LF);
	    }
	} else {
	    HTSprintf0(&command, "%s%c%c", username, CR, LF);
	}

	/* Now, let's get a stream setup up from the FingerHost:
	 * CONNECTING to finger host
	 */
	CTRACE((tfp, "HTFinger: doing HTDoConnect on '%s'\n", str));
	status = HTDoConnect(str, "finger", FINGER_PORT, &finger_fd);
	CTRACE((tfp, "HTFinger: Done DoConnect; status %d\n", status));

	if (status == HT_INTERRUPTED) {
	    /* Interrupt cleanly */
	    CTRACE((tfp,
		    "HTFinger: Interrupted on connect; recovering cleanly.\n"));
	    HTProgress(CONNECTION_INTERRUPTED);
	    result = HT_NOT_LOADED;
	} else if (status < 0) {
	    NETCLOSE(finger_fd);
	    finger_fd = -1;
	    CTRACE((tfp, "HTFinger: Unable to connect to finger host.\n"));
	    HTAlert(gettext("Could not access finger host."));
	    result = HT_NOT_LOADED;	/* FAIL */
	} else {
	    CTRACE((tfp, "HTFinger: Connected to finger host '%s'.\n", str));

	    /* Send the command, and process response if successful.
	     */
	    if (response(command, sitename, anAnchor, format_out, stream) != 0) {
		HTAlert(gettext("No response from finger server."));
		result = HT_NOT_LOADED;
	    }
	}
	FREE(str);
	FREE(command);
    }
    FREE(param);
    return result;
}
Example #7
0
static int response(char *command,
		    char *sitename,
		    HTParentAnchor *anAnchor,
		    HTFormat format_out,
		    HTStream *sink)
{
    int status;
    int length = (int) strlen(command);
    int ch, i;
    char line[BIG], *l, *cmd = NULL;
    char *p = line, *href = NULL;

    if (length == 0)
	return (-1);

    /* Set up buffering.
     */
    HTInitInput(finger_fd);

    /* Send the command.
     */
    CTRACE((tfp, "HTFinger command to be sent: %s", command));
    status = (int) NETWRITE(finger_fd, (char *) command, (unsigned) length);
    if (status < 0) {
	CTRACE((tfp, "HTFinger: Unable to send command. Disconnecting.\n"));
	NETCLOSE(finger_fd);
	finger_fd = -1;
	return status;
    }
    /* if bad status */
    /* Make a hypertext object with an anchor list.
     */
    target = HTML_new(anAnchor, format_out, sink);
    targetClass = *target->isa;	/* Copy routine entry points */

    /* Create the results report.
     */
    CTRACE((tfp, "HTFinger: Reading finger information\n"));
    START(HTML_HTML);
    PUTC('\n');
    START(HTML_HEAD);
    PUTC('\n');
    START(HTML_TITLE);
    PUTS("Finger server on ");
    PUTS(sitename);
    END(HTML_TITLE);
    PUTC('\n');
    END(HTML_HEAD);
    PUTC('\n');
    START(HTML_BODY);
    PUTC('\n');
    START(HTML_H1);
    PUTS("Finger server on ");
    START(HTML_EM);
    PUTS(sitename);
    END(HTML_EM);
    PUTS(": ");
    StrAllocCopy(cmd, command);
    for (i = ((int) strlen(cmd) - 1); i >= 0; i--) {
	if (cmd[i] == LF || cmd[i] == CR) {
	    cmd[i] = '\0';
	} else {
	    break;
	}
    }
    PUTS(cmd);
    FREE(cmd);
    END(HTML_H1);
    PUTC('\n');
    START(HTML_PRE);

    while ((ch = NEXT_CHAR) != EOF) {

	if (interrupted_in_htgetcharacter) {
	    CTRACE((tfp,
		    "HTFinger: Interrupted in HTGetCharacter, apparently.\n"));
	    _HTProgress(CONNECTION_INTERRUPTED);
	    goto end_html;
	}

	if (ch != LF) {
	    *p = (char) ch;	/* Put character in line */
	    if (p < &line[BIG - 1]) {
		p++;
	    }
	} else {
	    *p = '\0';		/* Terminate line */
	    /*
	     * OK we now have a line.
	     * Load it as 'l' and parse it.
	     */
	    p = l = line;
	    while (*l) {
		if (StrNCmp(l, STR_NEWS_URL, LEN_NEWS_URL) &&
		    StrNCmp(l, "snews://", 8) &&
		    StrNCmp(l, "nntp://", 7) &&
		    StrNCmp(l, "snewspost:", 10) &&
		    StrNCmp(l, "snewsreply:", 11) &&
		    StrNCmp(l, "newspost:", 9) &&
		    StrNCmp(l, "newsreply:", 10) &&
		    StrNCmp(l, "ftp://", 6) &&
		    StrNCmp(l, "file:/", 6) &&
		    StrNCmp(l, "finger://", 9) &&
		    StrNCmp(l, "http://", 7) &&
		    StrNCmp(l, "https://", 8) &&
		    StrNCmp(l, "wais://", 7) &&
		    StrNCmp(l, STR_MAILTO_URL, LEN_MAILTO_URL) &&
		    StrNCmp(l, "cso://", 6) &&
		    StrNCmp(l, "gopher://", 9))
		    PUTC(*l++);
		else {
		    StrAllocCopy(href, l);
		    start_anchor(strtok(href, " \r\n\t,>)\""));
		    while (*l && !StrChr(" \r\n\t,>)\"", *l))
			PUTC(*l++);
		    END(HTML_A);
		    FREE(href);
		}
	    }
	    PUTC('\n');
	}
    }
    NETCLOSE(finger_fd);
    finger_fd = -1;

  end_html:
    END(HTML_PRE);
    PUTC('\n');
    END(HTML_BODY);
    PUTC('\n');
    END(HTML_HTML);
    PUTC('\n');
    FREE_TARGET;
    return (0);
}
Example #8
0
/*	Push data from a socket down a stream
**	-------------------------------------
**
**   This routine is responsible for creating and PRESENTING any
**   graphic (or other) objects described by the file.
**
**   The file number given is assumed to be a TELNET stream, i.e., containing
**   CRLF at the end of lines which need to be stripped to LF for unix
**   when the format is textual.
**
**  State of socket and target stream on entry:
**			socket (file_number) assumed open,
**			target (sink) assumed valid.
**
**  Return values:
**	HT_INTERRUPTED  Interruption or error after some data received.
**	-2		Unexpected disconnect before any data received.
**	-1		Interruption or error before any data received, or
**			(UNIX) other read error before any data received, or
**			download cancelled.
**	HT_LOADED	Normal close of socket (end of file indication
**			received), or
**			unexpected disconnect after some data received, or
**			other read error after some data received, or
**			(not UNIX) other read error before any data received.
**
**  State of socket and target stream on return depends on return value:
**	HT_INTERRUPTED	socket still open, target aborted.
**	-2		socket still open, target stream still valid.
**	-1		socket still open, target aborted.
**	otherwise	socket closed,	target stream still valid.
*/
PUBLIC int HTCopy ARGS4(
	HTParentAnchor *,	anchor,
	int,			file_number,
	void*,			handle GCC_UNUSED,
	HTStream*,		sink)
{
    HTStreamClass targetClass;
    BOOL suppress_readprogress = NO;
    int bytes;
    int rv = 0;

    /*	Push the data down the stream
    */
    targetClass = *(sink->isa); /* Copy pointers to procedures */

    /*	Push binary from socket down sink
    **
    **	This operation could be put into a main event loop
    */
    HTReadProgress(bytes = 0, 0);
    for (;;) {
	int status;

	if (LYCancelDownload) {
	    LYCancelDownload = FALSE;
	    (*targetClass._abort)(sink, NULL);
	    rv = -1;
	    goto finished;
	}

	if (HTCheckForInterrupt()) {
	    _HTProgress (TRANSFER_INTERRUPTED);
	    (*targetClass._abort)(sink, NULL);
	    if (bytes)
		rv = HT_INTERRUPTED;
	    else
		rv = -1;
	    goto finished;
	}

#ifdef USE_SSL
	if (handle)
	    status = SSL_read((SSL *)handle, input_buffer, INPUT_BUFFER_SIZE);
	else
	    status = NETREAD(file_number, input_buffer, INPUT_BUFFER_SIZE);
#else
	status = NETREAD(file_number, input_buffer, INPUT_BUFFER_SIZE);
#endif /* USE_SSL */

	if (status <= 0) {
	    if (status == 0) {
		break;
	    } else if (status == HT_INTERRUPTED) {
		_HTProgress (TRANSFER_INTERRUPTED);
		(*targetClass._abort)(sink, NULL);
		if (bytes)
		    rv = HT_INTERRUPTED;
		else
		    rv = -1;
		goto finished;
	    } else if (SOCKET_ERRNO == ENOTCONN ||
#ifdef _WINDOWS	/* 1997/11/10 (Mon) 16:57:18 */
		       SOCKET_ERRNO == ETIMEDOUT ||
#endif
		       SOCKET_ERRNO == ECONNRESET ||
		       SOCKET_ERRNO == EPIPE) {
		/*
		 *  Arrrrgh, HTTP 0/1 compatibility problem, maybe.
		 */
		if (bytes <= 0) {
		    /*
		     *	Don't have any data, so let the calling
		     *	function decide what to do about it. - FM
		     */
		    rv = -2;
		    goto finished;
		} else {
#ifdef UNIX
		   /*
		    *  Treat what we've received already as the complete
		    *  transmission, but not without giving the user
		    *  an alert.  I don't know about all the different
		    *  TCP stacks for VMS etc., so this is currently
		    *  only for UNIX. - kw
		    */
		   HTInetStatus("NETREAD");
		   HTAlert("Unexpected server disconnect.");
		   CTRACE((tfp,
	    "HTCopy: Unexpected server disconnect. Treating as completed.\n"));
		   status = 0;
		   break;
#else  /* !UNIX */
		   /*
		    *  Treat what we've gotten already
		    *  as the complete transmission. - FM
		    */
		   CTRACE((tfp,
	    "HTCopy: Unexpected server disconnect.  Treating as completed.\n"));
		   status = 0;
		   break;
#endif /* UNIX */
		}
#ifdef UNIX
	    } else {		/* status < 0 and other errno */
		/*
		 *  Treat what we've received already as the complete
		 *  transmission, but not without giving the user
		 *  an alert.  I don't know about all the different
		 *  TCP stacks for VMS etc., so this is currently
		 *  only for UNIX. - kw
		 */
		HTInetStatus("NETREAD");
		HTAlert("Unexpected read error.");
		if (bytes) {
		    (void)NETCLOSE(file_number);
		    rv = HT_LOADED;
		} else {
		    (*targetClass._abort)(sink, NULL);
		    rv = -1;
		}
		goto finished;
#endif
	    }
	    break;
	}

	/*
	 *  Suppress ReadProgress messages when collecting a redirection
	 *  message, at least initially (unless/until anchor->content_type
	 *  gets changed, probably by the MIME message parser).  That way
	 *  messages put up by the HTTP module or elsewhere can linger in
	 *  the statusline for a while. - kw
	 */
	suppress_readprogress = (anchor && anchor->content_type &&
				 !strcmp(anchor->content_type,
					 "message/x-http-redirection"));
#ifdef NOT_ASCII
	{
	    char * p;
	    for (p = input_buffer; p < input_buffer+status; p++) {
		*p = FROMASCII(*p);
	    }
	}
#endif /* NOT_ASCII */

	(*targetClass.put_block)(sink, input_buffer, status);
	bytes += status;
	if (!suppress_readprogress)
	    HTReadProgress(bytes, anchor ? anchor->content_length : 0);
	HTDisplayPartial();

    } /* next bufferload */

    _HTProgress(TRANSFER_COMPLETE);
    (void)NETCLOSE(file_number);
    rv = HT_LOADED;

finished:
    HTFinishDisplayPartial();
    return(rv);
}
Example #9
0
/*		Load Document from HTTP Server			HTLoadHTTP()
**		==============================
**
**	Given a hypertext address, this routine loads a document.
**
**
** On entry,
**	arg	is the hypertext reference of the article to be loaded.
**	gate	is nill if no gateway, else the gateway address.
**
** On exit,
**	returns	>=0	If no error, a good socket number
**		<0	Error.
**
**	The socket must be closed by the caller after the document has been
**	read.
**
*/
PUBLIC int HTLoadHTTP ARGS4 (CONST char *, arg,
	CONST char *,	gate, 
	HTAnchor *,	anAnchor,
	int,		diag)
{
    int s;				/* Socket number for returned data */
    char *command;			/* The whole command */
    int status;				/* tcp return */
    char host[256];         /* Hold on to the host */
 
    SockA soc_address;			/* Binary network address */
    SockA * sin = &soc_address;

    if (!arg) return -3;		/* Bad if no name sepcified	*/
    if (!*arg) return -2;		/* Bad if name had zero length	*/

/*  Set up defaults:
*/
#ifdef DECNET
	sin->sdn_family = AF_DECnet;	    /* Family = DECnet, host order */
	sin->sdn_objnum = DNP_OBJ;          /* Default: http object number */
#else  /* Internet */
	sin->sin_family = AF_INET;	    /* Family = internet, host order */
	sin->sin_port = htons(TCP_PORT);    /* Default: http port    */
#endif

    if (TRACE) {
        if (gate) fprintf(stderr,
		"HTTPAccess: Using gateway %s for %s\n", gate, arg);
        else fprintf(stderr, "HTTPAccess: Direct access for %s\n", arg);
    }
    
/* Get node name and optional port number:
*/
    {
	char *p1 = HTParse(gate ? gate : arg, "", PARSE_HOST);
    strcpy(host, p1);
	int status = HTParseInet(sin, p1);  /* TBL 920622 */
        free(p1);
	if (status) return status;   /* No such host for example */
    }
    
   
/*	Now, let's get a socket set up from the server for the sgml data:
*/      
#ifdef DECNET
    s = socket(AF_DECnet, SOCK_STREAM, 0);
#else
    s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#endif
    status = connect(s, (struct sockaddr*)&soc_address, sizeof(soc_address));
    if (status < 0) {
#ifndef DECNET
	/* This code is temporary backward-compatibility. It should
	   go away when no server runs on port 2784 alone */
	if (sin->sin_port == htons(TCP_PORT)) {  /* Try the old one */
	  if (TRACE) printf (
	    "HTTP: Port %d doesn't answer (errno = %d). Trying good old port %d...\n",
	    TCP_PORT, errno, OLD_TCP_PORT);
	  sin->sin_port = htons(OLD_TCP_PORT);
	  /* First close current socket and open a clean one */
	  status = NETCLOSE (s);
	  s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
	  status = connect(s, (struct sockaddr*)&soc_address,
			   sizeof(soc_address));
	}
	if (status < 0)
#endif
	  {
	    if (TRACE) fprintf(stderr, 
	      "HTTP: Unable to connect to remote host for `%s' (errno = %d).\n", arg, errno);
	    /* free(command);   BUG OUT TBL 921121 */
	    return HTInetStatus("connect");
	  }
      }
    
    if (TRACE) fprintf(stderr, "HTTP connected, socket %d\n", s);

/*	Ask that node for the document,
**	omitting the host name & anchor if not gatewayed.
*/        
    if (gate) {
        command = malloc(4 + strlen(arg)+ 2 + 1);
        if (command == NULL) outofmem(__FILE__, "HTLoadHTTP");
        strcpy(command, "GET ");
	strcat(command, arg);
    } else if ( HTTP11 ) { /* not gatewayed */
        /* Switch this to HTTP 1.1 */
	char * p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION);
        command = malloc(4 + strlen(arg) + 11 + 6 + strlen(host) + 2 + 20 + 2 + 1);
        if (command == NULL) outofmem(__FILE__, "HTLoadHTTP");
        strcpy(command, "GET ");
	    strcat(command, arg);
        strcat(command, " HTTP/1.1\r\n");
        strcat(command, "Host: ");
        strcat(command, host);
        strcat(command, "\r\n");
        strcat(command, "Connection: close\r\n");
    } else {
	char * p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION);
        command = malloc(4 + strlen(p1)+ 2 + 1);
        if (command == NULL) outofmem(__FILE__, "HTLoadHTTP");
        strcpy(command, "GET ");
	strcat(command, p1);
	free(p1);
    }
    strcat(command, "\r\n");		/* Include CR for telnet compat. */
	    

    if (TRACE) fprintf(stderr, "HTTP writing command `%s' to socket %d\n", command, s);
    
#ifdef NOT_ASCII
    {
    	char * p;
	for(p = command; *p; p++) {
	    *p = TOASCII(*p);
	}
    }
#endif

    status = NETWRITE(s, command, (int)strlen(command));
    free(command);
    if (status<0) {
	if (TRACE) fprintf(stderr, "HTTPAccess: Unable to send command.\n");
	    return HTInetStatus("send");
    }

    /* Skip the HTTP 1.1 headers */
    if ( HTTP11 ) {
        char buffer[2];
        int endhdr = 0;
        while ( 1 ) {
            int rc = read(s, buffer, 1) ;
            if ( TRACE ) fprintf(stderr,"%c",buffer[0]);
            if ( rc < 1 ) {
	        if (TRACE) fprintf(stderr, "HTTPAccess: EOF reading headers.\n");
	        return HTInetStatus("send");
            }
            if ( buffer[0] == '\r' && endhdr == 0 ) endhdr = 1;
            else if ( buffer[0] == '\n' && endhdr == 1 ) endhdr = 2;
            else if ( buffer[0] == '\r' && endhdr == 2 ) endhdr = 3;
            else if ( buffer[0] == '\n' && endhdr == 3 ) break;
            else endhdr = 0;
        }
    }
/*	Now load the data
*/
    
    {
      char *url = HTParse(arg, "",
                          PARSE_ACCESS | PARSE_HOST | PARSE_PATH |
                          PARSE_PUNCTUATION);
      int compressed;
      int fmt = 
        diag ? WWW_PLAINTEXT : HTFileFormat (url, WWW_HTML, &compressed);

      HTParseFormat(fmt, (HTParentAnchor *) anAnchor, s, compressed);

      free (url);
    }
      
    if (TRACE) fprintf(stderr, "HTTP: close socket %d.\n", s);
    status = NETCLOSE(s);

    return HT_LOADED;			/* Good return */
}
Example #10
0
void ClientThread(void *dummy)
{

  THREAD FILE *logfile;

  THREAD stats_t  timestat;

  THREAD rqst_timer_t timerarray[MAXNUMOFFILES];
  THREAD SOCKET mastersock = BADSOCKET_VALUE; /* connection to webmaster */


  THREAD page_stats_t *page_stats;    /* actually a dynamic array */

    int   loopcnt = 0;
    int   filecnt;
    int   loop;
    int   ran_number;
    int   page_index;
    int   page_number;
    int   file_count = 0;
    char  file_name[50];
    struct timeval  runningtime;
    time_t    junk;
    int   i;
    int   returnval;

    /*
     * INITIALIZE DATA
     */

    page_stats =
      (page_stats_t *)mymalloc((number_of_pages)*sizeof(page_stats_t));

    for (i=0; i < number_of_pages; i++) {
        page_stats_init(&(page_stats[i]));
    }

    if (debug)
      {
  /*
   *  OPEN A DEBUG FILE
   */
  fflush(stderr);
  sprintf(file_name, "%s.%d", DEBUG_FILE, (int)getpid());
  debugfile = fopen(file_name, "w+");
  if (debugfile == 0)
      errexit("Can't open debug file\n");
  D_PRINTF( "Running in debug mode, %d\n",amclient );
    }

    if (record_all_transactions)
    {
  /*
   *  OPEN A LOG FILE.
   */
  sprintf(file_name, "%s%d", LOG_FILE, (int)getpid());
  returnerr("Log file is %s\n", file_name);
  logfile = fopen(file_name, "w+");
    }

    /* Initialize random number generator */
    junk = getpid ();
    rand_r(&junk);
    D_PRINTF( "Random seed: %d\n", junk );

    for (i=0; i < MAXNUMOFFILES; i++)
    {
  rqtimer_init(&(timerarray[i]));
    }
    stats_init(&timestat);

    D_PRINTF( "Number of files %d\n", numfiles );

    timestat.total_num_of_files = numfiles;

    if (amclient)
    {
        /*
         * WE ARE A CLIENT PROCESS. (i.e. WE ARE NOT RUN BY A USER, BUT BY
         * THE MASTER WWWSTONE PROCESS. WE NEED TO CONNECT TO THE
         * MASTER WHO WILL SYNCHRONIZE ALL THE CLIENTS.
         */
  D_PRINTF( "Trying to connect with %s\n",connectstr );

  mastersock = connecttomaster(connectstr);

  D_PRINTF( "connecttomaster returns %d, %s\n",
          mastersock, neterrstr() );

  if(BADSOCKET(mastersock))
        {
            /*
             * ERROR CONNECTING TO THE MASTER. ABORT.
             */
            errexit("Error connecting to the master: %s\n", neterrstr());
        }
    } /* END IF CLIENT */

#ifdef WIN32
    /* Tell parent we're ready */
    InterlockedIncrement(&CounterSemaphore);

    /* Wait for main() thread to release us */
    WaitForSingleObject(hSemaphore, INFINITE);
    ReleaseSemaphore(hSemaphore, 1, 0);
#endif /* WIN32 */
    if (testtime != 0)
    {
       /*
        * IF RUNNING A TIMED TEST, WE WILL LOOP
  * UNTIL THE ALARM GOES OFF.
        * WE'LL ALSO NEED TO SET THE SIGNAL HANDLER
        */
#ifndef WIN32
      /*signal(SIGALRM, alarmhandler);*/
       /*
        * SEND SIGALRM IN testtime SECONDS
        */
      /*alarm(testtime);*/
#endif /* WIN32 */
    }

    /*
     * AND THEY'RE OFF...
     */

    if (testtime)
  numloops = INFINITY;
    GETTIMEOFDAY(&(timestat.starttime), &(timestat.starttimezone));

    /* LOOP UNTIL WE HIT numloops, OR WE RUN OUT OF TIME */
    for(loopcnt = 0;  (loopcnt < numloops) && !timeexpired;  loopcnt++)
    {
  /*
   * THIS IS WHERE LOAD TESTING IS DONE.
   * GET A RANDOM NUMBER, THEN INDEX INTO THE
   * PAGE, AND THEN REQUEST THAT SET OF FILES.
   */
  if (uil_filelist_f) /* HAVE FILELIST */
  {
      D_PRINTF( "Have filelist\n" );
      /* if (testtime != 0) /* RUNNING IN TIMED MODE */
            if (1)
      {
    D_PRINTF( "Running in timed mode\n" );
    /* random number between 0 and totalweight-1 */
                junk = getpid ();
    ran_number = (rand_r(&junk) % total_weight);
    D_PRINTF( "random %ld\n", ran_number );

    /* loop through pages, find correct one
     * while ran_number is positive, decrement it
     * by the load_num of the current page
     * example: ran_number is 5, pages have weights of 10 and 10
     *          first iteration page_index = 0, ran_number = -5
     *          iteration halted, page_index = 0
     */
    page_index = -1;
    while (ran_number >= 0)
      {
        page_index++;
        D_PRINTF( "Current page index %d: %ld - %d\n",
          page_index, ran_number,
          load_file_list[page_index].load_num
          );
        ran_number -= load_file_list[page_index].load_num;
      }

    if (page_index >= number_of_pages) { page_index--; }

    D_PRINTF( "Final page index %d\n", page_index );
    filecnt = makeload(load_file_list[page_index].num_of_files,
               page_index, timerarray, &timestat, mastersock, page_stats);
                testtime = 1;
      }
      else /* NOT RUNNING IN TIMED MODE */
      {
    for (page_number = 0;
         page_number < number_of_pages;
         page_number++)
    {
        filecnt = makeload(load_file_list[page_number].num_of_files,
      page_number, timerarray, &timestat, mastersock, page_stats);

    } /* END for page_number */
      } /* END if/else TIMED MODE */
  }
  else /* NO FILELIST */
  {
      D_PRINTF( "No filelist\n" );
     /*
      * LOOP THROUGH UNTIL numfiles TIMES OR UNTIL TIMER EXPIRES
      * AND ALARM SETS filecnt TO INFINITY.
      */

      /* does this still work?? */
      /* filecnt = makeload(numfiles, -1, timerarray); */
  } /* END if HAVE FILELIST */

  if (filecnt > 0)
      file_count += filecnt;

    } /* END while loopcnt */

    GETTIMEOFDAY(&(timestat.endtime), &(timestat.endtimezone));
    D_PRINTF( "Test run complete\n" );
    signal(SIGALRM, 0);

    if (testtime == 0)
    {
  numfiles = loopcnt;

  if (uil_filelist_f)
  {
      numfiles = file_count;
  }
    }

    /* This option ( "-R" ) looks broken (e.g. l > 50) -- JEF 2/15/96 */
    if (record_all_transactions)
    {
  /*
   * DUMP THE LOG FILE INFORMATION.
   */
  for (loop=0; loop < (loopcnt * file_count); loop++)
  {
      fprintf(logfile, " entertime \t%d.%d\n"
           " beforeconnect \t%d.%d\n"
           " afterconnect \t%d.%d\n"
           " beforeheader \t%d.%d\n"
           " afterheader \t%d.%d\n"
           " afterbody \t%d.%d\n"
           " exittime \t%d.%d\n"
           " total bytes \t%d\n"
           " body bytes\t%d\n",
    timerarray[loop].entertime.tv_sec,
    timerarray[loop].entertime.tv_usec,
    timerarray[loop].beforeconnect.tv_sec,
    timerarray[loop].beforeconnect.tv_usec,
    timerarray[loop].afterconnect.tv_sec,
    timerarray[loop].afterconnect.tv_usec,
    timerarray[loop].beforeheader.tv_sec,
    timerarray[loop].beforeheader.tv_usec,
    timerarray[loop].afterheader.tv_sec,
    timerarray[loop].afterheader.tv_usec,
    timerarray[loop].afterbody.tv_sec,
    timerarray[loop].afterbody.tv_usec,
    timerarray[loop].exittime.tv_sec,
    timerarray[loop].exittime.tv_usec,
    timerarray[loop].totalbytes,
    timerarray[loop].bodybytes);
  } /* end for loop */
    } /* end if recording all transactions */

    D_PRINTF( "total errors: %d\n",timestat.rs.totalerrs );
    /* gethostname(timestat.hostname,MAXHOSTNAMELEN); */
    /* D_PRINTF( "Test for host: %s\n",timestat.hostname ); */
    D_PRINTF( "Server is: %s running at port number: %d\n",
  webserver,portnum );

    /* sprintf(timestat.hostname,"%s:%d",timestat.hostname,getpid()); */
    if (amclient) /* CLIENT TO A WEBMASTER */
    {
   char *stats_as_text;

        /*
         * SEND THE TIMING DATA TO THE MASTER
         */
  stats_as_text = stats_to_text(&timestat);
  D_PRINTF( "stats_to_text returned %s\n", stats_as_text );

  returnval = senddata(mastersock, stats_as_text,
    SIZEOF_STATSTEXTBASE + number_of_pages*SIZEOF_DOUBLETEXT);
  D_PRINTF( "Wrote time stats to master %d\n", returnval );

  if (returnval < 1)
    {
      D_PRINTF( "Error while writing time stats: %s\n",
        neterrstr() );
      errexit("Error while writing time stats: %s\n",
        neterrstr());
    }

  if (uil_filelist_f)
    /* write pagestats */
    {
      char *page_stats_as_text;
      for (i = 0; i < number_of_pages; i++)
        {
    D_PRINTF( "On page_stats[%d]\n", i );
    page_stats_as_text = page_stats_to_text(&page_stats[i]);
    returnval = strlen(page_stats_as_text);
    D_PRINTF( "page_stats_to_text[%d] returned %d\n",
      i, returnval );
    returnval = senddata(mastersock, page_stats_as_text,
             SIZEOF_PAGESTATSTEXT);
    if (returnval < 1)
      {
        D_PRINTF( "Error while writing page_stats[%d]: %s\n",
          i, neterrstr() );
        errexit("Error while writing page_stats[%d]: %s\n",
          i, neterrstr());
      } /* end if */
    D_PRINTF( "Wrote %d bytes of page_stats[%d] to master\n",
      returnval, i );
        } /* end for */
    } /* end if filelist */

  D_PRINTF( "About to close socket\n" );
        if (NETCLOSE(mastersock))
      D_PRINTF( "Close socket error: %s\n", neterrstr() );
    }
    else /* NOT A CLIENT TO A WEBMASTER */
    {
  if (testtime)
    {
      printf("Test ran for: %d minutes\n",(testtime/60));
  }
  else
  {
      printf("Test ran for: %d iterations.\n",numloops);
  }
  compdifftime(&(timestat.endtime), &(timestat.starttime),
    &(runningtime));
  printf("Total time of test (sec) %d.%d\n", runningtime.tv_sec,
    runningtime.tv_usec);
  printf("Files retrieved per iteration: %d\n",numfiles);  /* 'per iteration' */
  printf("----------------------------------\n");
  printf("Totals:\n\n");
  rqstat_print(&(timestat.rs));

  if (timestat.rs.totalconnects == 0)
      goto end;
  printf("Thruput = %5.2lf Kbytes/sec\n",
         thruputpersec(timestat.rs.totalbytes, &runningtime) / 1000);

  if (uil_filelist_f && numloops && verbose)
  {
      for (loop = 0; loop < number_of_pages; loop++)
      {
    if (timestat.page_numbers[loop] != 0)
    {
        printf ("===============================================================================\n");
        printf ("Page # %d\n\n", loop);
        printf ("Total number of times page was hit %d\n",
          page_stats[loop].totalpages);
        rqstat_print(&(page_stats[loop].rs));
        printf ("Page size %d \n", page_stats[loop].page_size);
        printf ("===============================================================================\n\n");
    } /* END if timestat */
      } /* END for loop */
  } /* END if filelist */
    } /* END if client */

end:
    if(record_all_transactions)
      fclose(logfile);
    if(debug)
    {
  D_PRINTF( "Client exiting.\n" );
  fclose(debugfile);
    }

#ifdef WIN32
    /* tell parent we're done */
    InterlockedIncrement(&CounterSemaphore);
#endif /* WIN32 */

} /* END ClientThread() */
Example #11
0
/* connect to a socket given the hostname and protocol */
SOCKET
connectsock(char *host, NETPORT portnum, char *protocol)
 {
  struct sockaddr_in sin;   /* an Internet endpoint address */
  SOCKET  s;              /* socket descriptor */
  int     type;           /* socket type */
  short   proto;
  int     returnval;  /* temporary return value */

  D_PRINTF( "Beginning connectsock; host=%s port=%d proto=%s\n", host,
  portnum, protocol );

  sin.sin_family = AF_INET;
  memset((char *)&sin, 0, sizeof(sin));
  D_PRINTF( "Zeroed address structure\n" );

  sin.sin_port = htons(portnum);
  D_PRINTF( "Set port number %d\n", portnum );

  /* get the contact information */
  if (strcmp(host, webserver) == 0) {
      sin.sin_addr.S_ADDR = webserv_addr;
      sin.sin_family = PF_INET;
      proto = webserv_ppe.p_proto;
      type = webserv_type;
  } else if (strcmp(host, webmaster) == 0) {
      sin.sin_addr.S_ADDR = webmast_addr;
      sin.sin_family = PF_INET;
      proto = webmast_ppe.p_proto;
      type = webmast_type;
  } else {
      struct hostent  host_phe;
      struct protoent host_ppe;
      unsigned long host_addr;
      short     host_type;       /* socket type */

      if (resolve_addrs(host, "tcp", &host_phe, &host_ppe, &host_addr, &host_type))
    return returnerr("Can't resolve hostname %s in get()\n", host);
      sin.sin_addr.S_ADDR = host_addr;
      sin.sin_family = PF_INET;
      proto = host_ppe.p_proto;
      type = host_type;
  }

  /* Allocate a socket */
  s = socket(PF_INET, type, proto);
  D_PRINTF( "Socket %d returned %d, %s\n",
  type, s, neterrstr() );

  if (BADSOCKET(s))
  {
    D_PRINTF( "Can't create socket: %s\n",neterrstr() );
    return BADSOCKET_VALUE;
  }

  /* Connect the socket */
  D_PRINTF( "Trying to connect %d with size %d, %s\n",
  s, sizeof(sin), neterrstr() );
  D_PRINTF( "Address is family %d, port %d, addr %s\n",
  sin.sin_family, ntohs(sin.sin_port),
  inet_ntoa(sin.sin_addr) );

  returnval = connect(s, (struct sockaddr *)&sin, sizeof(sin));
  D_PRINTF( "Connect returned %d, %s\n",
  returnval, neterrstr() );
  if (returnval < 0)
    {
      D_PRINTF( "Can't connect: %s\n", neterrstr() );
      NETCLOSE(s);
      return BADSOCKET_VALUE;
    }

  /* all done, returning socket descriptor */
  D_PRINTF( "Returning %d from connectsock call\n", s );
  return(s);

} /* END connectsock() */
Example #12
0
PUBLIC int HTLoadHTTP ARGS4 (
	char *, 		arg,
	HTParentAnchor *,	anAnchor,
	HTFormat,		format_out,
	HTStream*,		sink)
{
  int s;				/* Socket number for returned data */
  char *command;			/* The whole command */
  char *eol;			/* End of line if found */
  char *start_of_data;		/* Start of body of reply */
  int status;				/* tcp return */
  int bytes_already_read;
  char crlf[3];			/* A CR LF equivalent string */
  HTStream *target;		/* Unconverted data */
  HTFormat format_in;			/* Format arriving in the message */

  char *line_buffer;
  char *line_kept_clean;
  BOOL extensions;		/* Assume good HTTP server */
  int compressed;
  char line[2048];	/* bumped up to cover Kerb huge headers */

  int length, doing_redirect, rv;
  int already_retrying = 0;
  int return_nothing;

  int i;
  int keepingalive = 0;
  char *p;

/*SWP*/
  int statusError=0;

  if (!arg)
    {
      status = -3;
      HTProgress ("Bad request.");
      goto done;
    }
  if (!*arg)
    {
      status = -2;
      HTProgress ("Bad request.");
      goto done;
    }

  sprintf(crlf, "%c%c", CR, LF);

  /* At this point, we're talking HTTP/1.0. */
  extensions = YES;

 try_again:
  /* All initializations are moved down here from up above,
     so we can start over here... */
  eol = 0;
  bytes_already_read = 0;
  length = 0;
  doing_redirect = 0;
  compressed = 0;
  target = NULL;
  line_buffer = NULL;
  line_kept_clean = NULL;
  return_nothing = 0;

	/* okay... addr looks like http://hagbard.ncsa.uiuc.edu/blah/etc.html
	lets crop it at the 3rd '/' */
	for(p = arg,i=0;*p && i!=3;p++)
		if(*p=='/') i++;

	if(i==3)
		i = p-arg; /* i = length not counting last '/' */
	else
		i = 0;

	if((lsocket != -1) && i && addr && !strncmp(addr,arg,i)){
		/* keepalive is active and addresses match -- try the old socket */
		s = lsocket;
		keepingalive = 1; /* flag in case of network error due to server timeout*/
		lsocket = -1; /* prevent looping on failure */
#ifndef DISABLE_TRACE
		if (www2Trace)
			fprintf (stderr,
				 "HTTP: Keep-Alive reusing '%s'\n",addr);
#endif
/*
		if (addr && *addr) {
			sprintf(tmpbuf,"Reusing socket from %s.",addr);
			HTProgress(tmpbuf);
		}
*/
	} else {
		if(addr) free(addr);
		/* save the address for next time around */
		addr = malloc(i+1);
		strncpy(addr,arg,i);
		*(addr+i)=0;

		keepingalive = 0; /* just normal opening of the socket */
		if(lsocket != -1) NETCLOSE(lsocket); /* no socket leaks here */
		lsocket = -1; /*dont assign until we know the server says okay */

#ifndef DISABLE_TRACE
		if (www2Trace)
			fprintf (stderr,
				 "HTTP: Keep-Alive saving '%s'\n",addr);
#endif
/*
		if (addr && *addr) {
			sprintf(tmpbuf,"Saving %s for possible socket reuse.",addr);
			HTProgress(tmpbuf);
		}
*/
	}

  if (!keepingalive) {
      status = HTDoConnect (arg, "HTTP", TCP_PORT, &s);
      if (status == HT_INTERRUPTED){
	  /* Interrupt cleanly. */
#ifndef DISABLE_TRACE
	  if (www2Trace)
	      fprintf (stderr,
		       "HTTP: Interrupted on connect; recovering cleanly.\n");
#endif
	  HTProgress ("Connection interrupted.");
	  /* status already == HT_INTERRUPTED */
	  goto done;
      }
      if (status < 0) {
#ifndef DISABLE_TRACE
	  if (www2Trace)
	      fprintf(stderr,
		      "HTTP: Unable to connect to remote host for `%s' (errno = %d).\n", arg, errno);
#endif
	  HTProgress ("Unable to connect to remote host.");
	  status = HT_NO_DATA;
	  goto done;
      }
  }
  /*	Ask that node for the document,
   **	omitting the host name & anchor
   */
  {
    char * p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION);
    command = malloc(5 + strlen(p1)+ 2 + 31);

    if (do_post && !do_put)
      strcpy(command, "POST ");
    else if (do_post && do_put)
      strcpy(command, "PUT ");
    else if (do_head)
      strcpy(command, "HEAD ");
    else if (do_meta)
      strcpy(command, "META ");
    else
      strcpy(command, "GET ");

    /*
     * For a gateway, the beginning '/' on the request must
     * be stripped before appending to the gateway address.
     */
    if ((using_gateway)||(using_proxy)) {
        strcat(command, p1+1);
    }
    else
        strcat(command, p1);
    free(p1);
  }
  if (extensions)
    {
      strcat(command, " ");
      strcat(command, HTTP_VERSION);
    }

  strcat(command, crlf);	/* CR LF, as in rfc 977 */

  if (extensions)
    {
#ifdef SAM_NOT_YET
		/* SAM This produces an absolutely huge Accept: line.  While
		   there is probably a better way to turn this off, just
		   compiling it out works for now.
		*/
      int n, i;

      if (!HTPresentations) HTFormatInit();
      n = HTList_count(HTPresentations);

      begin_ptr=command+strlen(command);
      env_length=0;

      sprintf(line, "Accept:");
      env_length+=strlen(line);
      StrAllocCat(command, line);

	/* KCMS Accept Header - swp */
	if (KCMS_Return_Format==JPEG) {
		sprintf(line," image/x-pcd-jpeg,");
		StrAllocCat(command, line);
		env_length+=strlen(line);
	}
	else if (KCMS_Return_Format==JYCC) {
		sprintf(line," image/x-pcd-jycc,");
		StrAllocCat(command, line);
		env_length+=strlen(line);
	}
	else if (KCMS_Return_Format==GIF) {
		sprintf(line," image/x-pcd-gif,");
		StrAllocCat(command, line);
		env_length+=strlen(line);
	}

      for(i=0; i<n; i++)
        {
          HTPresentation * pres = HTList_objectAt(HTPresentations, i);
          if (pres->rep_out == WWW_PRESENT)
            {
		sprintf(line, " %s,",HTAtom_name(pres->rep));
		env_length+=strlen(line);
		StrAllocCat(command, line);
		if (env_length>200) {
			if ((tmp_ptr=strrchr(command,','))!=NULL) {
				*tmp_ptr='\0';
			}
			sprintf(line, "%c%c",CR,LF);
			StrAllocCat(command, line);

			begin_ptr=command+strlen(command);
			sprintf(line, "Accept:");
			env_length=strlen(line);
			StrAllocCat(command, line);
		}
            }
        }

      /* This gets rid of the last comma. */
      if ((tmp_ptr=strrchr(command,','))!=NULL) {
	*tmp_ptr='\0';
	sprintf(line, "%c%c",CR,LF);
	StrAllocCat(command, line);
      }
      else { /* No accept stuff...get rid of "Accept:" */
	begin_ptr='\0';
      }
#endif

      /* if reloading, send no-cache pragma to proxy servers. --swp */
      /* original patch from Ari L. <*****@*****.**> */
      if (reloading) {
	sprintf(line, "Pragma: no-cache%c%c", CR, LF);
	StrAllocCat(command, line);
      }

      /*This is just used for "not" sending this header on a proxy request*/
      if (useKeepAlive) {
	sprintf(line, "Connection: keep-alive%c%c", CR, LF);
	StrAllocCat(command, line);
      }

      if (sendAgent) {
	sprintf(line, "User-Agent: %s%c%c",agent[selectedAgent],CR,LF);
/*
	sprintf(line, "User-Agent:  %s/%s  libwww/%s%c%c",
		HTAppName ? HTAppName : "unknown",
		HTAppVersion ? HTAppVersion : "0.0",
		HTLibraryVersion, CR, LF);
*/
	StrAllocCat(command, line);
      }

      if (sendReferer) {
	/* HTTP Referer field, specifies back-link URL   - amb */
	if (HTReferer) {
		sprintf(line, "Referer: %s%c%c", HTReferer, CR, LF);
		StrAllocCat(command, line);
		HTReferer = NULL;
	}
      }

      {
	char *tmp,*startPtr,*endPtr;

	/* addr is always in URL form */

	if (addr && !using_proxy && !using_gateway) {
		tmp=strdup(addr);
		startPtr=strchr(tmp,'/');
		if (startPtr) {
			startPtr+=2; /*now at begining of hostname*/
			if (*startPtr) {
				endPtr=strchr(startPtr,':');
				if (!endPtr) {
					endPtr=strchr(startPtr,'/');
					if (endPtr && *endPtr) {
						*endPtr='\0';
					}
				}
				else {
					*endPtr='\0';
				}

				sprintf(line, "Host: %s%c%c", startPtr, CR, LF);
				StrAllocCat(command, line);

				free(tmp);
				tmp=startPtr=endPtr=NULL;
			}
		}
	}
	else if (using_proxy || using_gateway) {
		sprintf(line, "Host: %s%c%c", proxy_host_fix, CR, LF);
		StrAllocCat(command, line);
	}
      }

      /* SWP -- 7/10/95 */
      /* HTTP Extension headers */
      /* Domain Restriction */
      sprintf(line,"Extension: Notify-Domain-Restriction%c%c",CR,LF);
      StrAllocCat(command,line);

      /* BJS -- 12/05/95 -- allow arbitrary headers sent from browser */
      if(extra_headers){
		int h;
		for(h=0;extra_headers[h];h++){
			sprintf(line,"%s%c%c",extra_headers[h],CR,LF);
			StrAllocCat(command,line);
		}
      }

      {
        char *docname;
        char *hostname;
        char *colon;
        int portnumber;
        char *auth;

        docname = HTParse(arg, "", PARSE_PATH);
        hostname = HTParse(arg, "", PARSE_HOST);
        if (hostname &&
            NULL != (colon = strchr(hostname, ':')))
          {
            *(colon++) = '\0';	/* Chop off port number */
            portnumber = atoi(colon);
          }
        else portnumber = 80;

        if (NULL!=(auth=HTAA_composeAuth(hostname, portnumber, docname)))
          {
            sprintf(line, "%s%c%c", auth, CR, LF);
            StrAllocCat(command, line);
          }
#ifndef DISABLE_TRACE
        if (www2Trace)
          {
            if (auth)
              fprintf(stderr, "HTTP: Sending authorization: %s\n", auth);
            else
              fprintf(stderr, "HTTP: Not sending authorization (yet)\n");
          }
#endif
        FREE(hostname);
        FREE(docname);
      }
    }

  if (do_post && !do_put)
    {
#ifndef DISABLE_TRACE
      if (www2Trace)
        fprintf (stderr, "HTTP: Doing post, content-type '%s'\n",
                 post_content_type);
#endif
      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");
    }
  else if (do_post && do_put)
    {
      sprintf (line, "Content-length: %d%c%c",
	       put_file_size, CR, LF);
      StrAllocCat(command, line);
      StrAllocCat(command, crlf);	/* Blank line means "end" */
    }
  else {
      StrAllocCat(command, crlf);	/* Blank line means "end" */
  }

#ifndef DISABLE_TRACE
  if (www2Trace)
    fprintf (stderr, "Writing:\n%s----------------------------------\n",
             command);
#endif

/*
  HTProgress ("Sending HTTP request.");
*/

  status = NETWRITE(s, command, (int)strlen(command));
  if (do_post && do_put) {
      char buf[BUFSIZ];
      int upcnt=0,n;

      while (status>0) {
	n=fread(buf,1,BUFSIZ-1,put_fp);

	upcnt+= status = NETWRITE(s, buf, n);
#ifndef DISABLE_TRACE
	if (www2Trace) {
		fprintf(stderr,"[%d](%d) %s",status,n,buf);
	}
#endif
	if (feof(put_fp)) {
		break;
	}
      }

      if (status<0 || !feof(put_fp) || upcnt!=put_file_size) {
	char tmpbuf[BUFSIZ];

	sprintf(tmpbuf,"Status: %d  --  EOF: %d  --  UpCnt/FileSize: %d/%d\n\nThe server you connected to either does not support\nthe PUT method, or an error occurred.\n\nYour upload was corrupted! Please try again!",status,(feof(put_fp)?1:0),upcnt,put_file_size);
	application_error(tmpbuf,"Upload Error!");
      }
  }

  /* Twirl on each request to make things look nicer -- SWP */
  HTCheckActiveIcon(1);

#ifndef DISABLE_TRACE
  if (httpTrace) {
	fprintf(stderr,"%s",command);
  }
#endif

  free (command);
  if (status <= 0)
    {
      if (status == 0)
        {
#ifndef DISABLE_TRACE
          if (www2Trace)
            fprintf (stderr, "HTTP: Got status 0 in initial write\n");
#endif
          /* Do nothing. */
        }
      else if
        ((errno == ENOTCONN || errno == ECONNRESET || errno == EPIPE) &&
         !already_retrying &&
         /* Don't retry if we're posting. */ !do_post)
          {
            /* Arrrrgh, HTTP 0/1 compability problem, maybe. */
#ifndef DISABLE_TRACE
            if (www2Trace)
              fprintf
                (stderr,
                 "HTTP: BONZO ON WRITE Trying again with HTTP0 request.\n");
#endif
/*
            HTProgress ("Retrying as HTTP0 request.");
*/
            NETCLOSE(s);
// SAM            extensions = NO;
            already_retrying = 1;
            goto try_again;
          }
      else
        {
		if(keepingalive){
#ifndef DISABLE_TRACE
			if (www2Trace)
				fprintf (stderr, "HTTP: Timeout on Keep-Alive. Retrying.\n");
#endif
			HTProgress("Server Timeout: Reconnecting");
			goto try_again;
		}
#ifndef DISABLE_TRACE
          if (www2Trace)
            fprintf (stderr, "HTTP: Hit unexpected network WRITE error; aborting connection.\n");
#endif
          NETCLOSE (s);
          status = -1;
          HTProgress ("Unexpected network write error; connection aborted.");
          goto done;
        }
    }

#ifndef DISABLE_TRACE
  if (www2Trace)
    fprintf (stderr, "HTTP: WRITE delivered OK\n");
#endif
  HTProgress ("Done sending HTTP request; waiting for response.");

  /*	Read the first line of the response
   **	-----------------------------------
   */

  {
      /* Get numeric status etc */
      BOOL end_of_file = NO;
      int buffer_length = INIT_LINE_SIZE;

      line_buffer = (char *) malloc(buffer_length * sizeof(char));

      do {
	  /* Loop to read in the first line */
	  /* Extend line buffer if necessary for those crazy WAIS URLs ;-) */
	  if (buffer_length - length < LINE_EXTEND_THRESH) {
	      buffer_length = buffer_length + buffer_length;
	      line_buffer =
		  (char *) realloc(line_buffer, buffer_length * sizeof(char));
          }
#ifndef DISABLE_TRACE
	  if (www2Trace)
	      fprintf (stderr, "HTTP: Trying to read %d\n",
		       buffer_length - length - 1);
#endif
	  status = NETREAD(s, line_buffer + length,
			   buffer_length - length - 1);
#ifndef DISABLE_TRACE
	  if (www2Trace)
	      fprintf (stderr, "HTTP: Read %d\n", status);
#endif
	  if (status <= 0) {
	      /* Retry if we get nothing back too;
		 bomb out if we get nothing twice. */
	      if (status == HT_INTERRUPTED) {
#ifndef DISABLE_TRACE
		  if (www2Trace)
		      fprintf (stderr, "HTTP: Interrupted initial read.\n");
#endif
		  HTProgress ("Connection interrupted.");
		  status = HT_INTERRUPTED;
		  NETCLOSE (s);
		  goto clean_up;
              } else
		  if
		  (status < 0 &&
		   (errno == ENOTCONN || errno == ECONNRESET || errno == EPIPE)
		   && !already_retrying && !do_post)
		      {
			  /* Arrrrgh, HTTP 0/1 compability problem, maybe. */
#ifndef DISABLE_TRACE
			  if (www2Trace)
			      fprintf (stderr, "HTTP: BONZO Trying again with HTTP0 request.\n");
#endif
			  NETCLOSE(s);
			  if (line_buffer)
			      free(line_buffer);
			  if (line_kept_clean)
			      free(line_kept_clean);

			  extensions = NO;
			  already_retrying = 1;
			  HTProgress ("Retrying as HTTP0 request.");
			  goto try_again;
		      } else {
			      if(keepingalive){
#ifndef DISABLE_TRACE
					if (www2Trace)
						fprintf (stderr, "HTTP: Timeout on Keep-Alive. Retrying.\n");
#endif
					HTProgress("Server Timeout: Reconnecting");
					goto try_again;
			      }
#ifndef DISABLE_TRACE
			  if (www2Trace)
			      fprintf (stderr, "HTTP: Hit unexpected network read error; aborting connection; status %d.\n", status);
#endif
			  HTProgress
			      ("Unexpected network read error; connection aborted.");

			  NETCLOSE (s);
			  status = -1;
			  goto clean_up;
		      }
          }

	  bytes_already_read += status;
	  {
	      char line[256];
	      sprintf (line, "Read %d bytes of data.", bytes_already_read);
	      HTProgress (line);
	  }

	  if (status == 0) {
	      end_of_file = YES;
	      break;
          }
	  line_buffer[length+status] = 0;

	  if (line_buffer) {
	      if (line_kept_clean)
		  free (line_kept_clean);
	      line_kept_clean = (char *)malloc (buffer_length * sizeof (char));
/*
	      bcopy (line_buffer, line_kept_clean, buffer_length);
*/
	      memcpy (line_kept_clean, line_buffer, buffer_length);
          }

	  eol = strchr(line_buffer + length, LF);
	  /* Do we *really* want to do this? */
	  if (eol && eol != line_buffer && *(eol-1) == CR)
	      *(eol-1) = ' ';

	  length = length + status;

	  /* Do we really want to do *this*? */
	  if (eol)
	      *eol = 0;		/* Terminate the line */
      /* All we need is the first line of the response.  If it's a HTTP/1.0
	 response, then the first line will be absurdly short and therefore
	 we can safely gate the number of bytes read through this code
	 (as opposed to below) to ~1000. */
      /* Well, let's try 100. */
      } while (!eol && !end_of_file && bytes_already_read < 100);
  } /* Scope of loop variables */


  /*	We now have a terminated unfolded line. Parse it.
   **	-------------------------------------------------
   */
#ifndef DISABLE_TRACE
  if (www2Trace)
    fprintf(stderr, "HTTP: Rx: %s\n", line_buffer);
#endif

  {
    int fields;
    char server_version[VERSION_LENGTH+1];
    int server_status;

	/*SWP*/
	statusError=0;

    server_version[0] = 0;

    fields = sscanf(line_buffer, "%20s %d",
                    server_version,
                    &server_status);

#ifndef DISABLE_TRACE
    if (www2Trace)
      fprintf (stderr, "HTTP: Scanned %d fields from line_buffer\n", fields);
#endif
#ifndef DISABLE_TRACE
    if (www2Trace)
      fprintf (stderr, "HTTP: line_buffer '%s'\n", line_buffer);
#endif

    /* Rule out HTTP/1.0 reply as best we can. */
    if (fields < 2 || !server_version[0] || server_version[0] != 'H' ||
        server_version[1] != 'T' || server_version[2] != 'T' ||
        server_version[3] != 'P' || server_version[4] != '/' ||
        server_version[6] != '.')
      {
        /* HTTP0 reply */
        HTAtom * encoding;

#ifndef DISABLE_TRACE
        if (www2Trace)
          fprintf (stderr, "--- Talking HTTP0.\n");
#endif

        format_in = HTFileFormat(arg, &encoding, WWW_HTML, &compressed);
        start_of_data = line_kept_clean;
      }
    else
      {
        /* Decode full HTTP response */
        format_in = HTAtom_for("www/mime");
        /* We set start_of_data to "" when !eol here because there
           will be a put_block done below; we do *not* use the value
           of start_of_data (as a pointer) in the computation of
           length or anything else in this situation. */
        start_of_data = eol ? eol + 1 : "";
        length = eol ? length - (start_of_data - line_buffer) : 0;

#ifndef DISABLE_TRACE
        if (www2Trace)
          fprintf (stderr, "--- Talking HTTP1.\n");
#endif

        switch (server_status / 100)
          {
          case 3:		/* Various forms of redirection */
            /* We now support this in the parser, at least. */
            doing_redirect = 1;
            break;

          case 4:		/* "I think I goofed" */
            switch (server_status)
              {
              case 403:
		statusError=1;
                /* 403 is "forbidden"; display returned text. */
                break;

              case 401:
                /* length -= start_of_data - text_buffer; */
                if (HTAA_shouldRetryWithAuth(start_of_data, length, s))
                  {
                    (void)NETCLOSE(s);
			lsocket = -1;
                    if (line_buffer)
                      free(line_buffer);
                    if (line_kept_clean)
                      free(line_kept_clean);

#ifndef DISABLE_TRACE
                    if (www2Trace)
                      fprintf(stderr, "%s %d %s\n",
                              "HTTP: close socket", s,
                              "to retry with Access Authorization");
#endif

                    HTProgress ("Retrying with access authorization information.");
                    goto try_again;
                    break;
                  }
                else
                  {
		    statusError=1;
                    /* Fall through. */
                  }

              default:
		statusError=1;
                break;
              } /* case 4 switch */
            break;

          case 5:		/* I think you goofed */
	    statusError=1;
            break;

          case 2:		/* Good: Got MIME object */
            switch (server_status)
              {
              case 204:
                return_nothing = 1;
                format_in = HTAtom_for("text/html");
                break;
	      case 200:
		if (do_head) {
			if (!start_of_data || !*start_of_data) {
				headData=NULL;
			}
			else {
				char *ptr;

				headData=strdup(start_of_data);
				ptr=strchr(headData,'\n');
				*ptr='\0';
			}
		}
		break;
              default:
                break;
              }
            break;

          default:		/* bad number */
	    statusError=1;
            HTAlert("Unknown status reply from server!");
            break;
          } /* Switch on server_status/100 */

      }	/* Full HTTP reply */
  } /* scope of fields */

  /* Set up the stream stack to handle the body of the message */
  target = HTStreamStack(format_in,
                         format_out,
                         compressed,
                         sink, anAnchor);

  if (!target)
    {
      char buffer[1024];	/* @@@@@@@@ */
      sprintf(buffer, "Sorry, no known way of converting %s to %s.",
              HTAtom_name(format_in), HTAtom_name(format_out));
      HTProgress (buffer);
      status = -1;
      NETCLOSE (s);
	lsocket = -1;
      goto clean_up;
    }

  if (!return_nothing)
    {
#ifndef DISABLE_TRACE
      if (www2Trace)
        fprintf (stderr, "HTTP: Doing put_block, '%s'\n", start_of_data);
#endif
/* BJS: parse start_of_data...*/
	for(p=start_of_data;*p;p++){
/*		if(*p=='C' && !strncmp("Content-length: ",p,16)){
		i = 0;
		p+=16;
		while(*p && isdigit(*p)){
			i = i*10 + *p-'0';
			p++;
		}
		p--;
#ifndef DISABLE_TRACE
		if(www2Trace)
			fprintf(stderr, "HTTP: Content Length is %d\n",i);
#endif
	}
*/
		if(*p=='K' && !strncmp("Keep-Alive:",p,11)){
#ifndef DISABLE_TRACE
			if (www2Trace)
				fprintf (stderr, "HTTP: Server Agrees to Keep-Alive\n");
#endif
			lsocket = s;
			p+=10;
		}
	}

#ifndef DISABLE_TRACE
        if (www2Trace && lsocket == -1)
		fprintf (stderr, "HTTP: Server does not agree to Keep-Alive\n");
#endif
      /* Recycle the first chunk of data, in all cases. */
      (*target->isa->put_block)(target, start_of_data, length);

      /* Go pull the bulk of the data down. */
	/* if we dont use length, header length is wrong due to the
	    discarded first line - bjs*/
      rv = HTCopy(s, target, length /*bytes_already_read*/);
      if (rv == -1)
        {
          (*target->isa->handle_interrupt) (target);
          status = HT_INTERRUPTED;
	  NETCLOSE (s);
		lsocket = -1;
          goto clean_up;
        }
      if (rv == -2 && !already_retrying && !do_post)
        {
          /* Aw hell. */
#ifndef DISABLE_TRACE
          if (www2Trace)
            fprintf (stderr, "HTTP: Trying again with HTTP0 request.\n");
#endif
          /* May as well consider it an interrupt -- right? */
          (*target->isa->handle_interrupt) (target);
          NETCLOSE(s);
          if (line_buffer)
            free(line_buffer);
          if (line_kept_clean)
            free(line_kept_clean);

          extensions = NO;
          already_retrying = 1;
          HTProgress ("Retrying as HTTP0 request.");
          goto try_again;
        }
    }
  else
    {
      /* return_nothing is high. */
      (*target->isa->put_string) (target, "<mosaic-access-override>\n");
      HTProgress ("And silence filled the night.");
    }

  (*target->isa->end_document)(target);

  /* Close socket before doing free. */
	if(lsocket == -1){
		NETCLOSE(s);
#ifndef DISABLE_TRACE
		if(www2Trace)
			fprintf(stderr,"HTTP: Closing connection\n");
#endif
	} else {
		HTProgress("Leaving Server Connection Open");
#ifndef DISABLE_TRACE
		if(www2Trace)
			fprintf(stderr,"HTTP: Keeping connection alive\n");
#endif
	}
/*
  else {
      NETCLOSE(s);
#ifndef DISABLE_TRACE
      if(www2Trace)
	fprintf(stderr,"HTTP: Closing connection\n");
#endif
  }
*/

  (*target->isa->free)(target);

  if (doing_redirect)
    {
      /* OK, now we've got the redirection URL temporarily stored
         in external variable redirecting_url, exported from HTMIME.c,
         since there's no straightforward way to do this in the library
         currently.  Do the right thing. */
      status = HT_REDIRECTING;
    }
  else
    {
      status = HT_LOADED;
    }

  /*	Clean up
   */

 clean_up:
  if (line_buffer)
    free(line_buffer);
  if (line_kept_clean)
    free(line_kept_clean);

 done:
  /* Clear out on exit, just in case. */
  do_post = 0;

  if (statusError) {
	securityType=HTAA_NONE;
#ifndef DISABLE_TRACE
	if (www2Trace)
		fprintf(stderr,"Resetting security type to NONE.\n");
#endif
  }

  return status;
}
Example #13
0
PRIVATE int server_loop()
#endif
{
    int tcp_status;		/* <0 if error, in general */
    int timeout = -1;		/* No timeout required but code exists */
    for(;;) {

/*  If it's a master socket, then find a slave:
*/
    	if (role == master) {
#ifdef SELECT
	    fd_set		read_chans;
	    fd_set		write_chans;
	    fd_set		except_chans;
	    int			nfound;	    /* Number of ready channels */
	    struct timeval	max_wait;   /* timeout in form for select() */
    
	    FD_ZERO(&write_chans);	    /* Clear the write mask */
	    FD_ZERO(&except_chans);	    /* Clear the exception mask */

/*  If timeout is required, the timeout structure is set up. Otherwise
**  (timeout<0) a zero is passed instead of a pointer to the struct timeval.
*/
	    if (timeout>=0) {
		max_wait.tv_sec = timeout/100;
		max_wait.tv_usec = (timeout%100)*10000;
	    }
    
	    for (com_soc=(-1); com_soc<0;) {	/* Loop while connections keep coming */
    
		
/*  The read mask expresses interest in the master channel for incoming
**  connections) or any slave channel (for incoming messages).
*/

/*  Wait for incoming connection or message
*/
	        read_chans = open_sockets;	 /* Read on all active channels */
		if (TRACE) printf(
"Daemon: Waiting for connection or message. (Mask=%x hex, max=%x hex).\n", 
		 	*(int *)(&read_chans), num_sockets);
		nfound=select(num_sockets, &read_chans,
		    &write_chans, &except_chans,
		    timeout >= 0 ? &max_wait : 0);
	
		if (nfound<0) return HTInetStatus("select()");
		if (nfound==0) return 0;	/* Timeout */

/*	We give priority to existing connected customers. When there are
**	no outstanding commands from them, we look for new customers.
*/
/*  	If a message has arrived on one of the channels, take that channel:
*/
		{
		    int i;
		    for(i=0; i<num_sockets; i++)
			if (i != master_soc)
			    if (FD_ISSET(i, &read_chans)) {
			    if (TRACE) printf(
			    	"Message waiting on socket %d\n", i);
			    com_soc = i;		/* Got one! */
			    break;
			}
		    if (com_soc>=0) break; /* Found input socket */
		    
		} /* block */
		
/*  If an incoming connection has arrived, accept the new socket:
*/
		if (FD_ISSET(master_soc, &read_chans)) {
    
			CTRACE(tfp, "Daemon: New incoming connection:\n");
			tcp_status = accept(master_soc,
					(struct sockaddr *)&soc_address,
					&soc_addrlen);
			if (tcp_status<0)
			    return HTInetStatus("accept");
			CTRACE(tfp, "Daemon: Accepted new socket %d\n",
			    tcp_status);
			FD_SET(tcp_status, &open_sockets);
			if ((tcp_status+1) > num_sockets)
				num_sockets=tcp_status+1;
    
		} /* end if new connection */
    
    
	    } /* loop on event */
	
#else	/* SELECT not supported */
    
	    if (com_soc<0) { /* No slaves: must accept */
		    CTRACE(tfp, 
		    "Daemon: Waiting for incoming connection...\n");
		    tcp_status = accept(master_soc,
				    &rsoc->mdp.soc_tcp.soc_address,
				    &rsoc->mdp.soc_tcp.soc_addrlen);
		    if (tcp_status<0)
			return HTInetStatus("accept");
		    com_soc = tcp_status;	/* socket number */
		    CTRACE(tfp, "Daemon: Accepted socket %d\n", tcp_status);
	    } /* end if no slaves */
    
#endif

	}  /* end if master */


/* com_soc is now valid for read */

	{
	    struct sockaddr_in addr;
	    int namelen = sizeof(addr);
	    getpeername(com_soc, (struct sockaddr*)&addr, &namelen);
	    strncpy(HTClientHost,
	    	 inet_ntoa(addr.sin_addr), sizeof(HTClientHost));
	}
	
/*  Read the message now on whatever channel there is:
*/
        CTRACE(tfp,"Daemon: Reading socket %d from host %s\n",
		com_soc, HTClientHost);

	tcp_status=HTHandle(com_soc);
	
	if(tcp_status<=0) {				/* EOF or error */
	    if (tcp_status<0) {				/* error */
	        CTRACE(tfp,
		"Daemon: Error %d handling incoming message (errno=%d).\n",
			 tcp_status, errno);
	        /* DONT return HTInetStatus("netread");	 error */
	    } else {
		CTRACE(tfp, "Daemon: Socket %d disconnected by peer\n",
		    com_soc);
            }
	    if (role==master) {
		NETCLOSE(com_soc);
		FD_CLR(com_soc, &open_sockets);
	    } else {  /* Not multiclient mode */
#ifdef VM
		return -69;
#else
		return -ECONNRESET;
#endif
	    }
	} else {/* end if handler left socket open */
	    NETCLOSE(com_soc);
	    FD_CLR(com_soc, &open_sockets);
        }
    }; /* for loop */
/*NOTREACHED*/
} /* end server_loop */
Example #14
0
/****************************************************************************
 * name:    HtLoadHTTPANN (PRIVATE)
 * purpose: Issue a command to a group annotation server.
 * inputs:  
 *   - char  *arg:
 *   - char *data:
 *   - int    len:
 *   - char  *com:
 * returns: 
 *   
 * remarks: 
 *   
 ****************************************************************************/
static int
HtLoadHTTPANN(char *arg, char *data, int len, char *com)
{
	int s;				/* Socket number for returned data */
	char *command;			/* The whole command */
	int status;			/* tcp return */
	SockA soc_address;		/* Binary network address */
	SockA *sin = &soc_address;
	char *tptr;
	int fmt, compressed;
	int command_len;
	HTParentAnchor *anchor;

	/*
	 * Set up defaults:
	 */
#ifdef DECNET
	sin->sdn_family = AF_DECnet;        /* Family = DECnet, host order */
	sin->sdn_objnum = DNP_OBJ;          /* Default: http object number */
#else  /* Internet */
	sin->sin_family = AF_INET;          /* Family = internet, host order */
	sin->sin_port = htons(TCP_PORT);    /* Default: http port    */
#endif

	tptr = HTParse(arg, "", PARSE_HOST);
	status = HTParseInet(sin, tptr);
	free(tptr);
	if (status)
	{
		return(status);
	}

	/*
	 * Now, let's get a socket set up from the server for the data.
	 */
#ifdef DECNET
	s = socket(AF_DECnet, SOCK_STREAM, 0);
#else
	s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
#endif
	status = connect
          (s, (struct sockaddr*)&soc_address,sizeof(soc_address));
	if (status < 0)
	{
		return(HTInetStatus("connect"));
	}

        /* If there's an anchor at this point, leave it in. */
	tptr = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION|PARSE_ANCHOR);
#ifndef DISABLE_TRACE
	if (srcTrace) {
		fprintf(stderr, "HTParse(%s) returns:\n\t(%s)\n", arg, tptr);
	}
#endif
	command_len = strlen(com) + strlen(tptr);
	command = malloc(command_len + len + 1);
	if (command == NULL) outofmem(__FILE__, "HTLoadHTTP");
	strcpy(command, com);
	strcat(command, tptr);
	if (len != 0)
	{
		char *bptr;

		bptr = (char *)(command + command_len);
/*		bcopy(data, bptr, len);*/
		memcpy(bptr, data, len);
		command_len += len;
	}
	else
	{
		command_len++;
	}
	free(tptr);

	status = NETWRITE(s, command, command_len);
	free(command);
	if (status < 0)
	{
		return(HTInetStatus("send"));
	}

	tptr = HTParse(arg, "",
		  PARSE_ACCESS | PARSE_HOST | PARSE_PATH |
		  PARSE_PUNCTUATION);
#if 0
	/* fmt = HTFileFormat (tptr, WWW_HTML, &compressed); */
        fmt = WWW_HTML;
	anchor = HTAnchor_parent(HTAnchor_findAddress(arg));
	HTParseFormat(fmt, anchor, s, 0);
#endif
	free(tptr);

	status = NETCLOSE(s);

	return(HT_LOADED);
}