This repository has been archived on 2024-01-04. You can view files and clone it, but cannot push or open issues or pull requests.
ncsa-mosaic/src/cciBindings2.c

1117 lines
29 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 <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "mosaic.h"
#include "gui.h"
#include "cci.h"
#include "cciBindings2.h"
#include <X11/Intrinsic.h>
#include "cciServer.h"
#include "list.h"
#include "memStuffForPipSqueeks.h"
#include <libutils/flatpakCheck.h>
#include "libwww2/HTFormat.h"
static Boolean cciAccepting = 0;
static int listenPortNumber=0;
static XtInputId connectInputID;
static List listOfConnections;
static List listOfSendOutput;
static List listOfSendAnchorTo; /* client in list if should receive */
static List listOfSendBrowserView;
static List listOfSendEvent;
static List listOfFileToURLs;
static List listOfForm; /* list of form submitted by application */
/* ADC ugly hack below ZZZZZ */
extern int CCIprotocol_handler_found;
extern int MCCIanchorcached;
extern XtAppContext app_context;
/***/ extern HTStream* CCIPresent();
extern char *machine_with_domain; /* host name */
/* from cciBindings.c */
extern int cci_event;
#ifndef DISABLE_TRACE
extern int cciTrace;
#endif
struct Connection {
XtInputId inputId;
MCCIPort client;
};
struct SendWhatToWhom {
MCCIPort client;
char *contentType;
};
struct FileURL {
char *fileName;
char *url;
};
struct FormSubmit{
MCCIPort client;
char *actionID;
int valid;
};
cciStat *cciStatListFindEntry(MCCIPort findMe)
{
/* this finds an entry in listOfSendAnchorTo based on MCCIPort client. */
cciStat *current;
char notDone = 1;
current = (cciStat *) ListHead(listOfSendAnchorTo);
while (notDone)
{
if ((current == NULL) || (current->client == findMe))
notDone = 0;
else
current = (cciStat *) ListNext(listOfSendAnchorTo);
}
return current;
}
cciStat *cciStatListDeleteEntry(MCCIPort deleteMe)
{
cciStat *current;
if (current = cciStatListFindEntry(deleteMe))
{
ListDeleteEntry(listOfSendAnchorTo,current);
return current;
}
else
return NULL;
}
void cciStatPreventSendAnchor(MCCIPort client, char *url)
{
/* this sets the flag that is checked for in cciSafeToSend, but
* only if sendAnchor is on for this client.
*/
cciStat *current;
if ((current = cciStatListFindEntry(client)) && (url != NULL))
current->url = strdup(url);
}
int cciSafeToSend(cciStat *current, char *url)
{
/* ensures that Mosaic does not send an ANCHOR in response to a GET
* if SEND ANCHOR is turned on.
*
* INPUTS:
* url The url for which the flag is to be set.
* RETURNS:
* returns 0 if flag set for (client,url) pair (not safe to send)
* 1 if flag is not set for (client,url) pair
* (safe to send)
*/
int rc = 1;
if (current->url != NULL)
{
rc = strcmp(url,current->url);
free(current->url);
current->url = NULL;
}
return rc;
}
void cciStatFree(cciStat *i)
{
free(i);
}
cciStat *cciStatNew(MCCIPort client, int status)
{
cciStat *new;
new = (cciStat *) malloc( sizeof(cciStat) );
if (new)
{
new->client = client;
new->status = status;
new->url = NULL;
}
return new;
}
void MoCCISendAnchor(client,sendIt)
/* set the state of sending anchors */
MCCIPort client;
int sendIt; /* 0, don't send, 1 send before browser gets document, */
/* 2 send after browser gets document */
/* 3 send it before and then let the CCI app handle it ADC ZZZ */
{
cciStat *statElt;
statElt = cciStatListDeleteEntry(client);
switch (sendIt)
{
case 0:
if (statElt)
cciStatFree(statElt);
break;
case 1: /* send before browser gets document */
if (statElt)
statElt->status = 1;
else
statElt = cciStatNew(client,1);
if (statElt)
ListAddEntry(listOfSendAnchorTo,statElt);
break;
case 2: /* send after browser gets document */
if (statElt)
statElt->status = 2;
else
statElt = cciStatNew(client,2);
if (statElt)
ListAddEntry(listOfSendAnchorTo,statElt);
break;
case 3: /* send before browser gets document, then let it handle it ADC ZZZ */
if (statElt)
statElt->status = 3;
else
statElt = cciStatNew(client,3);
if (statElt)
ListAddEntry(listOfSendAnchorTo,statElt);
break;
default:
;
}
}
void MoCCISendAnchorToCCI(url, beforeAfter)
char *url;
int beforeAfter;
/***************************************************************
* beforeAfter - 0: send to all clients in list
* 1: send to all clients with status == 1;
* 2: send to all clients with status == 2:
* 3: send to all clients with status == 3: ADC ZZZ
***************************************************************/
{
cciStat *client;
client = (cciStat *) ListHead(listOfSendAnchorTo);
while(client)
{
if (cciSafeToSend(client, url)) /* test flag */
switch (beforeAfter)
{
case 0:
if (client->status == 3) { /* ADC ZZZ */
MCCIanchorcached = 1;
MCCISendAnchorHistory(client->client,url);
MCCIanchorcached = 0;
}
else
MCCISendAnchorHistory(client->client,url);
break;
case 1:
if (client->status == 1)
MCCISendAnchorHistory(client->client,url);
break;
case 2:
if (client->status == 2)
MCCISendAnchorHistory(client->client,url);
case 3: /* ADC ZZZ */
if (client->status == 3)
MCCISendAnchorHistory(client->client,url);
CCIprotocol_handler_found = 1;
break;
default:
;
}
client = (cciStat *) ListNext(listOfSendAnchorTo);
}
}
void MoCCISendEvent(client,on)
MCCIPort client;
int on;
{
MCCIPort tmp;
if (on) {
ListAddEntry(listOfSendEvent,client);
}
else {
ListDeleteEntry(listOfSendEvent,client);
/* turn off cci_event only if list of clients is NULL */
if (!(tmp = (MCCIPort) ListHead(listOfSendEvent)))
cci_event = 0;
}
}
void MoCCISendMouseAnchor(client,on)
MCCIPort client;
int on;
{
MCCIPort tmp;
if (on) {
ListAddEntry(listOfSendEvent,client);
}
else {
ListDeleteEntry(listOfSendEvent,client);
/* turn off cci_event only if list of clients is NULL */
if (!(tmp = (MCCIPort) ListHead(listOfSendEvent)))
cci_event = 0;
}
}
void MoCCISendBrowserView(client,on)
MCCIPort client;
int on;
{
if (on) {
ListAddEntry(listOfSendBrowserView,client);
}
else {
ListDeleteEntry(listOfSendBrowserView,client);
}
}
void MoCCIForm(client, actionID, status,close_connection)
MCCIPort client;
char *actionID;
int status;
int close_connection;
{
struct FormSubmit *sendForm;
int registered = 0;
if (status){
sendForm = (struct FormSubmit *) ListHead(listOfForm);
while (sendForm){
if ((sendForm->client == client) &&
(!strcmp(sendForm->actionID,actionID))) {
sendForm->valid = 1;
registered = 1;
}
sendForm = (struct FormSubmit *)ListNext(listOfForm);
}
/* only register if not done so alreday */
if (!registered){
if (!(sendForm = (struct FormSubmit *)
MALLOC(sizeof(struct FormSubmit)))) {
return; /* mem problem */
}
sendForm->client = client;
sendForm->actionID = strdup(actionID);
sendForm->valid = 1;
ListAddEntry(listOfForm, sendForm);
}
}
else if (close_connection)
{
sendForm = (struct FormSubmit *) ListHead(listOfForm);
while(sendForm){
if (sendForm->client == client) {
ListDeleteEntry(listOfForm, sendForm);
FREE(sendForm->actionID);
FREE(sendForm);
sendForm = (struct FormSubmit *)
ListCurrent(listOfForm);
#if 0
sendForm->valid = 0;
#endif
}
else{
sendForm = (struct FormSubmit *)
ListNext(listOfForm);
}
}
}
else{ /* remove entry from list, forget the valid bit, delete it!! */
sendForm = (struct FormSubmit *) ListHead(listOfForm);
while(sendForm){
if ((sendForm->client == client) &&
(!strcmp(sendForm->actionID,actionID))){
ListDeleteEntry(listOfForm, sendForm);
FREE(sendForm->actionID);
FREE(sendForm);
sendForm = (struct FormSubmit *)
ListCurrent(listOfForm);
#if 0
sendForm->valid = 0;
#endif
}
else{
sendForm = (struct FormSubmit *)
ListNext(listOfForm);
}
}
}
#ifndef DISABLE_TRACE
if (cciTrace) {
sendForm = (struct FormSubmit *) ListHead(listOfForm);
fprintf(stderr,"***** begin mosaic list *****\n");
while(sendForm){
fprintf(stderr,"actionID %s\n",sendForm->actionID);
fprintf(stderr,"clientaddress %s\n",sendForm->client->serverAddress);
sendForm = (struct FormSubmit *) ListNext(listOfForm);
}
}
#endif
}
int MoCCIPreInitialize()
{
static int donePreInit = 0;
if (donePreInit) {
return 0;
}
donePreInit = 1;
listOfConnections = ListCreate();
listOfSendOutput = ListCreate();
listOfSendAnchorTo = ListCreate();
listOfSendBrowserView = ListCreate();
listOfSendEvent = ListCreate();
listOfFileToURLs = ListCreate();
listOfForm = ListCreate();
}
int MoCCIInitialize(portNumber)
int portNumber;
{
int retVal;
MoCCIPreInitialize();
retVal = MCCIServerInitialize(portNumber);
if (retVal) {
/* Write port number to .mosaiccciport */
char *home = flatpakCheck(), *fnam;
FILE *fp;
if (!home)
home = "/tmp";
fnam = (char *)malloc (strlen (home) + 32);
sprintf (fnam, "%s/cciport", home); // SAM
fp = fopen (fnam, "w");
if (fp) {
fprintf(fp,"%s:%d\n",machine_with_domain,portNumber);
fclose (fp);
}
free (fnam);
}
return(retVal);
}
int MoCCITerminateAllConnections()
{
struct Connection *con;
struct SendWhatToWhom *sendOutput;
con = (struct Connection *) ListHead(listOfConnections);
while(con) {
XtRemoveInput(con->inputId);
NetCloseConnection(con->client);
MoCCISendAnchor(con->client,0);
MoCCISendBrowserView(con->client,0);
MoCCISendEvent(con->client, 0);
MoCCIForm(con->client, NULL, 0, 1);
sendOutput=(struct SendWhatToWhom *)ListHead(listOfSendOutput);
while(sendOutput){ /* remove sendOutputs */
HTRemoveConversion(sendOutput->contentType,
"www/present",CCIPresent);
ListDeleteEntry(listOfSendOutput,sendOutput);
FREE(sendOutput->contentType);
FREE(sendOutput);
sendOutput = (struct SendWhatToWhom *)
ListCurrent(listOfSendOutput);
}
ListDeleteEntry(listOfConnections,con);
con = (struct Connection *) ListHead(listOfConnections);
}
}
int MoCCITerminateAConnection(client)
MCCIPort client;
{
struct Connection *con;
struct SendWhatToWhom *sendOutput;
con = (struct Connection *) ListHead(listOfConnections);
while(con) {
if (con->client == client) {
XtRemoveInput(con->inputId);
MoCCISendAnchor(con->client,0);
MoCCISendBrowserView(con->client,0);
MoCCISendEvent(con->client, 0);
MoCCIForm(con->client, NULL, 0, 1);
sendOutput=(struct SendWhatToWhom *)
ListHead(listOfSendOutput);
while(sendOutput){ /* remove sendOutputs */
if(sendOutput->client == client){
HTRemoveConversion(sendOutput->contentType,
"www/present",CCIPresent);
ListDeleteEntry(listOfSendOutput,sendOutput);
FREE(sendOutput->contentType);
FREE(sendOutput);
}
sendOutput = (struct SendWhatToWhom *)
ListNext(listOfSendOutput);
}
ListDeleteEntry(listOfConnections,con);
con = (struct Connection *)
ListCurrent(listOfConnections);
}
else {
con = (struct Connection *) ListNext(listOfConnections);
}
}
}
void MoCCIHandleInput(client,source)
MCCIPort client;
int source;
{
if (MCCIIsThereInput(client)) {
MCCIHandleInput(client);
}
}
void MoCCINewConnection(app_context,source,inputID)
XtAppContext app_context;
int *source;
XtInputId *inputID;
{
MCCIPort client;
struct Connection *con;
#ifndef DISABLE_TRACE
if (cciTrace) {
fprintf(stderr,"MoCCINewConnection(): I've been called\n");
}
#endif
client = MCCICheckAndAcceptConnection();
if (!client) {
/* nothing here */
return;
}
#ifndef DISABLE_TRACE
if (cciTrace) {
fprintf(stderr,"Mosaic: got a CCI connection\n");
}
#endif
/*
this determines wether there is one or many cci clients connecting
XtRemoveInput(*inputID);
*/
MCCISendResponseLine(client,MCCIR_OK,"VERSION 01 X Mosaic 2.7b5");
con = (struct Connection *) malloc(sizeof(struct Connection));
con->client = client;
con->inputId = XtAppAddInput(app_context,
MCCIGetSocketDescriptor(client),
(XtPointer) XtInputReadMask,
(XtInputCallbackProc) MoCCIHandleInput, (XtPointer) client);
ListAddEntry(listOfConnections,con);
}
static XmxCallback (MoCCIWindowCallBack)
{
Boolean newState;
mo_window *win = mo_fetch_window_by_id (XmxExtractUniqid ((int)client_data));
int newPort;
char *portString;
char buff[256];
newState = cciAccepting;
switch (XmxExtractToken ((int)client_data)) {
case 0: /*ok*/
newState = XmToggleButtonGetState(win->cci_accept_toggle);
XtUnmanageChild(win->cci_win);
break;
case 1: /*Cancel*/
if (cciAccepting != XmToggleButtonGetState
(win->cci_accept_toggle)) {
/* reset toggle state */
XmxSetToggleButton(win->cci_accept_toggle,
cciAccepting);
XmxSetToggleButton(win->cci_off_toggle,
!cciAccepting);
}
XtUnmanageChild(win->cci_win);
break;
case 2: /*Help*/
mo_open_another_window (win,
mo_assemble_help_url("docview-menubar-file.html#open"),
NULL, NULL);
break;
}
if (newState != cciAccepting) {
/* toggle state has changed */
cciAccepting = newState;
if (cciAccepting) {
newPort = 0;
portString= XmxTextGetString (win->cci_win_text);
if (portString) {
newPort = atoi(portString);
}
if ((newPort < 1024) || (newPort > 65535)) {
XmxMakeErrorDialog (win->cci_win,
"CCI port address must be between 1024 and 65535" ,
"CCI port address error" );
XtManageChild (Xmx_w);
cciAccepting = False;
listenPortNumber = 0;
XmxSetToggleButton(win->cci_accept_toggle,
cciAccepting);
XmxSetToggleButton(win->cci_off_toggle,
!cciAccepting);
return;
}
if (MoCCIInitialize(newPort)) {
listenPortNumber = newPort;
connectInputID = XtAppAddInput(app_context,
MCCIReturnListenPortSocketDescriptor(),
(XtPointer) XtInputReadMask,
(XtInputCallbackProc) MoCCINewConnection,
app_context);
sprintf(buff,"%s %d","CCI Now listening on port" ,newPort);
XmxMakeInfoDialog(win->cci_win,buff,"CCI port status" );
XtManageChild(Xmx_w);
}
else {
cciAccepting = False;
listenPortNumber = 0;
XmxSetToggleButton(win->cci_accept_toggle,
cciAccepting);
XmxSetToggleButton(win->cci_off_toggle,
!cciAccepting);
/* Can't accept on this port...*/
XmxMakeErrorDialog (win->cci_win,
"CCI Can't accept requests on this port. May be in use already." ,
"CCI port address error" );
XtManageChild(Xmx_w);
}
}
else {
XtRemoveInput(connectInputID); /* stop accepting connections*/
MCCICloseAcceptPort(); /* kill accept port */
/* terminate existing connections */
MoCCITerminateAllConnections();
listenPortNumber = 0;
sprintf(buff,"CCI Is no longer listening");
XmxMakeInfoDialog(win->cci_win, buff,"CCI port status");
XtManageChild(Xmx_w);
}
}
}
mo_status MoDisplayCCIWindow(win)
mo_window *win;
{
Widget dialogFrame;
Widget dialogSeparator;
/*Widget buttonsForm;*/
Widget cciForm,label;
Widget toggleBox;
Widget buttonBox;
if (!win->cci_win) {
XmxSetUniqid (win->id);
win->cci_win = XmxMakeFormDialog(win->base,
"NCSA Mosaic: Common Client Interface" );
dialogFrame = XmxMakeFrame(win->cci_win, XmxShadowOut);
XmxSetConstraints
(dialogFrame, XmATTACH_FORM, XmATTACH_FORM,
XmATTACH_FORM, XmATTACH_FORM, NULL, NULL, NULL, NULL);
/* Main form. */
cciForm = XmxMakeForm(dialogFrame);
label = XmxMakeLabel(cciForm, "CCI Port Address: " );
XmxSetArg(XmNcolumns, 25);
win->cci_win_text= XmxMakeText (cciForm);
XmxAddCallbackToText (win->cci_win_text,
MoCCIWindowCallBack, 0);
toggleBox = XmxMakeRadioBox(cciForm);
win->cci_accept_toggle = XmxMakeToggleButton
(toggleBox, "Accept requests" , NULL, 0);
win->cci_off_toggle = XmxMakeToggleButton
(toggleBox, "Interface off" , NULL, 0);
dialogSeparator= XmxMakeHorizontalSeparator(cciForm);
buttonBox = XmxMakeFormAndThreeButtons(cciForm,
MoCCIWindowCallBack,
"Ok" ,
"Dismiss" ,
"Help..." ,
0,1,2);
XmxSetOffsets (label, 13, 0, 10, 0);
XmxSetConstraints
(label, XmATTACH_FORM, XmATTACH_NONE,
XmATTACH_FORM, XmATTACH_NONE, NULL, NULL, NULL, NULL);
XmxSetOffsets (win->cci_win_text, 10, 0, 5, 8);
XmxSetConstraints
(win->cci_win_text, XmATTACH_FORM, XmATTACH_NONE,
XmATTACH_WIDGET,
XmATTACH_FORM, NULL, NULL, label, NULL);
XmxSetConstraints (toggleBox, XmATTACH_WIDGET,
XmATTACH_NONE, XmATTACH_WIDGET, XmATTACH_NONE,
win->cci_win_text, NULL, label, NULL);
XmxSetOffsets (toggleBox, 8, 0, 2, 0);
XmxSetConstraints (dialogSeparator, XmATTACH_WIDGET,
XmATTACH_NONE, XmATTACH_FORM, XmATTACH_FORM,
toggleBox, NULL, NULL, NULL);
XmxSetConstraints (buttonBox, XmATTACH_WIDGET,
XmATTACH_FORM, XmATTACH_FORM, XmATTACH_FORM,
dialogSeparator, NULL, NULL, NULL);
}
if (cciAccepting) {
char buff[10];
sprintf(buff,"%d",listenPortNumber);
XmxTextSetString(win->cci_win_text,buff);
}
else {
XmxTextSetString(win->cci_win_text,"");
}
XmxSetToggleButton(win->cci_accept_toggle, cciAccepting);
XmxSetToggleButton(win->cci_off_toggle, !cciAccepting);
XmxManageRemanage (win->cci_win);
return mo_succeed;
}
void MoCCISendOutputToClient(contentType,fileName)
char *contentType; /* string name of data type */
char *fileName; /* data stored here */
{
struct SendWhatToWhom *sendOutput;
/* send data to all clients that registered for this content type*/
sendOutput=(struct SendWhatToWhom *)ListHead(listOfSendOutput);
while(sendOutput){
if (!strcmp(sendOutput->contentType,contentType)) {
#ifndef DISABLE_TRACE
if (cciTrace) {
fprintf(stderr,"Sending output through cci of type %s\n",
sendOutput->contentType);
}
#endif
/* prep data for sending here */
/* send it back to client */
MCCISendOutputFile(sendOutput->client,
contentType,fileName);
}
sendOutput=(struct SendWhatToWhom *)ListNext(listOfSendOutput);
}
return;
}
/* inorder to send content to application, mosaic must call this function
twice, the first to set the variable send, the second to do the actual
sending
*/
int MoCCIFormToClient(actionID, query, contentType, post_data, status)
char *actionID;
char *query;
char *contentType;
char *post_data;
int status;
{
static int send = 0;
struct FormSubmit *sendForm;
int found = 0;
/* just make a note that its a cciPOST */
if (status && (send == 0)) {
send = 1;
return(0);
}
if (send){
send = 0;
sendForm=(struct FormSubmit *) ListHead(listOfForm);
while(sendForm)
{
if ( !strcmp(actionID, sendForm->actionID))
/* found correct client */
{
if (sendForm->valid)
MCCIFormQueryToClient(sendForm->client,
actionID, query, contentType, post_data);
found = 1;
}
sendForm = (struct FormSubmit *)ListNext(listOfForm);
}
}
return found;
}
/* this function is a callback from the libwww2 Converter */
void MoCCISendOutput(MCCIPort client,Boolean sendIt,char *contentType)
{
struct SendWhatToWhom *sendOutput;
if (sendIt) {
if (!(sendOutput = (struct SendWhatToWhom *)
MALLOC(sizeof(struct SendWhatToWhom)))) {
return /*mem error*/;
}
sendOutput->client = client;
sendOutput->contentType = strdup(contentType);
ListAddEntry(listOfSendOutput,sendOutput);
/* set up call back for this content Type */
HTSetConversion(contentType,"www/present",CCIPresent,
1.0, 0.0, 0.0);
/*If we use this, out put a message like....sent to cci
*/
/** HTSetPresentation(contentType,MoCCISendOutputCB,
1.0, 0.0, 0.0);
*/
}
else {
sendOutput=(struct SendWhatToWhom *)ListHead(listOfSendOutput);
while(sendOutput){
if ((sendOutput->client == client) &&
(!strcmp(sendOutput->contentType,contentType))) {
HTRemoveConversion(contentType,
"www/present",CCIPresent);
ListDeleteEntry(listOfSendOutput,sendOutput);
FREE(sendOutput->contentType);
FREE(sendOutput);
sendOutput = (struct SendWhatToWhom *)
ListCurrent(listOfSendOutput);
}
else {
sendOutput = (struct SendWhatToWhom *)
ListNext(listOfSendOutput);
}
}
}
}
void MoCCIStartListening(w,port)
Widget w;
int port;
{
/*int listenPort;*/
if (MoCCIInitialize(port)) {
connectInputID = XtAppAddInput(app_context,
MCCIReturnListenPortSocketDescriptor(),
(XtPointer) XtInputReadMask,
(XtInputCallbackProc) MoCCINewConnection,
app_context);
cciAccepting = True;
listenPortNumber = port;
/*
XmxMakeInfoDialog(w,"Mosaic CCI port is listening",
"CCI port status");
XtManageChild(Xmx_w);
*/
}
else {
char buf[80];
sprintf(buf,"%s %d","Could not listen on port" ,port);
XmxMakeErrorDialog(w,buf,
"CCI Error" );
XtManageChild(Xmx_w);
}
}
void MoCCISendEventOutput(event_type)
/* Handle SendEventOutput if needed */
/* send Event data to all the clients that have requested it */
CCI_events event_type;
{
MCCIPort client;
client = (MCCIPort) ListHead(listOfSendEvent);
while (client) {
MCCISendEventOutput(client,event_type);
client = (MCCIPort) ListNext(listOfSendEvent);
}
}
void MoCCISendMouseAnchorOutput(anchor)
/* Handle SendMouseAnchorOutput if needed */
/* send MouseAnchor data to all the clients that have requested it */
char *anchor;
{
MCCIPort client;
client = (MCCIPort) ListHead(listOfSendEvent);
while (client) {
MCCISendMouseAnchorOutput(client,anchor);
client = (MCCIPort) ListNext(listOfSendEvent);
}
}
void MoCCISendBrowserViewOutput(url, contentType, data, dataLength)
/* Handle SendBrowserViewOutput if needed */
/* send BrowserView data to all the clients that have requested it */
char *url;
char *contentType;
char *data;
int dataLength;
{
MCCIPort client;
if (dataLength == 0) {
return;
}
if (!data) {
return;
}
if ((!url) || (!strlen(url))) {
return;
}
if ((!contentType) || (!strlen(contentType))) {
contentType = "unknown";
}
client = (MCCIPort) ListHead(listOfSendBrowserView);
while (client) {
MCCISendBrowserViewOutput(client,url,contentType,
data,dataLength);
client = (MCCIPort) ListNext(listOfSendBrowserView);
}
}
int MoCCISendBrowserViewFile(url, contentType, filename)
char *url;
char *contentType;
char *filename;
{
struct stat fileInfo;
FILE *fp;
char *data;
if (!ListHead(listOfSendBrowserView)) {
return(MCCI_OK);
}
if ((!filename) || (!strlen(filename))) {
return(MCCI_OK);
}
if ((!url) || (!strlen(url))) {
return(MCCI_OK);
}
if ((!contentType) || (!strlen(contentType))) {
contentType = "unknown";
}
if (stat(filename,&fileInfo)) { /* get the length of the file */
return(MCCI_FAIL);
}
if (!(fp = fopen(filename,"r"))) {
return(MCCI_FAIL);
}
if (!(data = (char *) malloc(fileInfo.st_size))) {
fclose(fp);
return(MCCI_OUTOFMEMORY);
}
if (fileInfo.st_size != fread(data,sizeof(char),fileInfo.st_size,fp)){
fclose(fp);
free(data);
return(MCCI_FAIL);
}
MoCCISendBrowserViewOutput(url, contentType, data, fileInfo.st_size);
free(data);
fclose(fp);
return(MCCI_OK);
}
int MoCCIMaxNumberOfConnectionsAllowed()
/* return number of connections allowed. This is set in the X resources.
* if it's zero, then treat it as unlimited.
*/
{
return(get_pref_int(eMAX_NUM_OF_CCI_CONNECTIONS));
}
int MoCCICurrentNumberOfConnections()
{
return(ListCount(listOfConnections));
}
void MoCCIAddFileURLToList(fileName,url)
/* this routine should be called each time a url has been down loaded
and stored as file. This routine adds the fileName,url pair to the
list for later query over cci by an external viewer (cci app).
*/
char *fileName;
char *url;
{
struct FileURL *fileURL;
#ifndef DISABLE_TRACE
if (cciTrace) {
fprintf(stderr,"MoCCIAddFileURLToList():fileName=\"%s\", url=\"%s\"\n",(fileName?fileName:"NULL"),(url?url:"NULL"));
}
#endif
if ((!fileName) || (!url)) {
return;
}
if (!(fileURL = (struct FileURL *) MALLOC(sizeof (struct FileURL)))) {
/* out of memory, just return */
return;
}
fileURL->fileName = strdup(fileName);
fileURL->url = strdup(url);
ListAddEntry(listOfFileToURLs,fileURL);
return;
}
char *MoReturnURLFromFileName(fileName)
/* given filename, return associated URL in the list */
/* if not found, return NULL */
char *fileName;
{
struct FileURL *fileURL;
fileURL = (struct FileURL *) ListHead(listOfFileToURLs);
while (fileURL){
if (!strncmp(fileURL->fileName,fileName,
strlen(fileURL->fileName))) {
return(fileURL->url);
}
fileURL = (struct FileURL *) ListNext(listOfFileToURLs);
}
return(NULL);
}
/* this rplaces a vanilla url name with the name it was actually called with,
which is what is needed by external apps. It is indeed a huge hack, and
should be fixed
*/
void MoCCIAddAnchorToURL(url, urlAndAnchor)
char *url;
char *urlAndAnchor;
{
struct FileURL *fileURL;
fileURL = (struct FileURL *) ListTail(listOfFileToURLs);
if (fileURL && !strcmp(fileURL->url, url)) {
free(fileURL->url);
fileURL->url = strdup(urlAndAnchor);
}
}