Exemple #1
0
PUBLIC char HTGetSSLCharacter ARGS1(void *, handle)
{
    char ch;
    interrupted_in_htgetcharacter = 0;
    if(!handle)
	return (char)EOF;
    do {
	if (input_pointer >= input_limit) {
	    int status = SSL_read((SSL *)handle,
				 input_buffer, INPUT_BUFFER_SIZE);
	    if (status <= 0) {
		if (status == 0)
		    return (char)EOF;
		if (status == HT_INTERRUPTED) {
		    CTRACE((tfp, "HTFormat: Interrupted in HTGetSSLCharacter\n"));
		    interrupted_in_htgetcharacter = 1;
		    return (char)EOF;
		}
		CTRACE((tfp, "HTFormat: SSL_read error %d\n", status));
		return (char)EOF; /* -1 is returned by UCX
				     at end of HTTP link */
	    }
	    input_pointer = input_buffer;
	    input_limit = input_buffer + status;
	}
	ch = *input_pointer++;
    } while (ch == (char) 13); /* Ignore ASCII carriage return */

    return FROMASCII(ch);
}
char *LYKeycodeToString(int c,
			int upper8)
{
    static char buf[30];
    unsigned n;
    BOOLEAN named = FALSE;

    for (n = 0; n < TABLESIZE(named_keys); n++) {
	if (named_keys[n].key == c) {
	    named = TRUE;
	    LYStrNCpy(buf, named_keys[n].name, sizeof(buf) - 1);
	    break;
	}
    }

    if (!named) {
	if (c <= 0377
	    && TOASCII(c) > TOASCII(' ')
	    && TOASCII(c) < 0177)
	    sprintf(buf, "%c", c);
	else if (upper8
		 && TOASCII(c) > TOASCII(' ')
		 && c <= 0377
		 && c <= LYlowest_eightbit[current_char_set])
	    sprintf(buf, "%c", c);
	else if (TOASCII(c) < TOASCII(' '))
	    sprintf(buf, "^%c", FROMASCII(TOASCII(c) | 0100));
	else if (c >= 0400)
	    sprintf(buf, "key-0x%x", c);
	else
	    sprintf(buf, "0x%x", c);
    }
    return buf;
}
Exemple #3
0
/*		Decode %xx escaped characters			HTUnEscape()
 *		**		-----------------------------
 *		**
 *		**	This function takes a pointer to a string in which some
 *		**	characters may have been encoded in %xy form, where xy is
 *		**	the acsii hex code for character 16x+y.
 *		**	The string is converted in place, as it will never grow.
 *		*/
char * HTUnEscape (char * str)
{
    char * p = str;
    char * q = str;

/* 16.3.2007 Chris Kronberg: Removed Null entry test. In our case not relevant. */

    if (!(p && *p))
        return str;

    while(*p != '\0') {
        if (*p == HEX_ESCAPE ) {
            if ( p[1] == '2' && p[2]  == '0' ) { 
               /* 16.3.2007 Christine Kronberg */
               /* We do not want to decode the whitespace */
               *q++ = *p++;
            }
            else 
            {
            p++;
	    if (*p) {
               *q = HTAsciiHexToChar(*p++) * 16;
            }
#if 1
	    /* Suggestion from Markku Savela */
	    if (*p) {
               *q = FROMASCII(*q + HTAsciiHexToChar(*p)), ++p;
            }
	    q++;
#else 
	    if (*p) {
               *q = FROMASCII(*q + HTAsciiHexToChar(*p));
            }
	    p++, q++;
#endif
           }
	} else {
	    *q++ = *p++; 
	}
    }
    
    *q++ = 0;
    return str;
    
} /* HTUnEscape */
Exemple #4
0
PRIVATE void NetToText_put_character ARGS2(HTStream *, me, char, net_char)
{
    char c = FROMASCII(net_char);
    if (me->had_cr) {
	if (c == LF) {
	    me->sink->isa->put_character(me->sink, '\n');	/* Newline */
	    me->had_cr = NO;
	    return;
	} else {
	    me->sink->isa->put_character(me->sink, CR); /* leftover */
	}
    }
    me->had_cr = (BOOL) (c == CR);
    if (!me->had_cr)
	me->sink->isa->put_character(me->sink, c);		/* normal */
}
Exemple #5
0
int LYKeyForEditAction(int lec)
{
    int editaction, i;

    for (i = FIRST_I; i >= 0; i = NEXT_I(i, KEYMAP_SIZE - 1)) {
	editaction = CurrentLineEditor()[i];
	if (editaction == lec) {
#ifdef NOT_ASCII
	    if (i < 256) {
		return FROMASCII(i);
	    } else
#endif
		return i;
	}
    }
    return (-1);
}
Exemple #6
0
/*
 * Given a lynxactioncode, return a key (lynxkeycode) or sequence of two keys
 * that results in the given action while forms-editing.  The main keycode is
 * returned as function value, possibly with modifier bits set; in addition, if
 * applicable, a key that sets the required modifier flag is returned in
 * *pmodkey if (pmodkey!=NULL).  Non-lineediting bindings that would require
 * typing LYE_LKCMD (default ^V) to activate are not checked here, the caller
 * should do that separately if required.  If no key is bound by current
 * line-editor bindings to the action, -1 is returned.
 *
 * This is all a bit long - it is general enough to continue to work should the
 * three Mod<N>Binding[] become different tables.  - kw
 */
int LYEditKeyForAction(int lac,
		       int *pmodkey)
{
    int editaction, i, c;
    int mod1found = -1, mod2found = -1, mod3found = -1;

    if (pmodkey)
	*pmodkey = -1;
    for (i = FIRST_I; i >= 0; i = NEXT_I(i, KEYMAP_SIZE - 1)) {
	editaction = CurrentLineEditor()[i];
#ifdef NOT_ASCII
	if (i < 256) {
	    c = FROMASCII(i);
	} else
#endif
	    c = i;
	if (editaction == (lac | LYE_FORM_LAC))
	    return c;
	if (editaction == LYE_FORM_PASS) {
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
	    if (lynx_edit_mode && !no_dired_support && lac &&
		LKC_TO_LAC(key_override, c) == lac)
		return c;
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
	    if (LKC_TO_LAC(keymap, c) == lac)
		return c;
	}
	if (editaction == LYE_TAB) {
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
	    if (lynx_edit_mode && !no_dired_support && lac &&
		LKC_TO_LAC(key_override, '\t') == lac)
		return c;
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
	    if (LKC_TO_LAC(keymap, '\t') == lac)
		return c;
	}
	if (editaction == LYE_SETM1 && mod1found < 0)
	    mod1found = i;
	if (editaction == LYE_SETM2 && mod2found < 0)
	    mod2found = i;
	if ((editaction & LYE_DF) && mod3found < 0)
	    mod3found = i;
    }
#ifdef USE_ALT_BINDINGS
    if (mod3found >= 0) {
	for (i = mod3found; i >= 0; i = NEXT_I(i, LAST_MOD3_LKC)) {
	    editaction = CurrentLineEditor()[i];
	    if (!(editaction & LYE_DF))
		continue;
	    editaction = Mod3Binding[i];
#ifdef NOT_ASCII
	    if (i < 256) {
		c = FROMASCII(i);
	    } else
#endif
		c = i;
	    if (pmodkey)
		*pmodkey = c;
	    if (editaction == (lac | LYE_FORM_LAC))
		return (c | LKC_MOD3);
	    if (editaction == LYE_FORM_PASS) {
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
		if (lynx_edit_mode && !no_dired_support && lac &&
		    LKC_TO_LAC(key_override, c) == lac)
		    return (c | LKC_MOD3);
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
		if (LKC_TO_LAC(keymap, c) == lac)
		    return (c | LKC_MOD3);
	    }
	    if (editaction == LYE_TAB) {
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
		if (lynx_edit_mode && !no_dired_support && lac &&
		    LKC_TO_LAC(key_override, '\t') == lac)
		    return (c | LKC_MOD3);
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
		if (LKC_TO_LAC(keymap, '\t') == lac)
		    return (c | LKC_MOD3);
	    }
	}
    }
    if (mod1found >= 0) {
	if (pmodkey) {
#ifdef NOT_ASCII
	    if (mod1found < 256) {
		*pmodkey = FROMASCII(mod1found);
	    } else
#endif
		*pmodkey = mod1found;
	}
	for (i = FIRST_I; i >= 0; i = NEXT_I(i, LAST_MOD1_LKC)) {
	    editaction = Mod1Binding[i];
#ifdef NOT_ASCII
	    if (i < 256) {
		c = FROMASCII(i);
	    } else
#endif
		c = i;
	    if (editaction == (lac | LYE_FORM_LAC))
		return (c | LKC_MOD1);
	    if (editaction == LYE_FORM_PASS) {
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
		if (lynx_edit_mode && !no_dired_support && lac &&
		    LKC_TO_LAC(key_override, c) == lac)
		    return (c | LKC_MOD1);
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
		if (LKC_TO_LAC(keymap, c) == lac)
		    return (c | LKC_MOD1);
	    }
	    if (editaction == LYE_TAB) {
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
		if (lynx_edit_mode && !no_dired_support && lac &&
		    LKC_TO_LAC(key_override, '\t') == lac)
		    return (c | LKC_MOD1);
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
		if (LKC_TO_LAC(keymap, '\t') == lac)
		    return (c | LKC_MOD1);
	    }
	}
    }
    if (mod2found >= 0) {
	if (pmodkey) {
#ifdef NOT_ASCII
	    if (mod1found < 256) {
		*pmodkey = FROMASCII(mod1found);
	    } else
#endif
		*pmodkey = mod1found;
	}
	for (i = FIRST_I; i >= 0; i = NEXT_I(i, LAST_MOD2_LKC)) {
	    editaction = Mod2Binding[i];
#ifdef NOT_ASCII
	    if (i < 256) {
		c = FROMASCII(i);
	    } else
#endif
		c = i;
	    if (editaction == (lac | LYE_FORM_LAC))
		return (c | LKC_MOD2);
	    if (editaction == LYE_FORM_PASS) {
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
		if (lynx_edit_mode && !no_dired_support && lac &&
		    LKC_TO_LAC(key_override, c) == lac)
		    return (c | LKC_MOD2);
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
		if (LKC_TO_LAC(keymap, c) == lac)
		    return (c | LKC_MOD2);
	    }
	    if (editaction == LYE_TAB) {
#if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
		if (lynx_edit_mode && !no_dired_support && lac &&
		    LKC_TO_LAC(key_override, '\t') == lac)
		    return (c | LKC_MOD2);
#endif /* DIRED_SUPPORT && OK_OVERRIDE */
		if (LKC_TO_LAC(keymap, '\t') == lac)
		    return (c | LKC_MOD2);
	    }
	}
    }
#endif /* USE_ALT_BINDINGS */
    if (pmodkey)
	*pmodkey = -1;
    return (-1);
}
Exemple #7
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);
}
Exemple #8
0
PRIVATE int HTSSLReader_read (HTInputStream * me)
{
    HTHost * host = me->host;
    SOCKET soc = HTChannel_socket(me->ch);
    HTNet * net = HTHost_getReadNet(host);
    HTRequest * request = HTNet_request(net);
    int status;
    if (!net->readStream) {
	HTTRACE(STREAM_TRACE, "HTSSLReader. No read stream for net object %p\n" _ net);
        return HT_ERROR;
    }
        
    /* Setting SSL */
    if (!me->htssl) {
	if ((me->htssl = HTSSL_new(soc)) == NULL) {
	    HTRequest_addSystemError(net->request, ERR_FATAL, socerrno, NO, "SSLREAD");
	    return HT_ERROR;
	}
    }

    /* Read from socket if we got rid of all the data previously read */
    do {

	/* Don't read if we have to push unwritten data from last call */
        if (me->write >= me->read) {
            me->b_read = 0;
            me->data[0] ='\0';
 	    me->b_read = HTSSL_read(me->htssl, soc, me->data, INPUT_BUFFER_SIZE);     
	    status = HTSSL_getError(me->htssl, me->b_read);
	    HTTRACE(STREAM_TRACE, "HTSSLReader. SSL returned %d\n" _ status);

	    /* Check what we got done */
	    switch (status) {

	    case SSL_ERROR_NONE:

		HTTRACEDATA(me->data, me->b_read, "Reading from socket %d" _ soc);
		me->write = me->data;
		me->read = me->data + me->b_read;
		HTTRACE(STREAM_TRACE, "HTSSLReader. %d bytes read from socket %d\n" _ 
			me->b_read _ soc);

		/* Make progress notification */
		if (request) {
		    HTAlertCallback * cbf = HTAlert_find(HT_PROG_READ);
		    if (HTNet_rawBytesCount(net))
			HTNet_addBytesRead(net, me->b_read);
		    if (cbf) {
			int tr = HTNet_bytesRead(net);
			(*cbf)(request, HT_PROG_READ, HT_MSG_NULL, NULL, &tr, NULL);
		    }
		}
		break;

	    case SSL_ERROR_WANT_READ:
		HTTRACE(STREAM_TRACE, "HTSSLReader. WOULD BLOCK fd %d\n" _ soc);
		HTHost_register(host, net, HTEvent_READ);

		/*
		**  There seems to be a bug as even though it says "read finished"
		**  it doesn't say that it wants to write. We therefore have to make
		**  an explicit flush to make sure that we don't block forever.
		*/
		HTHost_forceFlush(host);

		return HT_WOULD_BLOCK;

	    case SSL_ERROR_WANT_WRITE:
		return HTHost_forceFlush(host);

	    case SSL_ERROR_WANT_X509_LOOKUP:
		/* @@@ what to do here? @@@ */
		return HT_OK;

	    case SSL_ERROR_ZERO_RETURN:
	    case SSL_ERROR_SSL:
	    case SSL_ERROR_SYSCALL:
		HTTRACE(PROT_TRACE, "HTSSLReader. FIN received on socket %d\n" _ soc);
                HTHost_unregister(host, net, HTEvent_READ);
                HTHost_register(host, net, HTEvent_CLOSE);

                HTSSL_close(me->htssl);    
                HTSSL_free(me->htssl);
                me->htssl = NULL;

                return HT_CLOSED;
	    }
	}

#ifdef FIND_SIGNATURES
	{
	    char * ptr = me->data;
	    int len = me->b_read;
	    while ((ptr = strnstr(ptr, &len, "HTTP/1.1 200 OK")) != NULL) {
		HTTRACE(STREAM_TRACE, "HTSSLReader. Signature found at 0x%x of 0x%x.\n" _ ptr - me->data _ me->b_read);
		ptr++;
		len--;
	    }
	}
#endif /* FIND_SIGNATURES */
 #ifdef NOT_ASCII
	{
	    char *p = me->data;
	    while (p < me->read) {
		*p = FROMASCII(*p);
		p++;
	    }
	}
#endif /* NOT_ASCII */
	
	/* Now push the data down the stream */
	if ((status = (*net->readStream->isa->put_block)
	     (net->readStream, me->write, me->b_read)) != HT_OK) {
	    if (status == HT_WOULD_BLOCK) {
		HTTRACE(STREAM_TRACE, "HTSSLReader. Target WOULD BLOCK\n");
		HTHost_unregister(host, net, HTEvent_READ);
		return HT_WOULD_BLOCK;
	    } else if (status == HT_PAUSE) {
		HTTRACE(STREAM_TRACE, "HTSSLReader. Target PAUSED\n");
		HTHost_unregister(host, net, HTEvent_READ);
		return HT_PAUSE;
	    /* CONTINUE code or stream code means data was consumed */
	    } else if (status == HT_CONTINUE || status > 0) {
		if (status == HT_CONTINUE) {
		    HTTRACE(STREAM_TRACE, "HTSSLReader. CONTINUE\n");
		} else
		    HTTRACE(STREAM_TRACE, "HTSSLReader. Target returns %d\n" _ status);
/*		me->write = me->read; */
		return status;
	    } else {				     /* We have a real error */
		HTTRACE(STREAM_TRACE, "HTSSLReader. Target ERROR %d\n" _ status);
		return status;
	    }
	}
	me->write = me->read;
	{
	    int remaining = HTHost_remainingRead(host);
	    if (remaining > 0) {
		HTTRACE(STREAM_TRACE, "HTSSLReader. DIDN'T CONSUME %d BYTES: `%s\'\n" _ 
			    remaining _ me->read);
		HTHost_setConsumed(host, remaining);
	    }
	}
    } while (net->preemptive);
    HTHost_register(host, net, HTEvent_READ);
    return HT_WOULD_BLOCK;
}
Exemple #9
0
/*	Handle one message
**	------------------
**
** On entry,
**	soc		A file descriptor for input and output.
** On exit,
**	returns		>0	Channel is still open.
**			0	End of file was found, please close file
**			<0	Error found, please close file.
*/
int handle(int soc)
{
#define COMMAND_SIZE	255
#define MAX_LINES 10000			/* Maximum number of lines returned */
    char command[COMMAND_SIZE+1];
    char		    buffer[BUFFER_SIZE];
    int	status;
    char * arg;		/* Pointer to the argument string */
    char * filename;	/* Pointer to filename or group list*/
    char * keywords;	/* pointer to keywords */
    char system_command[COMMAND_SIZE+1];
    int lines;		/* Number of lines returned by EXEC file */
    int fd;		/* File descriptor number */
    int	isIndex = 0;	/* Is the thing asked for an index? */
   
    for (;;) {
	status = read(soc, command, COMMAND_SIZE);
	if (status<=0) {
	    if (TRACE) printf("read returned %i, errno=%i\n", status, errno);
	    return status;	/* Return and close file */
	}
	command[status]=0;	/* terminate the string */
#ifdef VM
	{
	    char * p;
	    for (p=command; *p; p++) {
		*p = FROMASCII(*p);
		if (*p == '\n') *p = ' ';
	    }
	}
#endif
	if (TRACE) printf("read string is `%s'\n", command);

	arg=strchr(command,' ');
	if (arg) {
	    *arg++ = 0;				/* Terminate command 	*/
	    arg = strip(arg);			/* Strip space 		*/
	    if (0==strcmp("GET", command)) {	/* Get a file 		*/

/* 	Remove host and any punctuation. (Could use HTParse to remove access too @)
*/      
		filename = arg;
		if (arg[0]=='/') {
		    if (arg[1]=='/') {
		        filename = strchr(arg+2, '/');	/* Skip //host/ */
			if (!filename) filename=arg+strlen(arg);
		    } else {
		        filename = arg+1;		/* Assume root: skip slash */
		    }
		}

		if (*filename) {		/* (else return test message) 	*/
		    keywords=strchr(filename, '?');
		    if (keywords) *keywords++=0;	/* Split into two */
#ifdef VM

/*	Formats supported by FIND are:
**
**	/FIND				Help for find general index
**	/FIND/				(same)
**	/FIND/?				(same)
**	/FIND/group.disk.ft.fn		Get a document from a disk- NOT INDEX
**	/FIND/grouplist?		Help for group index
**	/FIND/grouplist?keylist		Search a set of disks for keywords
**					where grouplist = group+group+group.. or void
**					keylist = key+key+key... (not void)
*/
		    if((
		    		(0==strncmp(filename,"FIND",4))
		    		|| (0==strncmp(filename,"find",4))
			) && (
		           (filename[4]==0)
			   || (filename[4]=='/')
			   || (filename[4]='?')
			)) {
		    
		        filename=filename+4;
			if (*filename=='/') filename++;	/* Skip first slash */
			 
			if (!*filename) {	 /* If no data at all,    */
			    if (!keywords)
			     keywords = filename; /* Respond as if just "?" given */			
			}
    
			if (keywords) {
			    char *p;
			    while((p=strchr(filename,'+'))!=0) *p=' ';/* Remove +s */
			    while((p=strchr(keywords,'+'))!=0) *p=' ';/* Remove +s */
			    
			    if (!*keywords) {	/* If no keywords    */
				write_ascii(soc, "<IsIndex><TITLE>");
				write_ascii(soc, filename);
				write_ascii(soc, " keyword index</TITLE>\n");
				if (*filename) {
				    write_ascii(soc, "This index covers groups: `");
				    write_ascii(soc, filename);
				    write_ascii(soc, "'");
				} else {
			    	    write_ascii(soc,
		"This is the general CERN public document index");
				}
				write_ascii(soc,
		".<P>You may use your browser's keyword search on this index.<P>\n");
				return 0;
			    }
    
			    strcpy(system_command,"EXEC NICFIND1 ");
			    strcat(system_command, keywords);
			    if (*filename) {
				strcat(system_command, " ( ");
				strcat(system_command, filename);
			    }
			    isIndex = 1;
			} else {
			    strcpy(system_command,"EXEC NICFOUN1 ");
			    strcat(system_command, filename);
			    isIndex = 0;
			}
			
		    }  /* if FIND */

/*	Formats supported by NEWS are:
**
**	/NEWS				General news
**	/NEWS/grouplist			News for given groups
**	/NEWS/grouplist?		All news for all given groups
**	/NEWS/grouplist?keylist		Search news for keywords
**					where grouplist = group+group+group.. or void
**					keylist = key+key+key... (can be void)
*/
		    else if((
		    		(0==strncmp(filename,"NEWS",4))
		    		|| (0==strncmp(filename,"news",4))
			    ) && (
				(filename[4]==0)
				|| (filename[4]=='/')
				|| (filename[4]='?')
			    )) {
		    
			isIndex = 1;
		        filename=filename+4;
			if (*filename=='/') filename++;		/* Skip first slash */
			 
			if (!*filename) {	 /* If no data at all,    */
			    if (!keywords)
			     keywords = filename; /* Respond as if just "?" given */			
			}
			
			if (!keywords) keywords = ""; /* "If nun, write none"-1066 */
			
			{
			    char *p;
			    while((p=strchr(filename,'+'))!=0) *p=' ';/* Remove +s */
			    while((p=strchr(keywords,'+'))!=0) *p=' ';/* Remove +s */
			    
			    strcpy(system_command,"EXEC NICFIND1 ");
			    if (keywords) strcat(system_command, keywords);
			    strcat(system_command, " ( NEWS ");
			    if (*filename) {
				strcat(system_command, "(");
				strcat(system_command, filename);
				strcat(system_command, ") ");
			    }
			}
			
		    } else { /* not FIND or NEWS */
			write_ascii(soc, "Bad syntax. No such document.\n");
			return 0;
		    }

/*	Execute system command and get the results
*/
		    lines = system(system_command);
		    if (TRACE) printf("Command `%s' returned %i lines.\n",
			     system_command, lines);
		    if (lines<=0) {
			write_ascii(soc,
			"\nSorry, the FIND server could not execute\n  `");
			write_ascii(soc, system_command);
			write_ascii(soc, "'\n\n");
			return 0;
		    }
		    
		    /*	Copy the file across: */
		    
		    if (isIndex) write_ascii(soc, "<IsIndex>\n");
		    for(;lines; lines--){		/* Speed necessary here */
			char *p;
			fgets(buffer, BUFFER_SIZE, stdin);
	    /*	    if (strcmp(buffer,"<END_OF_FILE>")==0) break;	*/
			for(p=buffer; *p; p++) *p = TOASCII(*p);
			write(soc, buffer, p-buffer);
		    }
		    return 0;
			


#else
		    fd = open(arg, O_RDONLY, 0 );	/* un*x open @@ */
		    if (fd<0) return fd;
		    status = read_file(soc, fd);
		    close(fd);
		    return 0;
#endif
		}
	    }	
	}

	write_ascii(soc, "<h1>FIND Server v1.03</h1><h2>Test response</h2>\n");
	write_ascii(soc, "\n\nThe (unrecognised) command used was `");
	write_ascii(soc, command);
	write_ascii(soc, "'.\n\n");
	
	if (TRACE) printf("Return test string written back'\n");
	return 0;		/* End of file - please close socket */
    } /* for */
    
} /* handle */
Exemple #10
0
PRIVATE void HTMIME_put_character ARGS2(HTStream *, me, char, c)
{
    if (me->state == MIME_TRANSPARENT) {
    	(*me->targetClass.put_character)(me->target, c);/* MUST BE FAST */
	return;
    }
    
    /* This slightly simple conversion just strips CR and turns LF to
    ** newline. On unix LF is \n but on Mac \n is CR for example.
    ** See NetToText for an implementation which preserves single CR or LF.
    */
    if (me->net_ascii) {
        c = FROMASCII(c);
	if (c == CR) return;
	else if (c == LF) c = '\n';
    }
    
    switch(me->state) {

    case MIME_IGNORE:
    	return;

    case MIME_TRANSPARENT:		/* Not reached see above */
    	(*me->targetClass.put_character)(me->target, c);
	return;
	
    case MIME_NET_ASCII:
    	(*me->targetClass.put_character)(me->target, c); /* MUST BE FAST */
	return;

    case NEWLINE:
	if (c != '\n' && WHITE(c)) {		/* Folded line */
	    me->state = me->fold_state;	/* pop state before newline */
	    break;
	}
	
	/*	else Falls through */
	
    case BEGINNING_OF_LINE:
        switch(c) {
	case 'c':
	case 'C':
	    me->check_pointer = "ontent-t";
	    me->if_ok = CONTENT_T;
	    me->state = CHECK;
	    break;
	case '\n':			/* Blank line: End of Header! */
	    {
	        if (TRACE) fprintf(stderr,
			"HTMIME: MIME content type is %s, converting to %s\n",
			HTAtom_name(me->format), HTAtom_name(me->targetRep));
		me->target = HTStreamStack(me->format, me->request, NO);
		if (!me->target) {
		    if (TRACE) fprintf(stderr, "MIME: Can't translate! ** \n");
		    me->target = me->sink;	/* Cheat */
		}
		if (me->target) {
		    me->targetClass = *me->target->isa;
		/* Check for encoding and select state from there @@ */
		
		    me->state = MIME_TRANSPARENT; /* From now push straigh through */
		} else {
		    me->state = MIME_IGNORE;		/* What else to do? */
		}
	    }
	    break;
	    
	default:
	   goto bad_field_name;
	   break;
	   
	} /* switch on character */
        break;
	
    case CHECK:				/* Check against string */
        if (TOLOWER(c) == *(me->check_pointer)++) {
	    if (!*me->check_pointer) me->state = me->if_ok;
	} else {		/* Error */
	    if (TRACE) fprintf(stderr,
	    	"HTMIME: Bad character `%c' found where `%s' expected\n",
		c, me->check_pointer - 1);
	    goto bad_field_name;
	}
	break;
	
    case CONTENT_T:
        switch(c) {
	case 'r':
	case 'R':
	    me->check_pointer = "ansfer-encoding:";
	    me->if_ok = CONTENT_TRANSFER_ENCODING;
	    me->state = CHECK;
	    break;
	    
	case 'y':
	case 'Y':
	    me->check_pointer = "pe:";
	    me->if_ok = CONTENT_TYPE;
	    me->state = CHECK;
	    break;
	    
	default:
	    goto bad_field_name;
	    
	} /* switch on character */
	break;
	
    case CONTENT_TYPE:
    case CONTENT_TRANSFER_ENCODING:
        me->field = me->state;		/* remember it */
	me->state = SKIP_GET_VALUE;
				/* Fall through! */
    case SKIP_GET_VALUE:
    	if (c == '\n') {
	   me->fold_state = me->state;
	   me->state = NEWLINE;
	   break;
	}
	if (WHITE(c)) break;	/* Skip white space */
	
	me->value_pointer = me->value;
	me->state = GET_VALUE;   
	/* Fall through to store first character */
	
    case GET_VALUE:
    	if (WHITE(c)) {			/* End of field */
	    *me->value_pointer = 0;
	    switch (me->field) {
	    case CONTENT_TYPE:
	        me->format = HTAtom_for(me->value);
		break;
	    case CONTENT_TRANSFER_ENCODING:
	        me->encoding = HTAtom_for(me->value);
		break;
	    default:		/* Should never get here */
	    	break;
	    }
	} else {
	    if (me->value_pointer < me->value + VALUE_SIZE - 1) {
	        *me->value_pointer++ = c;
		break;
	    } else {
	        goto value_too_long;
	    }
	}
	/* Fall through */
	
    case JUNK_LINE:
        if (c == '\n') {
	    me->state = NEWLINE;
	    me->fold_state = me->state;
	}
	break;
	
	
    } /* switch on state*/
    
    return;
    
value_too_long:
    if (TRACE) fprintf(stderr,
    	"HTMIME: *** Syntax error. (string too long)\n");
    
bad_field_name:				/* Ignore it */
    me->state = JUNK_LINE;
    return;
    
}
/*	Handle one message
**	------------------
**
** On entry,
**	soc		A file descriptor for input and output.
** On exit,
**	returns		>0	Channel is still open.
**			0	End of file was found, please close file
**			<0	Error found, please close file.
*/
PUBLIC int HTHandle ARGS1(int, soc)
{
#define COMMAND_SIZE	2048            /* @@@@ WAIS queries can be big! */
#define MAX_LINES 10000			/* Maximum number of lines returned */
    char command[COMMAND_SIZE+1];
    char *keywords;	/* pointer to keywords in address */
    int	status;
    char * arg;		/* Pointer to the argument string */
    
    time_t theTime;	/* A long integer giving the datetime in secs */
       
    for (;;) {
        int allocated = COMMAND_SIZE;
	command = (char *)malloc(allocated+1);
	if (!command) {
	    fprintf(stderr, "Daemon: insufficient memrory!\n");
	    exit(-5);
	}
        for(;;) {
	    if (allocated - bytes_read < MINIMUM_READ) {
	        allocated = allocated + ALLOCATION_UNIT;
		command = (char *)realloc(command, allocated+1);
		if (!command) {
		  fprintf(stderr, "Daemon: No memory to reallocate command!!\n");
		  exit(-6);
		}
	    }
    	    status = NETREAD(soc, command + bytes_read, allocated - bytes_read);
	    if (TRACE) fprintf(stderr, "NETREAD returned %d, errono=%d\n", status, errno);
	    if (status<=0) {
	        free(command);
	        return status;	/* Return and close file */
	    }
	    {
	      char * p= command + bytes_read;
	      for(p=command + bytes_read; p < command + bytes_read + status; p++) {
		if (!*p) {
		  free(command);
		  return -1;    /* No LF */
		}
	        if (*p==10) {
		  break;
		}
	      }
	      bytes_read = bytes_read + status;
	      if (p=command+bytes_read)/* No terminators yet */
		continue;
	    }
	    break;/* Terminator found */
	}
	command[bytes_read]=0;	/* terminate the string */
#ifdef NOT_ASCII
	{
	    char * p;
	    for (p=command; *p; p++) {
		*p = FROMASCII(*p);
		if (*p == '\n') *p = ' ';
	    }
	}
#endif

/*	Log the call:
*/
	if (logfile) {
	    time(&theTime);
	    fprintf(logfile, "%24.24s %s %s",
		ctime(&theTime), HTClientHost, command);
	    fflush(logfile);	/* Actually update it on disk */
	    if (TRACE) printf("Log: %24.24s %s %s",
		ctime(&theTime), HTClientHost, command);
	}
	
	arg=strchr(command,' ');
	if (arg) {
	    int stat;
	    *arg++ = 0;				/* Terminate command 	*/
	    arg = strip(arg);			/* Strip space 		*/

	    if (0==strcmp("GET", command)) {	/* Get a file 		*/
		keywords=strchr(arg, '?');
		if (keywords) *keywords++=0;	/* Split into two */
	        stat =  HTRetrieve(arg, keywords, soc);
		free(command);
		return stat;
	    }

	} /* Space found supplied */

	HTWriteASCII(soc, "<h1>HTTP Server v1.02</h1><h2>Test response</h2>\n");
	HTWriteASCII(soc, "\n\nThe (unrecognised) command used was `");
	HTWriteASCII(soc, command);
	HTWriteASCII(soc, "'.\n\n");
	
	if (TRACE) printf("Return test string written back'\n");
	free(command);
	return 0;		/* End of file - please close socket */
    } /* for */
    
} /* handle */