#include #include "memStuffForPipSqueeks.h" #include "cci.h" #include "connect.h" #include "list.h" static int initialized = 0; static List anchorCBList = 0; static List outputCBList = 0; static List browserViewCBList = 0; extern char *GetLine(); typedef struct { MCCIPort serverPort; void (*callBack)(); void *callBackData; } AnchorCallBack; typedef struct { MCCIPort serverPort; char *type; void (*callBack)(); void *callBackData; } OutputCallBack; typedef struct { MCCIPort serverPort; void (*callBack)(); void *callBackData; } BrowserViewCallBack; int MCCIGetSocketDescriptor(serverPort) /* 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 serverPort; { return(NetGetSocketDescriptor(serverPort)); } int MCCIIsConnected(serverPort) /* return 1 if connected, 0 if not */ MCCIPort serverPort; { return(NetIsConnected(serverPort)); } void MCCIReadBrowserViewOutput(serverPort,response) MCCIPort serverPort; char *response; /* Read output from BrowserView */ { char *line; char *url = (char *) 0; BrowserViewCallBack *bvCB; char *start,*end,*s,*contentType; int contentLength; char *data = (char *) 0; int numRead; /* expect response line to be 'MCCIR_SEND_BROWSERVIEW ' */ /* skip over MCCIR_SEND_BROWSERVIEW */ s = response; s+=4; /* skip over repsonse code */ GetWordFromString(s,&url,&end); if (url && (url != end)) { url = strdup(url); } else { url = (char *) 0; } #ifdef DEBUG printf("MCCIReadBrowserViewOutput(): I've been called\n"); printf("MCCIReadBrowserViewOutput(): url = \"%s\"\n",url); #endif line = GetLine(serverPort); if (!line) { return; } #ifdef DEBUG printf("MCCIReadBrowserViewOutput(): got line:%s\n",line); #endif contentType = (char *) 0; if (!strncasecmp("Content-Type:",line,13)) { start = line; start += 13; GetWordFromString(start,&s,&end); *end = '\0'; contentType = strdup(s); line = GetLine(serverPort); #ifdef DEBUG printf("MCCIReadBrowserViewOutput(): 2 got line:%s\n",line); #endif if (!line) { return; } } #ifdef DEBUG printf("MCCIReadBrowserViewOutput(): contentType:%s\n",contentType); #endif if (!strncasecmp("Content-Length:",line,15)) { start = line; start += 15; GetWordFromString(start,&s,&end); contentLength = atoi(s); if (contentLength < 1){ return; /* error */ } if (!(data = (char *) MALLOC(contentLength))) { return; /* error */ } #ifdef DEBUG printf("MCCIReadBrowserViewOutput(): type=%s,length=%d\n", contentType,contentLength); #endif numRead = ReadBuffer(serverPort,data,contentLength); #ifdef DEBUG printf("MCCIReadBrowserViewOutput(): number of bytes read = %d\n",numRead); #endif /******************************************************* * done parsing getting message from network, * now notify my callbacks */ bvCB = (BrowserViewCallBack *) ListHead(browserViewCBList); while (bvCB) { if (bvCB->callBack) { (void)(bvCB->callBack)(url,contentType, data, contentLength, bvCB->callBackData); } bvCB = (BrowserViewCallBack *) ListNext(browserViewCBList); } } #ifdef DEBUG printf("MCCIReadBrowserViewOutput(): returning\n"); #endif } /* MCCIReadBrowserViewOutput() */ static void MCCIReadSendDataOutput(serverPort) /* read output sent from the Mosaic */ /* error recovery could be better in this routine */ MCCIPort serverPort; { char *line; char *start,*end,*s,*contentType; int contentLength; char *data = (char *) 0; OutputCallBack *outCB; int numRead; #ifdef DEBUG printf("MCCIReadSendDataOutput(): I've been called\n"); #endif line = GetLine(serverPort); if (!line) { return; } #ifdef DEBUG printf("MCCIReadSendDataOutput(): got line:%s\n",line); #endif contentType = (char *) 0; if (!strncasecmp("Content-Type:",line,13)) { start = line; start += 13; GetWordFromString(start,&s,&end); *end = '\0'; contentType = strdup(s); line = GetLine(serverPort); #ifdef DEBUG printf("MCCIReadSendDataOutput(): 2 got line:%s\n",line); #endif if (!line) { return; } } #ifdef DEBUG printf("MCCIReadSendDataOutput(): contentType:%s\n",contentType); #endif if (!strncasecmp("Content-Length:",line,15)) { start = line; start += 15; GetWordFromString(start,&s,&end); contentLength = atoi(s); if (contentLength < 1){ return; /* error */ } if (!(data = (char *) MALLOC(contentLength))) { return; /* error */ } #ifdef DEBUG printf("MCCIReadSendDataOutput(): type=%s,length=%d\n", contentType,contentLength); #endif numRead = ReadBuffer(serverPort,data,contentLength); #ifdef DEBUG printf("MCCIReadSendDataOutput(): number of bytes read = %d\n",numRead); #endif /* find callback */ outCB = (OutputCallBack *) ListHead(outputCBList); while(outCB) { #ifdef DEBUG printf("MCCIReadSendDataOutput(): Checking a call back\n"); printf("MCCIReadSendDataOutput(): comparing \"%s\" with \"%s\"\n",outCB->type,contentType); #endif if ((outCB->serverPort == serverPort) && (!strcasecmp(outCB->type,contentType))) { if (outCB->callBack) { (void)(outCB->callBack)(contentType, data,numRead,outCB->callBackData); #ifdef DEBUG printf("MCCIReadSendDataOutput(): calling a cb\n"); #endif } } outCB = (OutputCallBack *) ListNext(outputCBList); } } #ifdef DEBUG printf("MCCIReadSendDataOutput(): returning\n"); #endif if (!line) { return; } } static void MCCIHandleAddOutput(serverPort,response) MCCIPort serverPort; char *response; { char respCode[10]; char *start,*end; static char url[1024]; #ifdef DEBUG printf("MCCIHandleAddOutput I've been called with"); #endif if ((!response) || (!MCCIIsConnected(serverPort))) { return; } #ifdef DEBUG printf("\n\"%s\"\n",response); #endif sprintf(respCode,"%d",MCCIR_ANCHOR_INFO); if (!strncmp(respCode,response,3)) { /* It's an ANCHOR INFO */ AnchorCallBack *acb; start = strchr(response,'<'); end = strchr(response,'>'); start++; *end='\0'; strcpy(url,start); /* call all the anchor callbacks */ acb = (AnchorCallBack *) ListHead(anchorCBList); while (acb) { if (acb->serverPort == serverPort) { if (acb->callBack) { (acb->callBack)(url,acb->callBackData); } } acb = (AnchorCallBack *) ListNext(anchorCBList); } return; } sprintf(respCode,"%d",MCCIR_SEND_DATA_OUTPUT); if (!strncmp(respCode,response,3)) { /* It's send output data */ MCCIReadSendDataOutput(serverPort); } sprintf(respCode,"%d",MCCIR_SEND_BROWSERVIEW); if (!strncmp(respCode,response,3)) { /* It's send output data */ MCCIReadBrowserViewOutput(serverPort,response); } sprintf(respCode, "%d", MCCIR_GET_OK); if (!strncmp(respCode,response,3)) { /* It's a GET OK */ #ifdef DEBUG printf("GET reply: %s\n",response); #endif } sprintf(respCode, "%d", MCCIR_GET_FAILED); if (!strncmp(respCode,response,3)) { /* It's a GET FAILED */ #ifdef DEBUG printf("GET reply: %s\n",response); #endif } /* I don't know what this is Additional Output is... */ return; } int MCCIPoll(serverPort) /* this routine is intended to be called periodically to check for input * from the server. If so, it's handled. * return -1 on Not connected. * return 1 if something was read. * return 0 on nothing here. */ MCCIPort serverPort; { char *line; int ret=0; if (!MCCIIsConnected(serverPort)) { return(-1); } while (MCCIIsThereInput(serverPort)) { line = GetLine(serverPort); if (!line) { /* server has disconnected */ MCCIDisconnect(serverPort); } MCCIHandleAddOutput(serverPort,line); ret = 1; } if (!MCCIIsConnected(serverPort)) { return(-1); } else { return(ret); } } static char *MCCIGetResponse(serverPort) MCCIPort serverPort; /* get a response from a server. The string returned is good only until the next call to GetLine() */ { char *response; if (!MCCIIsConnected(serverPort)) { return("901 Error not connected"); } response = GetLine(serverPort); if (response) { while (response[0] == '3') { MCCIHandleAddOutput(serverPort,response); response = GetLine(serverPort); } } else { MCCIDisconnect(serverPort); return("900 Error No response"); } return(response); } static int MCCIWrite(serverPort,message,length) /* This is a wrapper to NetWrite, It's here to insure that data from the * server is read in before a write is sent out so as to prevent a * write write deadlock */ MCCIPort serverPort; char *message; int length; { int writeLength; if (!MCCIIsConnected(serverPort)) { return(0); } while(NetIsThereInput(serverPort)) { MCCIGetResponse(serverPort); if (!MCCIIsConnected(serverPort)) { return(0); } } writeLength = NetWrite(serverPort,message,length); return(writeLength); } MCCIInitialize() { anchorCBList = ListCreate(); outputCBList = ListCreate(); browserViewCBList = ListCreate(); initialized = 1; } MCCIPort MCCIConnect(serverAddress,port,callBack,callBackData) /* connect to given address */ /* return 0 on can't connect */ /* upon termination of connection, the callback is called. It's of the form: * void CCICloseCallBack(MCCIPort serverPort, void callBackData); */ char *serverAddress; int port; void (*callBack)(); /* disconnect callback */ void *callBackData; /* disconnect callback data */ { MCCIPort serverPort; char *line; if (!initialized) { MCCIInitialize(); } if (!(serverPort = NetClientConnect(serverAddress,port))) { return((MCCIPort) 0); } line = MCCIGetResponse(serverPort); #ifdef DEBUG printf("MCCIConnect(): received from server:\n%s",line); #endif if (serverPort) { serverPort->callBack = callBack; serverPort->callBackData = callBackData; } return(serverPort); } int MCCIIsThereInput(serverPort) /* return 1 on true, 0 on false */ MCCIPort serverPort; { if (!serverPort) return(0); if (!MCCIIsConnected(serverPort)) { return(0); } return(NetIsThereInput(serverPort)); } int MCCISendAnchor(serverPort,status,callBack,callBackData) /*************************************************************************** * MCCISendAnchor - tell browser to send anchor history * status - 0, MCCI_SEND_BEFORE, or MCCI_SEND_AFTER * 0 disables SendAnchor * MCCI_SEND_BEFORE, instructs the server to * send the anchor before the browser finishes * pulling down the URL. * MCCI_SEND_AFTER, instruts the server to * send the anchor after the browser finishes * pulling down the URL. * callBack - Routine that should be called back upon * anchor hits from browser. This function is * defined as: * * void callBack(char *anchor, void *callBackData) * * callBackData - data to be passed back to callBack routine * ***************************************************************************/ MCCIPort serverPort; int status; void (*callBack)(); void *callBackData; { char buff[80]; int length; int lengthToSend; AnchorCallBack *a; int notFound; char *line; if (!serverPort) { return(MCCI_FAIL); } if (!MCCIIsConnected(serverPort)) { return(MCCI_NETWORK_ERROR); } if (status) { /* create memory before sending request in case of failure */ if (!(a = (AnchorCallBack *) MALLOC(sizeof(AnchorCallBack)))) { return(MCCI_OUTOFMEMORY); } if (status == MCCI_SEND_BEFORE) { /* ejb 9 March 1995 */ sprintf(buff, "%s %s %s\r\n", MCCI_S_SEND, MCCI_S_ANCHOR, MCCI_S_BEFORE); } else { /* defaults to send after, backwards compatible. */ sprintf(buff, "%s %s %s\r\n", MCCI_S_SEND, MCCI_S_ANCHOR, MCCI_S_AFTER); } lengthToSend = strlen((char *)buff); length = MCCIWrite(serverPort, buff, lengthToSend); if (length != lengthToSend) { /* error sending */ FREE(a); return(MCCI_FAIL); } /* add to callback list */ if (callBack) { a->serverPort = serverPort; a->callBack = callBack; a->callBackData = callBackData; ListAddEntry(anchorCBList,a); } else { FREE(a); } } else { sprintf(buff, "%s %s %s\r\n", MCCI_S_SEND, MCCI_S_ANCHOR, MCCI_S_STOP); lengthToSend = strlen((char *)buff); length = MCCIWrite(serverPort, buff, lengthToSend); if (length != lengthToSend) { /* error sending */ return(MCCI_FAIL); } /* remove from callback list */ a = (AnchorCallBack *) ListHead(anchorCBList); while (a) { if (a->serverPort == serverPort) { if (callBack) { if (callBack == a->callBack) { ListDeleteEntry(anchorCBList,a); } } else { ListDeleteEntry(anchorCBList,a); } a = (AnchorCallBack *)ListCurrent(anchorCBList); } else { a = (AnchorCallBack *) ListNext(anchorCBList); } } } line = MCCIGetResponse(serverPort); #ifdef DEBUG printf("SEND ANCHOR reply: %s\n",line); #endif if (!line) { return(MCCI_NETWORK_ERROR); } if (line[0]=='2') { return(MCCI_OK); } else { return(MCCI_REQUEST_FAIL); } } int MCCIGet(serverPort,uri,output,absRelative,additionalHeader) /*************************************************************************** * MCCIGet - Resolve a URL * uri - the URL to be resolved * output - where should the output go? * MCCI_DEFAULT - same as OUTPUT_CURRENT * MCCI_OUTPUT_NONE - Browser shouldn't display * MCCI_OUTPUT_CURRENT - Browser should display in current * MCCI_OUTPUT_NEW - Browser should display in new window * absRelative - url should be treated as either a relative or * or absolute link to the current document * MCCI_DEFAULT - set to absolute * MCCI_ABSOLUTE * MCCI_RELATIVE * additionalHeader - This is a string containing additional HTTP * header information to pass to the server. If this is * a standard HTTP GET, this field should be set to NULL. * Example: * MCCIGet(port,"http://host/file",0,MCCI_ABSOLUTE,0); ***************************************************************************/ MCCIPort serverPort; char *uri; int output; int absRelative; char *additionalHeader; { char *buff; char buff2[80]; int length,lengthToSend; char *line; int approxSize; if (!serverPort) { return(MCCI_FAIL); } if (!MCCIIsConnected(serverPort)) { return(MCCI_NETWORK_ERROR); } approxSize = 256; if (!uri) { /* required parameter */ return(MCCI_FAIL); } else { approxSize += strlen(uri); } if (additionalHeader) { approxSize += strlen(additionalHeader); } if (!(buff = (char *) MALLOC(approxSize))) { /* memory problems */ return(MCCI_OUTOFMEMORY); } sprintf(buff,"GET URL <%s>",uri); switch (output) { case MCCI_OUTPUT_NONE: strcat(buff," OUTPUT NONE"); break; case MCCI_OUTPUT_NEW: strcat(buff," OUTPUT NEW"); break; case MCCI_OUTPUT_CURRENT: default: strcat(buff," OUTPUT CURRENT"); break; } /* switch (absRelative) { case MCCI_RELATIVE: strcat(buff," RELATIVE"); break; case MCCI_ABSOLUTE: default: strcat(buff," ABSOLUTE"); break; } */ if (additionalHeader) { strcat(buff," HEADER\r\n"); sprintf(buff2,"Content-Length: %d\r\n", strlen(additionalHeader)); strcat(buff,buff2); strcat(buff,additionalHeader); } else { strcat(buff,"\r\n"); } lengthToSend = strlen(buff); length = MCCIWrite(serverPort, buff, lengthToSend); FREE(buff); if (length != lengthToSend) { /* error sending */ return(MCCI_FAIL); } /* get server response */ line = MCCIGetResponse(serverPort); #ifdef DEBUG printf("GET reply: %s\n",line); #endif if (!line) { return(MCCI_NETWORK_ERROR); } if (line[0]=='2') { return(MCCI_OK); } else { return(MCCI_REQUEST_FAIL); } } int MCCISendOutputStop(serverPort,mimeType) MCCIPort serverPort; char *mimeType; { char buff[128]; int length,lengthToSend; char *line; OutputCallBack *outCB; if (!serverPort) { return(MCCI_FAIL); } if (!MCCIIsConnected(serverPort)) { return(MCCI_NETWORK_ERROR); } sprintf(buff,"%s %s %s %s %s\r\n", MCCI_S_SEND, MCCI_S_OUTPUT, MCCI_S_STOP, mimeType,NetReturnAddress(serverPort)); lengthToSend = strlen(buff); length = MCCIWrite(serverPort, buff, lengthToSend); if (length != lengthToSend) { /* error sending */ return(MCCI_FAIL); } /* get server response */ line = MCCIGetResponse(serverPort); #ifdef DEBUG printf("SEND OUTPUT STOP reply: %s\n",line); #endif /* remove call back from list */ outCB = (OutputCallBack *)ListHead(outputCBList); while (outCB) { if ((outCB->serverPort == serverPort) && (!(strcmp(mimeType,outCB->type)))) { ListDeleteEntry(outputCBList,outCB); FREE(outCB->type); FREE(outCB); outCB = (OutputCallBack *) ListCurrent(outputCBList); } else { outCB = (OutputCallBack *) ListNext(outputCBList); } } if (!line) { return(MCCI_NETWORK_ERROR); } if (line[0]=='2') { return(MCCI_OK); } else { return(MCCI_REQUEST_FAIL); } } int MCCISendOutput(serverPort,mimeType,callBack,callBackData) /* Tell Mosaic to send output of type mimeType * When Mosaic sends this type of data, the cci client may be notified by * the callback. The callback is of the form: * * void SendOuputCallBack(char *mimeType,char *data,int length, * void *callBackData); * * The cci client is repsonsible for freeing the area allocated in the * data field. */ MCCIPort serverPort; char *mimeType; void (*callBack)(); void *callBackData; { char buff[128]; int length,lengthToSend; char *line; OutputCallBack *outCB; if (!serverPort) { return(MCCI_FAIL); } if (!MCCIIsConnected(serverPort)) { return(MCCI_NETWORK_ERROR); } if (!(outCB = (OutputCallBack *) MALLOC( sizeof(OutputCallBack)))) { return(MCCI_OUTOFMEMORY); } sprintf(buff,"%s %s %s TO %s\r\n", MCCI_S_SEND,MCCI_S_OUTPUT, mimeType, NetReturnAddress(serverPort)); lengthToSend = strlen(buff); length = MCCIWrite(serverPort, buff, lengthToSend); if (length != lengthToSend) { /* error sending */ FREE(outCB); return(MCCI_FAIL); } outCB->serverPort = serverPort; outCB->type = strdup(mimeType); outCB->callBack = callBack; outCB->callBackData = callBackData; ListAddEntry(outputCBList,outCB); /* get server response */ line = MCCIGetResponse(serverPort); #ifdef DEBUG printf("SEND OUTPUT reply: %s\n",line); #endif if (!line) { return(MCCI_NETWORK_ERROR); } if (line[0]=='2') { return(MCCI_OK); } else { return(MCCI_REQUEST_FAIL); } } int MCCIDisconnect(serverPort) MCCIPort serverPort; { char buff[80]; int length,lengthToSend; char *line; AnchorCallBack *a; OutputCallBack *outCB; BrowserViewCallBack *bvCB; if (!serverPort) { return(MCCI_FAIL); } if (!MCCIIsConnected(serverPort)) { return(MCCI_NETWORK_ERROR); } /* This routine could be called due to an error... besides, notify the server is redundant. sprintf(buff,"%s\r\n",MCCI_S_DISCONNECT); lengthToSend = strlen(buff); length = MCCIWrite(serverPort, buff, lengthToSend); if (length != lengthToSend) { return(MCCI_FAIL); } */ NetCloseConnection(serverPort); /* remove any anchor callbacks on this port */ a = (AnchorCallBack *) ListHead(anchorCBList); while (a) { if (a->serverPort == serverPort) { ListDeleteEntry(anchorCBList,a); FREE(a); a = (AnchorCallBack *) ListCurrent(anchorCBList); } else { a = (AnchorCallBack *) ListNext(anchorCBList); } } /* remove any send output callbacks on this port */ outCB = (OutputCallBack *) ListHead(outputCBList); while(outCB) { if (outCB->serverPort == serverPort) { ListDeleteEntry(outputCBList,outCB); FREE(outCB->type); FREE(outCB); outCB = (OutputCallBack *) ListCurrent(outputCBList); } else { outCB = (OutputCallBack *) ListNext(outputCBList); } } bvCB = (BrowserViewCallBack *) ListHead(browserViewCBList); while(bvCB) { if (bvCB->serverPort == serverPort) { ListDeleteEntry(browserViewCBList,bvCB); FREE(bvCB); bvCB = (BrowserViewCallBack *) ListCurrent(browserViewCBList); } else { bvCB = (BrowserViewCallBack*) ListNext(browserViewCBList); } } /* call close connection callback */ if (serverPort->callBack) { (void) (serverPort->callBack)(serverPort, serverPort->callBackData); } return(MCCI_OK); } int MCCINBGet(serverPort,uri,output,absRelative,additionalHeader) /*************************************************************************** * MCCIGet - Resolve a URL * uri - the URL to be resolved * output - where should the output go? * MCCI_DEFAULT - same as OUTPUT_CURRENT * MCCI_OUTPUT_NONE - Browser shouldn't display * MCCI_OUTPUT_CURRENT - Browser should display in current * MCCI_OUTPUT_NEW - Browser should display in new window * absRelative - url should be treated as either a relative or * or absolute link to the current document * MCCI_DEFAULT - set to absolute * MCCI_ABSOLUTE * MCCI_RELATIVE * additionalHeader - This is a string containing additional HTTP * header information to pass to the server. If this is * a standard HTTP GET, this field should be set to NULL. * Example: * MCCINBGet(port,"http://host/file",0,MCCI_ABSOLUTE,0); ***************************************************************************/ MCCIPort serverPort; char *uri; int output; int absRelative; char *additionalHeader; { char *buff; char buff2[80]; int length,lengthToSend; char *line; int approxSize; if (!serverPort) { return(MCCI_FAIL); } if (!MCCIIsConnected(serverPort)) { return(MCCI_NETWORK_ERROR); } approxSize = 256; if (!uri) { /* required parameter */ return(MCCI_FAIL); } else { approxSize += strlen(uri); } if (additionalHeader) { approxSize += strlen(additionalHeader); } if (!(buff = (char *) MALLOC(approxSize))) { /* memory problems */ return(MCCI_OUTOFMEMORY); } sprintf(buff,"GET URL <%s>",uri); switch (output) { case MCCI_OUTPUT_NONE: strcat(buff," OUTPUT NONE"); break; case MCCI_OUTPUT_NEW: strcat(buff," OUTPUT NEW"); break; case MCCI_OUTPUT_CURRENT: default: strcat(buff," OUTPUT CURRENT"); break; } /* switch (absRelative) { case MCCI_RELATIVE: strcat(buff," RELATIVE"); break; case MCCI_ABSOLUTE: default: strcat(buff," ABSOLUTE"); break; } */ if (additionalHeader) { strcat(buff," HEADER\r\n"); sprintf(buff2,"Content-Length: %d\r\n", strlen(additionalHeader)); strcat(buff,buff2); strcat(buff,additionalHeader); } else { strcat(buff,"\r\n"); } lengthToSend = strlen(buff); length = MCCIWrite(serverPort, buff, lengthToSend); FREE(buff); if (length != lengthToSend) { /* error sending */ return(MCCI_FAIL); } return(MCCI_OK); } int MCCIPost(serverPort,url,contentType,data,dataLength,output) /*************************************************************************** * MCCIPost- Post data to an HTTP server * url - the URL to be resolved * contentType: MIME type for data * data - the data to be posted to the HTTP server * dataLength - Length of the above data * output - where should the output go? * MCCI_DEFAULT - same as OUTPUT_CURRENT * MCCI_OUTPUT_NONE - Browser shouldn't display * MCCI_OUTPUT_CURRENT - Browser should display in current * MCCI_OUTPUT_NEW - Browser should display in new window */ MCCIPort serverPort; char *url; char *contentType; char *data; int dataLength; int output; { char *line; char *buff; int lengthToSend; int length; if (!serverPort) { return(MCCI_FAIL); } if (!MCCIIsConnected(serverPort)) { return(MCCI_NETWORK_ERROR); } if (!(buff = (char *) MALLOC(strlen(url) + 256))) { return(MCCI_OUTOFMEMORY); } sprintf(buff, "%s <%s> %s", MCCI_S_POST, url, contentType); switch(output) { case MCCI_OUTPUT_NEW: strcat(buff," OUTPUT NEW"); break; case MCCI_OUTPUT_NONE: strcat(buff," OUTPUT NONE"); break; case MCCI_OUTPUT_CURRENT: case MCCI_DEFAULT: strcat(buff," OUTPUT CURRENT"); break; } strcat(buff,"\r\n"); lengthToSend = strlen(buff); length = MCCIWrite(serverPort, buff, lengthToSend); if (length != lengthToSend) { return(MCCI_FAIL); } #ifdef DEBUG printf("Post Request: %s",buff); #endif sprintf(buff, "Content-Length: %d \r\n",dataLength); lengthToSend = strlen(buff); length = MCCIWrite(serverPort, buff, lengthToSend); if (length != lengthToSend) { return(MCCI_FAIL); } length = MCCIWrite(serverPort, data, dataLength); if (length != dataLength) { return(MCCI_FAIL); } #ifdef DEBUG printf("%s%s\n",buff,data); #endif /* get server response */ line = MCCIGetResponse(serverPort); #ifdef DEBUG printf("POST reply: %s\n",line); #endif free(buff); if (!line) { return(MCCI_NETWORK_ERROR); } if (line[0]=='2') { return(MCCI_OK); } else { return(MCCI_REQUEST_FAIL); } } /* MCCIPost() */ int MCCISendBrowserView(serverPort,status,callBack,callBackData) /*************************************************************************** * MCCISendBrowserView()- This routine requests the web browser to send * a copy of what would normally be displayed in the browser * window. This typically includes text/html and any inline * images. The callbacks are called as data comes in. * status: 1 to turn on, 0 turn off. * * The call back is of the form: * * * void SendBrowserViewCallBack(char *url, char *mimeType, * char *data, int dataLength, * void *callBackData) */ MCCIPort serverPort; int status; void (*callBack)(); void *callBackData; { char *line; char buff[80]; int lengthToSend; int length; BrowserViewCallBack *bvcb; if (!serverPort) { return(MCCI_FAIL); } if (!MCCIIsConnected(serverPort)) { return(MCCI_NETWORK_ERROR); } if (status) { sprintf(buff,"%s %s\r\n",MCCI_S_SEND, MCCI_S_BROWSERVIEW); } else { sprintf(buff,"%s %s %s\r\n",MCCI_S_SEND, MCCI_S_BROWSERVIEW, MCCI_S_STOP); } lengthToSend = strlen(buff); length = MCCIWrite(serverPort, buff, lengthToSend); if (length != lengthToSend) { return(MCCI_FAIL); } if (!status) { /* remove the callback from callback list */ bvcb = (BrowserViewCallBack *) ListHead(browserViewCBList); while(bvcb) { if ((bvcb->serverPort == serverPort) && (bvcb->callBack == callBack) && (bvcb->callBackData == callBackData)) { ListDeleteEntry(browserViewCBList,bvcb); bvcb = (BrowserViewCallBack *) ListCurrent(browserViewCBList); } else { bvcb = (BrowserViewCallBack *) ListNext(browserViewCBList); } } } else { /* add callback to callback list */ if (!(bvcb = (BrowserViewCallBack *) MALLOC(sizeof(BrowserViewCallBack)))) { return(MCCI_OUTOFMEMORY); } bvcb->serverPort = serverPort; bvcb->callBack = callBack; bvcb->callBackData = callBackData; ListAddEntry(browserViewCBList,bvcb); } /* get response from browser */ line = MCCIGetResponse(serverPort); #ifdef DEBUG printf("SEND BROWSERVIEW reply: %s\n",line); #endif if (!line) { return(MCCI_NETWORK_ERROR); } if (line[0]=='2') { return(MCCI_OK); } else { return(MCCI_REQUEST_FAIL); } }