1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
|
/* nexsup.c--This is a 'support routine' used by the nedriv.f code, */
/* In brief, this is the main interface between the Fortran and */
/* C languages. It is called from Fortran and uses a UNIX socket */
/* to send messages to the PGPLOT viewer. */
/* 199-Feb-24 - update from nexsup.m - [AFT] */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <netdb.h>
#include <stdio.h>
int pgsock=-1;
struct sockaddr_in server;
#ifdef __STDC__
void grgetreply(int ifunc,int *ibuf,int *lbuf)
#else
void grgetreply(ifunc, ibuf, lbuf)
int ifunc;
int *ibuf;
int *lbuf;
#endif
{
/* Used by nexsup to send a message over the socket and wait */
/* for a reply back */
struct sockaddr_in replyadd;
struct pgmess {
unsigned char c1func;
unsigned char c1len;
char cmess[256];
};
struct pgmess sbuf;
int msgsock, repsock;
int i, itmp;
/* We need a socket that pgview can reply to. Create descriptor. */
repsock = socket(AF_INET, SOCK_STREAM, 0);
if (repsock < 0) {
perror("opening stream socket");
exit(1);
}
/* Name socket using wildcards */
replyadd.sin_family = AF_INET;
replyadd.sin_addr.s_addr = INADDR_ANY;
replyadd.sin_port = 0;
if (bind(repsock, (struct sockaddr *)&replyadd, sizeof(replyadd))) {
perror("binding stream socket");
exit(1);
}
/* Find out assigned port number so we can forward to the server. */
itmp = sizeof(replyadd);
if (getsockname(repsock, (struct sockaddr *)&replyadd, &itmp)) {
perror("getting socket name");
exit(1);
}
/* Start accepting connections */
listen(repsock, 5);
/* Now tell pgview the port that we are listen'ing on. Note, the port */
/* number is already in network byte order which is what pgview needs. */
sbuf.c1func = ifunc;
sbuf.c1len = 2;
memcpy(sbuf.cmess, &replyadd.sin_port, 2);
if (write(pgsock, &sbuf, sbuf.c1len+2) < 0)
perror("writing on stream socket");
/* Now wait for the reply */
msgsock = accept(repsock, (struct sockaddr *)0, (int *)0);
if (msgsock == -1)
perror("accept");
else {
*lbuf = read(msgsock, ibuf, 16);
}
close(msgsock);
return;
}
#ifdef __STDC__
void nexsup_(int *ifunc, char *cbuf, float rtmp[], int len_cbuf)
#else
void nexsup_(ifunc, cbuf, rtmp, len_cbuf)
int *ifunc;
char *cbuf;
float rtmp[];
int len_cbuf;
#endif
{
struct hostent *hp;
struct pgmess {
unsigned char c1func;
unsigned char c1len;
char cmess[256];
};
struct pgmess sbuf;
char *cdis, *cview;
char cloc[256];
int ibuf[10];
int i, icnt, itmp, lbuf, lloc;
if ( pgsock<0 ) {
icnt = 0;
do {
/* Create socket descriptor. */
pgsock = socket(AF_INET, SOCK_STREAM, 0);
if ( pgsock < 0) {
perror("opening stream socket");
}
/* Create socket address structure */
server.sin_family = AF_INET;
cdis = (char *) getenv("DISPLAY");
if ( cdis==NULL )
cdis="localhost";
else {
/* Convert a colon to null (end of string) */
for (i=0; i<strlen(cdis); i++) {
if ( cdis[i]==':' ) cdis[i]='\0';
}
}
hp = gethostbyname(cdis);
if (hp == 0) {
fprintf(stderr, "%s: unknown host", cdis);
}
memcpy(&server.sin_addr, hp->h_addr, hp->h_length);
server.sin_port = htons(7974);
/* Connect descriptor to address */
itmp=connect(pgsock,(struct sockaddr *)&server,sizeof(server));
if ( itmp<0 ) {
close(pgsock);
if ( icnt==0 ) {
cview = (char *) getenv("PGVIEW");
if ( cdis==NULL || cview!=NULL ) {
/* If PGVIEW is defined or DISPLAY is not defined, then try to launch pgview */
printf("Launching pgview...\n");
if ( cview==NULL ) cview="/LocalApps/pgview.app/pgview";
strcpy(cloc, cview);
lloc=strlen(cloc);
cloc[lloc]=' ';
cloc[lloc+1]='&';
cloc[lloc+2]='\0';
system(cloc);
} else {
printf("Please launch pgview on your display system.\n");
}
}
sleep(1);
if((icnt/5)*5 == icnt) printf("waiting...\n");
icnt=icnt+1;
}
} while (itmp<0 && icnt<20);
if ( itmp < 0 ) {
printf("Could not find port connected to pgview.\n");
exit(1);
}
}
switch (*ifunc) {
case 1:
grgetreply(1, ibuf, &lbuf);
rtmp[0]=(float)ntohl(ibuf[0]);
rtmp[1]=(float)ntohl(ibuf[1]);
rtmp[2]=(float)ntohl(ibuf[2]);
rtmp[3]=(float)ntohl(ibuf[3]);
break;
case 2:
sbuf.c1func = 2;
sbuf.c1len = 0;
if (write(pgsock, &sbuf, sbuf.c1len+2) < 0)
perror("writing on stream socket");
break;
case 3:
/* Make sure we send the null character at the end. */
itmp=strlen(cbuf)+1;
sbuf.c1func = 3;
sbuf.c1len = itmp;
memcpy(sbuf.cmess, cbuf, itmp);
if (write(pgsock, &sbuf, sbuf.c1len+2) < 0)
perror("writing on stream socket");
break;
case 4:
grgetreply(4, ibuf, &lbuf);
rtmp[0]=(float)ntohl(ibuf[0]);
rtmp[1]=(float)ntohl(ibuf[1]);
rtmp[2]=(float)ntohl(ibuf[2]);
break;
case 5:
sbuf.c1func = 5;
sbuf.c1len = 0;
if (write(pgsock, &sbuf, sbuf.c1len+2) < 0)
perror("writing on stream socket");
break;
case 6:
sbuf.c1func = 6;
sbuf.c1len = 0;
if (write(pgsock, &sbuf, sbuf.c1len+2) < 0)
perror("writing on stream socket");
break;
case 7:
close(pgsock);
pgsock=-1;
break;
default :
printf("nexsup--Unknown function code= %d\n",*ifunc);
break;
}
}
|