home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
m
/
mvssrc.zip
/
GPHPTSK
< prev
next >
Wrap
Text File
|
1992-04-13
|
19KB
|
497 lines
#include "tcpincl"
#include "tcph"
/*********************************************************************/
/* prototypes */
/*********************************************************************/
static void cleantoken(char *);
static void cleanastring(char *);
static int getftype(char *);
static int menukeywd(char *,char *,char *);
static int readaline(char *,FILE *,int);
static void sendafile(char *,FILE *,int,int);
static void sendamenu(char *,FILE *,int,int);
static int process(char *,int);
static void lookatsocket(int);
static struct menuitem
{
int type; /* type of record to send */
char desc[100]; /* user description string */
char select[100]; /* select string to send */
char hostname[100]; /* host name to connect to */
int port; /* host port to connect to */
};
#include "ebdasc"
/*=================================================================*/
void receive(int newsockfd,struct clientid clid)
/**************************************************************/
/* this routine processes the data once a connection */
/* has been accepted. It just takes the data sent by the */
/* client and prints it to sysprint, then sends it back */
/* to the client. */
/* */
/* INPUT: newsockfd - socket descriptor */
/* clid - takesocket structure... */
/**************************************************************/
{
char buffer[255]; /*buffer to hold clients character string */
char outbuf[256]; /* buffer to hold an output character string */
char *bufptr; /* pointer into buffer strings above... */
int sockfd; /*socket descriptor for socket call... */
int retcode; /*socket descriptor for socket call... */
int len; /*length of the buffer we're sent... */
int x; /*loop counter.... */
struct sockaddr_in clientaddress; /* address of client */
int addrlen; /* length of client address socket. */
sockfd = takesocket(&clid,newsockfd);
if(sockfd<0) tcperror("TAKESOCKET");
buffer[0] = 0;
/***********************/
/* NOTE: sometimes, if timing is right, RECV can return a 0 length */
/* record when a connection is closed by the client!! below is a */
/* hack to check for a 0 length record, and then terminate this */
/* connection if we got one. */
/***********************/
while(1==1)
{
if((len=recv(sockfd,outbuf,sizeof(buffer)-1,0)) <= 0)
{
tcperror("RECV - ");
printf("tcp error! len=%d\n",len);
break;
}
*(outbuf+(len))=0; /*make sure it's null terminated...*/
printf("len=%d;",len);
asctoebd(outbuf,len);
strcat(buffer,outbuf);
bufptr=buffer+(strlen(buffer)-2);
if(strcmp(bufptr,"\r\n")==0)
{
break;
}
}
if(len<= 0) return;
process(buffer,sockfd);
sprintf(outbuf,".\r\n");
ebdtoasc(outbuf,strlen(outbuf));
if(write(sockfd,outbuf,strlen(outbuf)) < 0) tcperror("SEND");
addrlen = sizeof(clientaddress);
if(getpeername(sockfd,&clientaddress,&addrlen)!=0)
{
tcperror("GETPEERNAME");
printf("could not determine client address\n");
}
printf("Connection from %s.\n",inet_ntoa(clientaddress.sin_addr));
fflush(stdout);
fflush(stderr);
/* lookatsocket(sockfd); */
if(close(sockfd)<0)
{
tcperror("CLOSE - ");
}
}
/*=================================================================*/
/*=================================================================*/
void cleantoken(char *token)
/*******************************************************************/
/* This routine cleans up a token. It converts all chars to */
/* upper case and removes any leading spaces. Note that the */
/* string is assumed to be null terminated. */
/* */
/* INPUT token pointer to token string. */
/* OUTPUT *token string upcased, blanks removed. */
/*******************************************************************/
{
int x; /* loop counter */
for(x=0;x<strlen(token);x++) *(token+x)=toupper(*(token+x));
x=0;
while(*(token+x)==' ') x++;
if(x>0) memmove(token,(token+x),(strlen(token)-x)+1);
};
/*=================================================================*/
void cleanastring(char *string)
/****************************************************/
/* This routine "cleans" a string by removing the */
/* leading spaces and trailing spaces+non-printable */
/* characters. */
/****************************************************/
{
char *ptr;
ptr = string;
/* first clean up the beginning of the string... */
while (isspace(*ptr)!=0 && ptr <=(string+strlen(string)-1)) ptr++;
strcpy(string,ptr);
/* now look at the end of the string... */
ptr = string+strlen(string)-1;
while (isgraph(*ptr)==0 && ptr >=string) ptr--;
*(ptr+1)=0;
}
/*=================================================================*/
/*=================================================================*/
void cleanafileline(char *string)
/****************************************************/
/* This routine "cleans" an output line by removing */
/* trailing spaces and non-printable characters. */
/****************************************************/
{
char *ptr;
ptr = string;
/* look at the end of the string... */
ptr = string+strlen(string)-1;
while (isgraph(*ptr)==0 && ptr >=string) ptr--;
*(ptr+1)=0;
}
/*=================================================================*/
/*=================================================================*/
int getftype(char *ident)
/*******************************************************************/
/* This routine determines what type of gopher file */
/* we've opened. We'll return the file type tot the */
/* caller. */
/* */
/* INPUT: ident pointer to first line of file */
/* */
/* OUTPUT: MENU file type is a menu */
/* FILE file type is a file */
/* INDEX file type is an INDEX (not done) */
/*******************************************************************/
{
int x; /* loop counter */
char buffer[256];
/**********/
/* first, convert the string to upper case... */
/*********/
strcpy(buffer,ident);
cleantoken(buffer);
/**********/
/* return the type of file. */
/*********/
if(strcmp(buffer,MENUIDENT)==0) return(MENU);
if(strcmp(buffer,INDEXIDENT)==0) return(INDEX);
/**********/
/* don't know, so assume it's a "file" file... */
/*********/
return(GFILE);
}
/*=================================================================*/
/*=================================================================*/
int menukeywd(char *buffer,char *token,char *operand)
/*******************************************************************/
/* This routine figures out what type of parm line */
/* the current line is. We'll return the token */
/* type to the caller. */
/* */
/* INPUT: buffer pointer to first line of file */
/* (Note: string must be null terminated! */
/* OUTPUT: Type of token. (See in include file...) */
/*******************************************************************/
{
int x; /* loop counter */
char *tokval;
char *oprval;
char tokstr[256];
strcpy(tokstr,buffer);
tokval=strtok(tokstr,"=");
oprval=strtok(NULL,"");
strcpy(token,tokval);
strcpy(operand,oprval);
cleantoken(token);
/*********/
/* now look at the tokens to see if we have a weener... */
/*********/
if(strcmp(token,TOKTYPE)==0) return(TYPETOK);
if(strcmp(token,TOKDISPLAY)==0) return(DISPLAYTOK);
if(strcmp(token,TOKSELECT)==0) return(SELECTTOK);
if(strcmp(token,TOKHOST)==0) return(HOSTTOK);
if(strcmp(token,TOKPORT)==0) return(PORTTOK);
if(strcmp(token,TOKEND)==0) return(ENDTOK);
return(COMMENTTOK);
}
/*=================================================================*/
/*=================================================================*/
int readaline(char *buffer,FILE *readfile,int maxlen)
/*******************************************************************/
/* This routine reads a line from the specified file. */
/* if a read error occurs, an error message is printed and */
/* FALSE is returned. */
/* */
/* INPUT buffer pointer to buffer to place line */
/* readfile file structure to read from */
/* */
/* OUTPUT buffer line that was read from the file */
/* TRUE read worked ok */
/* FALSE read failed! */
/*******************************************************************/
{
memset(buffer,0,maxlen);
fread(buffer,maxlen,1,readfile);
if(ferror(readfile))
{
perror("FREAD");
return(FALSE);
}
return(TRUE);
}
/*=================================================================*/
/*=================================================================*/
void sendafile(char *buffer,FILE *readfile,int maxlen,int sockfd)
/*******************************************************************/
/* This routine sends a file to the calling client. */
/* It assumes the file is a text formatted file. */
/* INPUT: buffer pointer to the already read line... */
/* readfile file we're going to read from.. */
/* maxlen size of the buffer. */
/* sockfd socket descriptor for client. */
/* */
/* OUTPUT: send the file to the client */
/*******************************************************************/
{
int x;
char *moveit;
char outbuf[256];
/*******/
/* send the first line (cause we already read it) */
/*******/
cleanafileline(buffer);
sprintf(outbuf,"%s\r\n",buffer);
ebdtoasc(outbuf,strlen(outbuf));
if(write(sockfd,outbuf,strlen(outbuf)) < 0)
{
tcperror("SEND");
return;
}
/*******/
/* get the rest of the lines of the file and send them... */
/*******/
while(1==1)
{
readaline(buffer,readfile,maxlen);
if(feof(readfile)) break;
if(*buffer=='.')
{
moveit = buffer+1;
memmove(moveit,buffer,strlen(buffer));
*buffer='.';
}
cleanafileline(buffer);
sprintf(outbuf,"%s\r\n",buffer);
ebdtoasc(outbuf,strlen(outbuf));
if(write(sockfd,outbuf,strlen(outbuf)) < 0)
{
tcperror("SEND");
return;
}
}
}
/*=================================================================*/
/*=================================================================*/
void sendamenu(char *buffer,FILE *readfile,int maxlen,int sockfd)
/*******************************************************************/
/* This routine formats a menu file into gopher data & sends it */
/* to the client. */
/* INPUT: buffer pointer to the already read line... */
/* readfile file we're going to read from.. */
/* maxlen size of the buffer. */
/* sockfd socket descriptor for client */
/* */
/* OUTPUT: send the menu to the client */
/*******************************************************************/
{
char *moveit;
char token[133];
char operand[133];
char *typeoftype; /*pointer for strtok */
char outbuf[256];
int kindotoken;
int x; /* loop counter */
struct menuitem menu;
memset(&menu,0,sizeof menu );
while(1==1)
{
readaline(buffer,readfile,maxlen);
if(feof(readfile))
{
break;
}
if(strlen(buffer)>0) kindotoken = menukeywd(buffer,token,operand);
switch(kindotoken)
{
case TYPETOK:
cleantoken(operand);
typeoftype=strtok(operand," ");
if(strcmp(typeoftype,TYPEFILE)==0) menu.type=GFILE;
if(strcmp(typeoftype,TYPEMENU)==0) menu.type=MENU;
if(strcmp(typeoftype,TYPEINDEX)==0) menu.type=INDEX;
if(strcmp(typeoftype,TYPETELNET)==0) menu.type=TELNET;
break;
case DISPLAYTOK:
strcpy(menu.desc,operand);
break;
case SELECTTOK:
strcpy(menu.select,operand);
break;
case HOSTTOK:
strcpy(menu.hostname,operand);
break;
case PORTTOK:
menu.port=atoi(operand);
break;
case ENDTOK:
if(menu.type==TELNET && menu.port==0) menu.port=0;
else if(menu.port==0) menu.port=70;
if(strlen(menu.desc)!=0 && strlen(menu.hostname)!=0)
sprintf(outbuf,"%d%s\t%s\t%s\t%d\r\n\0",menu.type,menu.desc,
menu.select,menu.hostname,menu.port);
fflush(stdout);
ebdtoasc(outbuf,strlen(outbuf));
if(write(sockfd,outbuf,strlen(outbuf)) < 0)
{
tcperror("SEND");
return;
}
memset(&menu,0,sizeof menu );
break;
};
}
}
/*=================================================================*/
/*=================================================================*/
int process(char *filename,int sockfd)
/*******************************************************************/
/* This routine Processes the file the user requested. */
/* If it's a menu, we'll form a menu line, if it's a */
/* file, we'll just send it as is. */
/* */
/* INPUT: filename pointer to the file name to open */
/* sockfd socket descriptor for the client */
/* */
/* OUTPUT: print "gopher" lines. */
/* TRUE - file printed ok. */
/* FALSE - Error reading or writing */
/*******************************************************************/
{
int x; /* loop counter*/
char buffer[256]; /* buffer for input/output*/
FILE *readfile; /* declare the file... */
int numread; /* number of items read... */
int filetype; /* type of file we're dealing with*/
char *ptr; /* pointer into receive buffer */
/************/
/* First, strip off any "bad" characters and open the file. */
/************/
cleanastring(filename);
if(strlen(filename)==0) strcpy(filename,DEFAULT_DIRECTORY);
printf("entry requested:%s;",filename);
sprintf(buffer,"'%s'",filename); /* make sure userid isn't added */
if((readfile=fopen(buffer,"rb,type=record")) == NULL)
{
perror("PROCESS");
printf("INVALID! requested:%s\n",filename);
fflush(stdout);
fflush(stderr);
return(FALSE);
}
/************/
/* get the first line and see what type of file we've got. */
/************/
memset(buffer,0,sizeof(buffer));
if(readaline(buffer,readfile,sizeof(buffer))==FALSE) return(FALSE);
filetype=getftype(buffer);
/************/
/* Now let's go do whatever we need to for this file type. */
/************/
switch(filetype)
{
case MENU:
sendamenu(buffer,readfile,sizeof(buffer),sockfd);
break;
case GFILE:
sendafile(buffer,readfile,sizeof(buffer),sockfd);
break;
}
if(fclose(readfile) < 0) perror("PROCESS CLOSE");
}
/*=================================================================*/
/*=================================================================*/
void lookatsocket(int sockfd)
/*******************************************************************/
/* */
/* this is a debugging routine; it looks at the status of a */
/* socket. */
/*******************************************************************/
{
int rc; /* return code */
struct linger l; /* linger structure */
int length; /* length variable */
int option;
length = sizeof(l);
if(getsockopt(sockfd,SOL_SOCKET, SO_LINGER,&l,&length)==0)
{
printf("l_onoff=%d\n",l.l_onoff);
printf("l_linger=%d\n",l.l_linger);
}
else tcperror("GETSOCKOPT");
length = sizeof(option);
if(getsockopt(sockfd,SOL_SOCKET, SO_ERROR,&option,&length)==0)
{
printf("so_error=%d\n",option);
}
else tcperror("GETSOCKOPT");
if(fcntl(sockfd,F_SETFL,FNDELAY)!=0) tcperror("FCNTL");
while(1==1)
{
char buffer[256]; int len;
len=recv(sockfd,buffer,sizeof(buffer)-1,0);
if((len==-1)&&(errno==EWOULDBLOCK))
{
break;
}
else if(len==-1)
{
tcperror("recv");
break;
}
else
{
int x;
buffer[255] = 0;
printf("buffer =%s\n",buffer);
for(x=0;x<len;x++) printf("%x ",buffer[x]);
printf("\n");
break;
}
}
}