1372 lines
35 KiB
C
1372 lines
35 KiB
C
/****************************************************************************
|
|
* NCSA Mosaic for the X Window System *
|
|
* Software Development Group *
|
|
* National Center for Supercomputing Applications *
|
|
* University of Illinois at Urbana-Champaign *
|
|
* 605 E. Springfield, Champaign IL 61820 *
|
|
* mosaic@ncsa.uiuc.edu *
|
|
* *
|
|
* Copyright (C) 1993, Board of Trustees of the University of Illinois *
|
|
* *
|
|
* NCSA Mosaic software, both binary and source (hereafter, Software) is *
|
|
* copyrighted by The Board of Trustees of the University of Illinois *
|
|
* (UI), and ownership remains with the UI. *
|
|
* *
|
|
* The UI grants you (hereafter, Licensee) a license to use the Software *
|
|
* for academic, research and internal business purposes only, without a *
|
|
* fee. Licensee may distribute the binary and source code (if released) *
|
|
* to third parties provided that the copyright notice and this statement *
|
|
* appears on all copies and that no charge is associated with such *
|
|
* copies. *
|
|
* *
|
|
* Licensee may make derivative works. However, if Licensee distributes *
|
|
* any derivative work based on or derived from the Software, then *
|
|
* Licensee will (1) notify NCSA regarding its distribution of the *
|
|
* derivative work, and (2) clearly notify users that such derivative *
|
|
* work is a modified version and not the original NCSA Mosaic *
|
|
* distributed by the UI. *
|
|
* *
|
|
* Any Licensee wishing to make commercial use of the Software should *
|
|
* contact the UI, c/o NCSA, to negotiate an appropriate license for such *
|
|
* commercial use. Commercial use includes (1) integration of all or *
|
|
* part of the source code into a product for sale or license by or on *
|
|
* behalf of Licensee to third parties, or (2) distribution of the binary *
|
|
* code or source code to third parties that need it to utilize a *
|
|
* commercial product sold or licensed by or on behalf of Licensee. *
|
|
* *
|
|
* UI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR *
|
|
* ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED *
|
|
* WARRANTY. THE UI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE *
|
|
* USERS OF THIS SOFTWARE. *
|
|
* *
|
|
* By using or copying this Software, Licensee agrees to abide by the *
|
|
* copyright law and all other applicable laws of the U.S. including, but *
|
|
* not limited to, export control laws, and the terms of this license. *
|
|
* UI shall have the right to terminate this license immediately by *
|
|
* written notice upon Licensee's breach of, or non-compliance with, any *
|
|
* of its terms. Licensee may be held legally responsible for any *
|
|
* copyright infringement that is caused or encouraged by Licensee's *
|
|
* failure to abide by the terms of this license. *
|
|
* *
|
|
* Comments and questions are welcome and can be sent to *
|
|
* mosaic-x@ncsa.uiuc.edu. *
|
|
****************************************************************************/
|
|
#include "../config.h"
|
|
#include "mosaic.h"
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
|
|
#include "memStuffForPipSqueeks.h"
|
|
#include "cci.h"
|
|
#include "accept.h"
|
|
|
|
/* #define DEBUG */
|
|
|
|
static ListenAddress listenPort;
|
|
|
|
int MCCIanchorcached = 0; /* another ugly ADC hack ZZZZ */
|
|
|
|
#ifndef DISABLE_TRACE
|
|
extern int cciTrace;
|
|
#endif
|
|
|
|
extern char *GetLine();
|
|
|
|
int MCCIReturnListenPortSocketDescriptor()
|
|
{
|
|
return(listenPort);
|
|
}
|
|
|
|
MCCICloseConnection(clientPort)
|
|
MCCIPort clientPort;
|
|
{
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"CloseConnection(): I've been called\n");
|
|
}
|
|
#endif
|
|
|
|
MoCCITerminateAConnection(clientPort);
|
|
NetCloseConnection(clientPort);
|
|
|
|
}
|
|
|
|
MCCICloseAcceptPort()
|
|
{
|
|
NetCloseAcceptPort(listenPort);
|
|
}
|
|
|
|
int MCCIServerInitialize(portNumber)
|
|
/* return 0 on failure */
|
|
/* return listenPort on success */
|
|
int portNumber;
|
|
{
|
|
|
|
listenPort = NetServerInitSocket(portNumber);
|
|
|
|
if (listenPort == -1)
|
|
return(0);
|
|
else
|
|
return(1);
|
|
|
|
}
|
|
|
|
int MCCIGetSocketDescriptor(clientPort)
|
|
/* this routine is platform dependent and is not assumed to be supported
|
|
* on all platforms. It is only here for those routines that wish to have
|
|
* a select() external to the MCCI library.
|
|
* this routine extracts the socket descriptor from the MCCIPort and
|
|
* returns it */
|
|
MCCIPort clientPort;
|
|
{
|
|
return(NetGetSocketDescriptor(clientPort));
|
|
}
|
|
|
|
|
|
|
|
int MCCISendResponseLine(client,code,text)
|
|
MCCIPort client;
|
|
int code; /* response code */
|
|
char *text; /* text response (no newline)*/
|
|
{
|
|
int length/*,lengthSent*/;
|
|
char *buff;
|
|
|
|
if (!(buff = (char *) MALLOC(strlen(text) + 7))) {
|
|
/* out of memory */
|
|
return(MCCI_OUTOFMEMORY);
|
|
}
|
|
|
|
sprintf(buff,"%d %s\r\n",code,text);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
return(MCCI_OK);
|
|
}
|
|
|
|
MCCIPort MCCICheckAndAcceptConnection()
|
|
/* return NULL if no connection */
|
|
/* return a MCCIPort if connected */
|
|
{
|
|
MCCIPort client;
|
|
|
|
if (NetIsThereAConnection(listenPort)){
|
|
client = NetServerAccept(listenPort);
|
|
}
|
|
else {
|
|
return(NULL);
|
|
}
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"Current cci connections: max number=%d, currentNumber=%d\n",
|
|
MoCCIMaxNumberOfConnectionsAllowed(),
|
|
MoCCICurrentNumberOfConnections());
|
|
}
|
|
#endif
|
|
|
|
if (client && MoCCIMaxNumberOfConnectionsAllowed()) {
|
|
/* if maxNumConnections == 0, then no limit */
|
|
if ((MoCCICurrentNumberOfConnections() + 1) >
|
|
MoCCIMaxNumberOfConnectionsAllowed()) {
|
|
MCCISendResponseLine(client,MCCIR_MAX_CONNECTIONS,
|
|
"Maximum number of allowed CCI connections exceeded");
|
|
MCCICloseConnection(client);
|
|
return(NULL);
|
|
|
|
}
|
|
}
|
|
return(client);
|
|
}
|
|
|
|
|
|
|
|
int MCCIIsThereInput(client)
|
|
/* return 1 on true, 0 on false */
|
|
MCCIPort client;
|
|
{
|
|
if (!client)
|
|
return(0);
|
|
return(NetIsThereInput(client));
|
|
}
|
|
|
|
int MCCIReadContent(client,content)
|
|
/* read from client. Next line should contain Content-Length: value
|
|
and then the content body. Returns the number of chars read.
|
|
0 on error. space is allocated and placed into 'content'*/
|
|
MCCIPort client;
|
|
char **content;
|
|
{
|
|
char *s;
|
|
int length;
|
|
char garbage;
|
|
char *line;
|
|
int x;
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIReadContent(): Just entered...about to GetLine()\n");
|
|
}
|
|
#endif
|
|
*content = (char *) 0;
|
|
line = GetLine(client);
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIReadContent(): read line \"%s\"\n",line);
|
|
}
|
|
#endif
|
|
|
|
/* read content length */
|
|
s = strchr(line,':'); /* skip to length */
|
|
if ((!s) || (!strlen(s))) {
|
|
/* bad value */
|
|
return(0);
|
|
}
|
|
s++;
|
|
length = atoi(s);
|
|
if ((length > 10000000) || (length < 0)) {
|
|
/* bad value */
|
|
return(0);
|
|
}
|
|
if (!((*content) = (char*) MALLOC(length+1))) {
|
|
/* to recover protocol, this needs to be read in
|
|
any way before returning, but if we're out of memory,
|
|
it's likely hopeless anyway */
|
|
for (x = 0; x < length; x++) {
|
|
if (!NetRead(client,&garbage,1)) {
|
|
break;
|
|
}
|
|
}
|
|
return(0);
|
|
}
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"ReadContent(): about to read %d bytes\n",length);
|
|
}
|
|
#endif
|
|
|
|
length = ReadBuffer(client,*content,length);
|
|
(*content)[length]='\0';
|
|
return(length);
|
|
}
|
|
|
|
int MCCIHandleSend(client,line,retText)
|
|
/* take care of the SEND request parsing */
|
|
/* return value to send back to cci client */
|
|
MCCIPort client;
|
|
char *line; /* GET request line */
|
|
char *retText; /* text to be returned to cci client */
|
|
{
|
|
int retCode;
|
|
char *s,*end,*start;
|
|
|
|
if (!(s = strchr(line,' ')))
|
|
{ /* skip over SEND */
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
|
|
GetWordFromString(s,&start,&end);
|
|
if (!my_strncasecmp(start,MCCI_S_ANCHOR,strlen(MCCI_S_ANCHOR)))
|
|
{
|
|
/* SEND ANCHOR */
|
|
s = end;
|
|
GetWordFromString(s,&start,&end);
|
|
/* ejb 9 March 1995 added BEFORE and AFTER cases */
|
|
if (start && (start != end))
|
|
/* SEND ANCHOR STOP => turn off SEND ANCHOR */
|
|
if (!my_strncasecmp(start,MCCI_S_STOP,strlen(MCCI_S_STOP)))
|
|
MCCIRequestSendAnchor(&retCode,retText,client,0);
|
|
else
|
|
/* SEND ANCHOR BEFORE => Mosaic sends anchor, BEFORE done getting */
|
|
if (!my_strncasecmp(start,MCCI_S_BEFORE,strlen(MCCI_S_BEFORE)))
|
|
MCCIRequestSendAnchor(&retCode,retText,client,MCCI_SEND_BEFORE);
|
|
else
|
|
/* SEND ANCHOR AFTER => Mosaic sends anchor, AFTER done getting */
|
|
if (!my_strncasecmp(start,MCCI_S_AFTER,strlen(MCCI_S_AFTER)) ||
|
|
(!(start)))
|
|
MCCIRequestSendAnchor(&retCode,retText,client,MCCI_SEND_AFTER);
|
|
else
|
|
/* SEND ANCHOR HANDLER => Mosaic sends anchor first then lets cci handle it ADC ZZZ */
|
|
if (!my_strncasecmp(start,MCCI_S_HANDLER,strlen(MCCI_S_HANDLER)) ||
|
|
(!(start)))
|
|
MCCIRequestSendAnchor(&retCode,retText,client,MCCI_SEND_HANDLER);
|
|
else
|
|
/* SEND ANCHOR XXXXX => Mosaic doesn't know what to do with it */
|
|
{
|
|
/* we don't know what to do with it. */
|
|
strcpy(retText,"what\'s this stuff after ANCHOR?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
/* SEND ANCHOR => Mosaic sends anchor, AFTER done getting*/
|
|
else
|
|
MCCIRequestSendAnchor(&retCode,retText,client,MCCI_SEND_AFTER);
|
|
}
|
|
else if (!my_strncasecmp(start,MCCI_S_OUTPUT,strlen(MCCI_S_OUTPUT))) {
|
|
/* SEND OUTPUT */
|
|
s = end;
|
|
GetWordFromString(s,&start,&end);
|
|
if (start && (start != end)) {
|
|
if (!my_strncasecmp(start, MCCI_S_STOP,
|
|
strlen(MCCI_S_STOP))){
|
|
/* SEND OUTPUT STOP*/
|
|
s = end;
|
|
/* check for mime type */
|
|
GetWordFromString(s,&start,&end);
|
|
if (start && (start != end)) {
|
|
*end = '\0';
|
|
MCCIRequestSendOutput(&retCode,retText,
|
|
client,0,start);
|
|
}
|
|
else {
|
|
/* no output type... so all types */
|
|
MCCIRequestSendOutput(&retCode,retText,
|
|
client,0,(char *)0);
|
|
}
|
|
}
|
|
else {
|
|
/* SEND OUTPUT type */
|
|
*end = '\0';
|
|
MCCIRequestSendOutput(&retCode,retText,
|
|
client,1,start);
|
|
}
|
|
|
|
}
|
|
else {
|
|
/* "SEND OUTPUT" so send it all */
|
|
MCCIRequestSendOutput(&retCode,retText,
|
|
client,1,(char *)0);
|
|
}
|
|
}
|
|
|
|
else if (!my_strncasecmp(start,MCCI_S_BROWSERVIEW,strlen(MCCI_S_BROWSERVIEW))){
|
|
/* SEND BROWSERVIEW */
|
|
s = end;
|
|
GetWordFromString(s,&start,&end);
|
|
if (start && (start != end)) {
|
|
if (!my_strncasecmp(start, MCCI_S_STOP,
|
|
strlen(MCCI_S_STOP))){
|
|
/* SEND BROWSERVIEW STOP*/
|
|
MCCIRequestSendBrowserView(&retCode,retText,
|
|
client,0);
|
|
}
|
|
else {
|
|
/* SEND BROWSERVIEW garbageHere */
|
|
MCCIRequestSendBrowserView(&retCode,retText,
|
|
client,1);
|
|
}
|
|
}
|
|
else {
|
|
/* SEND BROWSERVIEW*/
|
|
MCCIRequestSendBrowserView(&retCode,retText,
|
|
client,1);
|
|
}
|
|
}
|
|
|
|
else if (!my_strncasecmp(start,MCCI_S_EVENT,strlen(MCCI_S_EVENT))){
|
|
/* SEND EVENT */
|
|
s = end;
|
|
GetWordFromString(s,&start,&end);
|
|
if (start && (start != end)) {
|
|
if (!my_strncasecmp(start, MCCI_S_STOP,
|
|
strlen(MCCI_S_STOP))){
|
|
/* SEND EVENT STOP*/
|
|
MCCIRequestSendEvent(&retCode,retText,
|
|
client,0);
|
|
}
|
|
else {
|
|
/* SEND EVENT garbageHere */
|
|
MCCIRequestSendEvent(&retCode,retText,
|
|
client,1);
|
|
}
|
|
}
|
|
else {
|
|
/* SEND EVENT*/
|
|
MCCIRequestSendEvent(&retCode,retText,
|
|
client,1);
|
|
}
|
|
}
|
|
|
|
else {
|
|
/* SEND ??? */
|
|
strcpy(retText,"SEND what???");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
return(retCode);
|
|
}
|
|
|
|
|
|
int MCCIHandlePost(client,line,retText)
|
|
/* take care of the Post request parsing */
|
|
/* return value to send back to cci client */
|
|
MCCIPort client;
|
|
char *line; /* GET request line */
|
|
char *retText; /* text to be returned to cci client */
|
|
{
|
|
char *s,*end;
|
|
char *url;
|
|
char *postData;
|
|
int postDataLength;
|
|
char *mimeType;
|
|
int retCode;
|
|
int output;
|
|
char *tmpend;
|
|
char *next;
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIHandlePost(): parsing line: \"%s\"\n",line);
|
|
}
|
|
#endif
|
|
|
|
if (!(s = strchr(line,' '))){ /* skip over POST */
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
GetWordFromString(s,&url,&end); /* Get <url> */
|
|
if ((!url) || (url == end)) {
|
|
strcpy(retText,"Hey bud, where's the URL for POST?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
s = end;
|
|
url++; /* skip over '<' */
|
|
end--; /* backup over '>' */
|
|
*end = '\0'; /* terminate url */
|
|
|
|
url = strdup(url);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIHandlePost(): extracted url: \"%s\"\n",url);
|
|
}
|
|
#endif
|
|
|
|
GetWordFromString(s,&mimeType,&end); /* Get Content Type*/
|
|
if ((!mimeType) || (mimeType == end)) {
|
|
strcpy(retText,"No Content-Type?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
tmpend = end;
|
|
|
|
s = end;
|
|
GetWordFromString(s,&next,&end); /* move pointer to OUTPUT */
|
|
|
|
*tmpend = '\0'; /* terminate the content-type */
|
|
mimeType = strdup(mimeType);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIHandlePost(): mimeType: \"%s\"\n",mimeType);
|
|
}
|
|
#endif
|
|
|
|
output = MCCI_DEFAULT;
|
|
if (next && (next != end)) {
|
|
if (!my_strncasecmp(next,MCCI_S_OUTPUT,
|
|
strlen(MCCI_S_OUTPUT))) {
|
|
/* output tag */
|
|
s = end;
|
|
GetWordFromString(s,&next,&end);
|
|
if (next && (next != end)) {
|
|
if (!my_strncasecmp(next,MCCI_S_CURRENT,strlen(MCCI_S_CURRENT))) {
|
|
output = MCCI_OUTPUT_CURRENT;
|
|
}
|
|
else if (!my_strncasecmp(next,MCCI_S_NEW,strlen(MCCI_S_NEW))) {
|
|
output = MCCI_OUTPUT_NEW;
|
|
}
|
|
else if (!my_strncasecmp(next,MCCI_S_NONE,strlen(MCCI_S_NONE))) {
|
|
output = MCCI_OUTPUT_NONE;
|
|
}
|
|
else {
|
|
output = MCCI_DEFAULT;
|
|
}
|
|
s = end;
|
|
GetWordFromString(s,&next,&end);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
output = MCCI_DEFAULT;
|
|
}
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"POST url = \"%s\",mimeType=\"%s\",output=%d\n",
|
|
url,mimeType,output);
|
|
}
|
|
#endif
|
|
|
|
postDataLength = MCCIReadContent(client,&postData);
|
|
if (postDataLength < 1) {
|
|
strcpy(retText,"No data for POST");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"Got the data, datalength = %d\n",postDataLength);
|
|
}
|
|
#endif
|
|
|
|
MCCIRequestPost(client,&retCode, retText, url, mimeType,
|
|
postData, postDataLength, output);
|
|
|
|
free(url);
|
|
free(mimeType);
|
|
|
|
return(retCode);
|
|
}
|
|
|
|
|
|
int MCCIHandleDisplay(client,line,retText)
|
|
/* take care of the Display request parsing */
|
|
/* return value to send back to cci client */
|
|
MCCIPort client;
|
|
char *line; /* GET request line */
|
|
char *retText; /* text to be returned to cci client */
|
|
{
|
|
char *s,*end;
|
|
char *url;
|
|
char *displayData;
|
|
int displayDataLength;
|
|
char *mimeType;
|
|
int retCode;
|
|
int output;
|
|
char *tmpend;
|
|
char *next;
|
|
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIHandleDisplay(): parsing line: \"%s\"\n",line);
|
|
}
|
|
#endif
|
|
|
|
if (!(s = strchr(line,' '))){ /* skip over DISPLAY */
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
GetWordFromString(s,&url,&end); /* Get <url> */
|
|
if ((!url) || (url == end)) {
|
|
strcpy(retText,"Hey bud, where's the URL for Display?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
s = end;
|
|
url++; /* skip over '<' */
|
|
end--; /* backup over '>' */
|
|
*end = '\0'; /* terminate url */
|
|
|
|
url = strdup(url);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIHandleDisplay(): extracted url: \"%s\"\n",url);
|
|
}
|
|
#endif
|
|
|
|
GetWordFromString(s,&mimeType,&end); /* Get Content Type*/
|
|
if ((!mimeType) || (mimeType == end)) {
|
|
strcpy(retText,"No Content-Type?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
tmpend = end;
|
|
|
|
s = end;
|
|
GetWordFromString(s,&next,&end); /* move pointer to OUTPUT */
|
|
|
|
*tmpend = '\0'; /* terminate the content-type */
|
|
mimeType = strdup(mimeType);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIHandleDisplay(): mimeType: \"%s\"\n",mimeType);
|
|
}
|
|
#endif
|
|
|
|
output = MCCI_DEFAULT;
|
|
if (next && (next != end)) {
|
|
if (!my_strncasecmp(next,MCCI_S_OUTPUT,
|
|
strlen(MCCI_S_OUTPUT))) {
|
|
/* output tag */
|
|
s = end;
|
|
GetWordFromString(s,&next,&end);
|
|
if (next && (next != end)) {
|
|
if (!my_strncasecmp(next,MCCI_S_CURRENT,strlen(MCCI_S_CURRENT))) {
|
|
output = MCCI_OUTPUT_CURRENT;
|
|
}
|
|
else if (!my_strncasecmp(next,MCCI_S_NEW,strlen(MCCI_S_NEW))) {
|
|
output = MCCI_OUTPUT_NEW;
|
|
}
|
|
else if (!my_strncasecmp(next,MCCI_S_NONE,strlen(MCCI_S_NONE))) {
|
|
output = MCCI_OUTPUT_NONE;
|
|
}
|
|
else {
|
|
output = MCCI_DEFAULT;
|
|
}
|
|
s = end;
|
|
GetWordFromString(s,&next,&end);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
output = MCCI_DEFAULT;
|
|
}
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"Display url = \"%s\",mimeType=\"%s\",output=%d\n",
|
|
url,mimeType,output);
|
|
}
|
|
#endif
|
|
|
|
/* MCCIReadContent will malloc space for displayData */
|
|
displayDataLength = MCCIReadContent(client,&displayData);
|
|
if (displayDataLength < 1) {
|
|
strcpy(retText,"No data for DISPLAY");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"Got the data, datalength = %d\n",displayDataLength);
|
|
}
|
|
#endif
|
|
|
|
MCCIRequestDisplay(client, &retCode, retText, url, mimeType,
|
|
displayData, displayDataLength, output);
|
|
|
|
free(url);
|
|
free(mimeType);
|
|
|
|
return(retCode);
|
|
}
|
|
|
|
|
|
int MCCIHandleGet(client,line,retText)
|
|
/* take care of the GET request parsing */
|
|
/* return value to send back to cci client */
|
|
MCCIPort client;
|
|
char *line; /* GET request line */
|
|
char *retText; /* text to be returned to cci client */
|
|
{
|
|
char *s;
|
|
char *url/*,*start*/,*end,*next;
|
|
int output/*,absRel*/;
|
|
char *headerExt;
|
|
int headerExtLength;
|
|
int retCode;
|
|
|
|
output = MCCI_DEFAULT;
|
|
/* absRel = MCCI_DEFAULT;*/
|
|
headerExt = (char *) 0;
|
|
headerExtLength=0;
|
|
|
|
if (!(s = strchr(line,' '))){ /* skip over GET */
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
GetWordFromString(s,&url,&end); /* URL */
|
|
if (my_strncasecmp(url,"URL",3)) {
|
|
strcpy(retText,"No URL?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
s = end;
|
|
GetWordFromString(s,&url,&end); /* actual <url> */
|
|
if ((!url) || (url == end)) {
|
|
strcpy(retText,"Hey bud, where's the URL?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
s = end;
|
|
url++; /* skip over '<' */
|
|
end--; /* backup over '>' */
|
|
*end = '\0'; /* terminate url */
|
|
|
|
url = strdup(url);
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"GetURL: URL=\"%s\"\n",url);
|
|
}
|
|
#endif
|
|
|
|
GetWordFromString(s,&next,&end);
|
|
if (next && (next != end)) {
|
|
if (!my_strncasecmp(next,MCCI_S_OUTPUT,
|
|
strlen(MCCI_S_OUTPUT))) {
|
|
/* output tag */
|
|
s = end;
|
|
GetWordFromString(s,&next,&end);
|
|
if (next && (next != end)) {
|
|
if (!my_strncasecmp(next,MCCI_S_CURRENT,strlen(MCCI_S_CURRENT))) {
|
|
output = MCCI_OUTPUT_CURRENT;
|
|
}
|
|
else if (!my_strncasecmp(next,MCCI_S_NEW,strlen(MCCI_S_NEW))) {
|
|
output = MCCI_OUTPUT_NEW;
|
|
}
|
|
else if (!my_strncasecmp(next,MCCI_S_NONE,strlen(MCCI_S_NONE))) {
|
|
output = MCCI_OUTPUT_NONE;
|
|
}
|
|
else {
|
|
output = MCCI_OUTPUT_CURRENT;
|
|
}
|
|
s = end;
|
|
GetWordFromString(s,&next,&end);
|
|
}
|
|
}
|
|
}
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"pt #2 GetURL: URL=\"%s\"\n",url);
|
|
}
|
|
#endif
|
|
|
|
if (next && (next != end)) {
|
|
if (!my_strncasecmp(next,MCCI_S_HEADER,strlen(MCCI_S_HEADER))) {
|
|
/* get header extention */
|
|
headerExtLength = MCCIReadContent(client,&headerExt);
|
|
}
|
|
}
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"pt #3 GetURL: URL=\"%s\"\n",url);
|
|
}
|
|
#endif
|
|
/* set flag to be caught in MoCCISendAnchorToCCI */
|
|
cciStatPreventSendAnchor(client, url);
|
|
MCCIRequestGetURL(&retCode,retText,url,output,headerExt);
|
|
if ((headerExtLength > 0) && (headerExt)) {
|
|
FREE(headerExt);
|
|
}
|
|
free(url);
|
|
return(retCode);
|
|
}
|
|
|
|
|
|
int MCCIHandleDoCommand(client,line,retText)
|
|
/* take care of the GET request parsing */
|
|
/* return value to send back to cci client */
|
|
MCCIPort client;
|
|
char *line; /* GET request line */
|
|
char *retText; /* text to be returned to cci client */
|
|
{
|
|
char *s;
|
|
char *end, *tmpend ;
|
|
char *command;
|
|
char *parameter;
|
|
int retCode;
|
|
|
|
/* expected line, DOCOMMAND command parameters... */
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"line is %s\n", line);
|
|
}
|
|
#endif
|
|
|
|
if (!(s = strchr(line,' '))){ /* skip over DOCOMMAND */
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
GetWordFromString(s,&command,&end); /* Get command */
|
|
if ((!command) || (command == end)) {
|
|
strcpy(retText,"You need a command");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
s = end;
|
|
tmpend = end;
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIHandleDisplay(): extracted command: \"%s\"\n",command);
|
|
}
|
|
#endif
|
|
|
|
parameter = strdup(s);
|
|
|
|
*tmpend = '\0';
|
|
command = strdup(command);
|
|
|
|
MCCIRequestDoCommand(&retCode,retText,command, parameter);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"MCCIHandleDisplay(): retCode: %d -- retText: [%s]\n",retCode,retText);
|
|
}
|
|
#endif
|
|
|
|
return(retCode);
|
|
}
|
|
|
|
|
|
int MCCIHandleForm(client,line,retText)
|
|
/* take care of the Form request parsing */
|
|
/* return value to send back to cci client */
|
|
MCCIPort client;
|
|
char *line; /* GET request line */
|
|
char *retText; /* text to be returned to cci client */
|
|
{
|
|
char *s;
|
|
char *actionID,*end,*next,*startstop, *tmp;
|
|
int output/*,absRel*/;
|
|
int retCode;
|
|
int status;
|
|
|
|
if (!(s = strchr(line,' '))){ /* skip over FORM */
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
GetWordFromString(s,&actionID,&end); /* actionID */
|
|
if ((!actionID) || (actionID == end)) {
|
|
strcpy(retText,"Hey bud, where's the actionID?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
s = end;
|
|
actionID = strdup(actionID);
|
|
tmp = strchr(actionID, ' ');
|
|
*tmp = '\0';
|
|
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"GetURL: actionID=[%s]\n",actionID);
|
|
}
|
|
#endif
|
|
|
|
GetWordFromString(s,&next,&end);
|
|
if (next && (next != end)) {
|
|
if (!my_strncasecmp(next,
|
|
MCCI_S_STOP, strlen(MCCI_S_STOP))) {
|
|
status = 0;
|
|
}
|
|
else if(!my_strncasecmp(next,
|
|
MCCI_S_START, strlen(MCCI_S_START))){
|
|
status = 1;
|
|
}
|
|
else {
|
|
return(MCCIR_ERROR);
|
|
}
|
|
}
|
|
else
|
|
return(MCCIR_ERROR);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr," actionID=\"%s\"\n",actionID);
|
|
}
|
|
#endif
|
|
|
|
/* set flag to be caught in MoCCISendAnchorToCCI */
|
|
/*
|
|
cciStatPreventSendAnchor(client, url);
|
|
*/
|
|
MCCIRequestForm(client, &retCode,retText,actionID,status);
|
|
|
|
/* free(actionID);
|
|
*/
|
|
return(retCode);
|
|
}
|
|
|
|
#ifdef NEW
|
|
#define NUM_ANNO_CODES 3
|
|
static int annoCodes[NUM_ANNO_CODES] = {MCCI_PUBLIC_ANNOTATION, MCCI_GROUP_ANNOTATION, MCCI_PRIVATE_ANNOTATION};
|
|
static char* annoStrings[NUM_ANNO_CODES] = {MCCI_S_PUBLIC_ANN, MCCI_S_GROUP_ANN, MCCI_S_PRIVATE_ANN};
|
|
#else /* NEW */
|
|
|
|
#endif /* NEW */
|
|
int MCCIHandleGetAnnotation(client,line,retText,retData,retDataLength)
|
|
MCCIPort client;
|
|
char *line; /* GET request line */
|
|
char *retText; /* text to be returned to cci client */
|
|
char **retData;
|
|
int *retDataLength;
|
|
{
|
|
char *s;
|
|
char *end;
|
|
char *type;
|
|
char *url;
|
|
int annotationType;
|
|
int retCode;
|
|
|
|
if (!(s = strchr(line,' '))){ /* skip over GET */
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
annotationType = 0;
|
|
GetWordFromString(s,&type,&end); /* Get type (pub,priv,group)*/
|
|
if (!my_strncasecmp(type,MCCI_S_PUBLIC_ANN,strlen(MCCI_S_PUBLIC_ANN))) {
|
|
annotationType = MCCI_PUBLIC_ANNOTATION;
|
|
}
|
|
else if (!my_strncasecmp(type,MCCI_S_GROUP_ANN,
|
|
strlen(MCCI_S_GROUP_ANN))) {
|
|
annotationType = MCCI_GROUP_ANNOTATION;
|
|
}
|
|
else if (!my_strncasecmp(type,MCCI_S_PRIVATE_ANN,
|
|
strlen(MCCI_S_PRIVATE_ANN))) {
|
|
annotationType = MCCI_PRIVATE_ANNOTATION;
|
|
}
|
|
else if (!my_strncasecmp(type,MCCI_S_ALL_ANN,
|
|
strlen(MCCI_S_ALL_ANN))) {
|
|
annotationType = MCCI_ALL_ANNOTATION;
|
|
}
|
|
else {
|
|
strcpy(retText,"PUBLIC, PRIVATE, GROUP or ALL annotation requests only");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
s = end;
|
|
GetWordFromString(s,&url,&end); /* actual <url> */
|
|
if ((!url) || (url == end)) {
|
|
strcpy(retText,"Hey bud, where's the URL?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
s = end;
|
|
url++; /* skip over '<' */
|
|
end--; /* backup over '>' */
|
|
*end = '\0'; /* terminate url */
|
|
|
|
url = strdup(url);
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"GetAnnotation: URL=\"%s\"\n",url);
|
|
}
|
|
#endif
|
|
|
|
#ifdef NEW
|
|
MCCISendResponseLine(client,retCode,retText);
|
|
for (int index = 0; index < NUM_ANNO_CODES; ++index) {
|
|
if (!my_strncasecmp(type,annoStrings[index],
|
|
strlen(annoStrings[index])) ||
|
|
!my_strncasecmp(type,MCCI_S_ALL_ANN,
|
|
strlen(MCCI_S_ALL_ANN))) {
|
|
MCCIRequestGetAnnotation(&retCode,retText,retData,retDataLength,
|
|
url,annoCodes[index]);
|
|
}
|
|
else
|
|
MCCIGetAnnotationDummyLine(&retCode,retText,retData,retDataLength,annoCodes[index]);
|
|
|
|
if (retDataLength !=
|
|
NetServerWrite(client,retData,retDataLength)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
#else /* NEW */
|
|
MCCIRequestGetAnnotation(&retCode,retText,retData,retDataLength,
|
|
url,annotationType);
|
|
|
|
#endif /* NEW */
|
|
free(url);
|
|
return(retCode);
|
|
}
|
|
|
|
int MCCIHandlePutAnnotation(client,line,retText)
|
|
MCCIPort client;
|
|
char *line; /* PUT request line */
|
|
char *retText; /* text to be returned to cci client */
|
|
{
|
|
char *s;
|
|
char *end;
|
|
char *type;
|
|
char *url;
|
|
char *annotation;
|
|
int annotationLength;
|
|
int retCode;
|
|
int annotationType;
|
|
|
|
if (!(s = strchr(line,' '))){ /* skip over GET */
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
annotationType = 0;
|
|
GetWordFromString(s,&type,&end); /* Get type (pub,priv,group)*/
|
|
if (!my_strncasecmp(type,MCCI_S_PUBLIC_ANN,strlen(MCCI_S_PUBLIC_ANN))) {
|
|
annotationType = MCCI_PUBLIC_ANNOTATION;
|
|
}
|
|
else if (!my_strncasecmp(type,MCCI_S_GROUP_ANN,
|
|
strlen(MCCI_S_GROUP_ANN))) {
|
|
annotationType = MCCI_GROUP_ANNOTATION;
|
|
}
|
|
else if (!my_strncasecmp(type,MCCI_S_PRIVATE_ANN,
|
|
strlen(MCCI_S_PRIVATE_ANN))) {
|
|
annotationType = MCCI_PRIVATE_ANNOTATION;
|
|
}
|
|
else {
|
|
strcpy(retText,"PUBLIC, PRIVATE or GROUP put annotations only");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
s = end;
|
|
GetWordFromString(s,&url,&end); /* actual <url> */
|
|
if ((!url) || (url == end)) {
|
|
strcpy(retText,"Hey bud, where's the URL?");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
s = end;
|
|
url++; /* skip over '<' */
|
|
end--; /* backup over '>' */
|
|
*end = '\0'; /* terminate url */
|
|
|
|
url = strdup(url);
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
fprintf(stderr,"GetURL: URL=\"%s\"\n",url);
|
|
}
|
|
#endif
|
|
annotationLength = MCCIReadContent(client,&annotation);
|
|
if (annotationLength < 1) {
|
|
strcpy(retText,"No annotation data");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
MCCIRequestPutAnnotation(&retCode,retText,annotationType,url,
|
|
annotation,annotationLength);
|
|
return(retCode);
|
|
}
|
|
|
|
int MCCIHandleFileToURL(client,line,retText)
|
|
MCCIPort client;
|
|
char *line;
|
|
char *retText;
|
|
{
|
|
char *fileName;
|
|
char *url;
|
|
char *s;
|
|
char *end;
|
|
int retCode;
|
|
|
|
if (!(s = strchr(line,' '))){ /* skip over FILETOURL*/
|
|
strcpy(retText,"Error in protocol");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
|
|
GetWordFromString(s,&fileName,&end); /* <fileName> */
|
|
if ((!fileName) || (fileName == end)) {
|
|
strcpy(retText,"I need a filename to translate");
|
|
return(MCCIR_ERROR);
|
|
}
|
|
fileName++; /* skip over '<' */
|
|
end--; /* backup over '>' */
|
|
*end = '\0'; /* terminate fileName */
|
|
|
|
fileName = strdup(fileName);
|
|
|
|
MCCIRequestFileToURL(&retCode,retText,fileName);
|
|
|
|
free(fileName);
|
|
|
|
return(retCode);
|
|
|
|
}
|
|
|
|
|
|
int MCCIHandleInput(client)
|
|
/* read input from the client and do something with it */
|
|
/* return 1 on success, 0 on failure or disconnect */
|
|
MCCIPort client;
|
|
{
|
|
int retCode;
|
|
char retText[MCCI_MAX_RETURN_TEXT];
|
|
char *blah;
|
|
char **retData=&blah;
|
|
int retDataLength = 0;
|
|
char *line;
|
|
|
|
line = GetLine(client);
|
|
|
|
#ifndef DISABLE_TRACE
|
|
if (cciTrace) {
|
|
if (line)
|
|
fprintf(stderr,"Server Read: %s\n",line);
|
|
else
|
|
fprintf(stderr,"Server Read: NULL line\n");
|
|
}
|
|
#endif
|
|
|
|
if (!line) {
|
|
/* error or disconnect */
|
|
MCCICloseConnection(client);
|
|
return(0);
|
|
}
|
|
|
|
/* parse the request */
|
|
/* to save speed & memory this parse is destructive to the text in 'line' */
|
|
|
|
if (!my_strncasecmp(line,MCCI_S_DISCONNECT,strlen(MCCI_S_DISCONNECT))) {
|
|
MCCISendResponseLine(client,MCCIR_DISCONNECT_OK,
|
|
"DISCONNECT request received");
|
|
return(0);
|
|
}
|
|
/* This has to go ahead of the simple get or else it gets snagged */
|
|
else if (!my_strncasecmp(line,MCCI_S_GETANNOTATION,
|
|
strlen(MCCI_S_GETANNOTATION))) {
|
|
retDataLength = 0;
|
|
|
|
/*SWP -- 7/11/95
|
|
* In the Original line, &retData is passed. retData is a char * to begin with
|
|
* and it eventually gets assigned the value from mo_fetch_personal_annotations
|
|
* which sends back all of the annotations for the specified url in one char
|
|
* * string. Not an array of strings.
|
|
*/
|
|
retCode = MCCIHandleGetAnnotation(client,line,retText,retData,
|
|
&retDataLength);
|
|
/*Original
|
|
retCode = MCCIHandleGetAnnotation(client,line,retText,&retData,
|
|
&retDataLength);
|
|
*/
|
|
MCCISendResponseLine(client,retCode,retText);
|
|
if (retDataLength !=
|
|
NetServerWrite(client,*retData,retDataLength)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
/* FINISHME */ /**** if retDataLength, send data */
|
|
/*** if retDataLength, free retData?? */
|
|
|
|
if (retDataLength>0) {
|
|
free(*retData);
|
|
}
|
|
|
|
}
|
|
else if (!my_strncasecmp(line,MCCI_S_GET,strlen(MCCI_S_GET))) {
|
|
retCode = MCCIHandleGet(client,line,retText);
|
|
MCCISendResponseLine(client,retCode,retText);
|
|
}
|
|
|
|
else if (!my_strncasecmp(line,MCCI_S_DOCOMMAND,strlen(MCCI_S_DOCOMMAND))){
|
|
retCode = MCCIHandleDoCommand(client,line,retText);
|
|
MCCISendResponseLine(client,retCode,retText);
|
|
}
|
|
|
|
else if (!my_strncasecmp(line,MCCI_S_DISPLAY,strlen(MCCI_S_DISPLAY))) {
|
|
retCode = MCCIHandleDisplay(client, line, retText);
|
|
MCCISendResponseLine(client, retCode,
|
|
"DISPLAY request received by Mosaic");
|
|
}
|
|
else if (!my_strncasecmp(line, MCCI_S_FORM, strlen(MCCI_S_FORM))) {
|
|
retCode = MCCIHandleForm(client, line, retText);
|
|
MCCISendResponseLine(client, MCCIR_FORM_OK,
|
|
"FORM request received by Mosaic");
|
|
}
|
|
else if (!my_strncasecmp(line,MCCI_S_QUIT,strlen(MCCI_S_QUIT))) {
|
|
MCCISendResponseLine(client,MCCIR_QUIT_OK,
|
|
"QUIT request received exiting...");
|
|
MCCIRequestQuit();
|
|
}
|
|
else if (!my_strncasecmp(line,MCCI_S_SEND,strlen(MCCI_S_SEND))) {
|
|
retCode = MCCIHandleSend(client,line,retText);
|
|
MCCISendResponseLine(client,retCode,retText);
|
|
}
|
|
else if (!my_strncasecmp(line,MCCI_S_POST,strlen(MCCI_S_POST))) {
|
|
retCode = MCCIHandlePost(client,line,retText);
|
|
MCCISendResponseLine(client,retCode,retText);
|
|
}
|
|
else if (!my_strncasecmp(line,MCCI_S_PUTANNOTATION,
|
|
strlen(MCCI_S_PUTANNOTATION))) {
|
|
retCode = MCCIHandlePutAnnotation(client,line,retText);
|
|
MCCISendResponseLine(client,retCode,retText);
|
|
}
|
|
else if (!my_strncasecmp(line,MCCI_S_FILE_TO_URL,
|
|
strlen(MCCI_S_FILE_TO_URL))) {
|
|
retCode = MCCIHandleFileToURL(client,line,retText);
|
|
MCCISendResponseLine(client,retCode,retText);
|
|
}
|
|
else {
|
|
/*
|
|
MCCIRRequestUnrecognized();
|
|
*/
|
|
MCCISendResponseLine(client,MCCIR_UNRECOGNIZED,
|
|
"Command not recognized");
|
|
}
|
|
|
|
|
|
return(1);
|
|
}
|
|
|
|
|
|
MCCISendAnchorHistory(client,url)
|
|
MCCIPort client;
|
|
char *url;
|
|
{
|
|
char buff[1024];
|
|
if (MCCIanchorcached == 1) /* ugly ADC hack ZZZ */
|
|
sprintf(buff,"%s <%s> CACHED", MCCI_S_ANCHOR, url);
|
|
else
|
|
sprintf(buff,"%s <%s>", MCCI_S_ANCHOR, url);
|
|
|
|
return(MCCISendResponseLine(client, MCCIR_ANCHOR_INFO,buff));
|
|
}
|
|
|
|
int MCCIFormQueryToClient(client, actionID, query, contentType, post_data)
|
|
MCCIPort client;
|
|
char *actionID;
|
|
char *query;
|
|
char *contentType;
|
|
char *post_data;
|
|
{
|
|
char buff[1024];
|
|
int length, dataLength;
|
|
|
|
|
|
sprintf(buff, "%s %s ", actionID, query);
|
|
if(MCCISendResponseLine(client, MCCIR_FORM_RESPONSE,buff)){
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
sprintf(buff,"Content-Type: %s\r\n",contentType);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
dataLength = strlen(post_data);
|
|
sprintf(buff,"Content-Length: %d \r\n",dataLength);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
if (dataLength!= NetServerWrite(client,post_data,dataLength)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
return(MCCI_OK);
|
|
}
|
|
|
|
int MCCISendOutputFile(client,contentType,fileName)
|
|
MCCIPort client;
|
|
char *contentType;
|
|
char *fileName;
|
|
/* this routine used to send output back to the client */
|
|
{
|
|
int length;
|
|
int countDown;
|
|
char buff[1030];
|
|
struct stat fileInfo;
|
|
FILE *fp;
|
|
|
|
if (stat(fileName,&fileInfo)) { /* get the length of the file */
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
if (!(fp = fopen(fileName,"r"))) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
sprintf(buff,"%d Send Data Output\r\n",MCCIR_SEND_DATA_OUTPUT);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
sprintf(buff,"Content-Type: %s \r\n",contentType);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
sprintf(buff,"Content-Length: %d \r\n",fileInfo.st_size);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
countDown = fileInfo.st_size;
|
|
while(countDown > 0) {
|
|
if (0 < (length = fread(buff,1,1024,fp))) {
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
countDown -= length;
|
|
|
|
}
|
|
else {
|
|
/* error reading here...but we promised to send
|
|
countDown number of bytes, so send nulls */
|
|
while (countDown > 0) {
|
|
if (1 != NetServerWrite(client,"\0",1)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
countDown--;
|
|
}
|
|
}
|
|
}
|
|
fclose(fp);
|
|
return(MCCI_OK);
|
|
|
|
}
|
|
|
|
|
|
int MCCISendBrowserViewOutput(client,url,contentType,data,dataLength)
|
|
/* Send BrowserView output response to client */
|
|
MCCIPort client;
|
|
char *url;
|
|
char *contentType;
|
|
char *data;
|
|
int dataLength;
|
|
{
|
|
char buff[1024];
|
|
int length;
|
|
|
|
if (MCCI_OK!=MCCISendResponseLine(client,MCCIR_SEND_BROWSERVIEW,url)){
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
|
|
sprintf(buff,"Content-Type: %s\r\n",contentType);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
sprintf(buff,"Content-Length: %d \r\n",dataLength);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
if (dataLength!= NetServerWrite(client,data,dataLength)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
return(MCCI_OK);
|
|
|
|
}
|
|
|
|
|
|
int MCCISendEventOutput(client, event_type)
|
|
/* Send Event output response to client */
|
|
MCCIPort client;
|
|
CCI_events event_type;
|
|
{
|
|
char buff[1024];
|
|
int length;
|
|
|
|
sprintf(buff,"%d %d\r\n",MCCIR_SEND_EVENT, (int) event_type);
|
|
length = strlen(buff);
|
|
if (length != NetServerWrite(client,buff,length)) {
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
return(MCCI_OK);
|
|
}
|
|
|
|
|
|
int MCCISendMouseAnchorOutput(client, anchor)
|
|
/* Send MouseAnchor output response to client */
|
|
MCCIPort client;
|
|
char *anchor;
|
|
{
|
|
|
|
if (MCCI_OK!=MCCISendResponseLine(client,MCCIR_SEND_MOUSE_ANCHOR,anchor)){
|
|
return(MCCI_FAIL);
|
|
}
|
|
|
|
return(MCCI_OK);
|
|
}
|
|
|