home *** CD-ROM | disk | FTP | other *** search
- /*
- * UTIL.C
- *
- * Session interface routines ( use these in user interface )
- *
- *****************************************************************************
- * *
- * part of: *
- * TCP/IP kernel for NCSA Telnet *
- * by Tim Krauskopf *
- * *
- * National Center for Supercomputing Applications *
- * 152 Computing Applications Building *
- * 605 E. Springfield Ave. *
- * Champaign, IL 61820 *
- * *
- * Copyright (c) 1987, Board of Trustees of the University of Illinois *
- * *
- *****************************************************************************
- *
- * Revision history:
- *
- * 10/87 Initial source release, Tim Krauskopf
- * 5/88 clean up for 2.3 release, JKM
- *
- */
-
- /*
- * Includes
- */
- /* #define DEBUG /* define for debug printfs */
- #include "debug.h"
-
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #if defined(MSC)
- #include <malloc.h>
- #endif
- #if defined(MSC) || defined(__TURBOC__)
- #include <conio.h>
- #include <io.h>
- #endif
- #ifdef MEMORY_DEBUG
- #include "memdebug.h"
- #endif
- #include "whatami.h"
- #include "hostform.h"
- #include "protocol.h"
- #include "data.h"
- #include "externs.h"
- #include "confile.h" /* include the configuration variables and definitions, but we are not CONFIG_MASTER */
-
- /*
- *#define NETX25 0
- */
-
- static unsigned char *Ssstemps[]={ /* standard output files */
- "capfile",
- "hp.out",
- "ps.out",
- "tek.out"
- };
-
- char Sptypes[NPORTS]; /* port types assigned for session use */
- extern struct config Scon; /* hardware configuration */
- extern int ftpdata; /* current ftp data port */
- #define NTIMES 30 /* size of timer queue */
-
- /*
- * timer queue of events which will be placed into the event queue
- * when the time is up.
- */
- static struct {
- unsigned char eclass, /* event queue data */
- event;
- int next, /* next item in list */
- idata;
- int32 when; /* when timer is to go off */
- } Stq[NTIMES];
-
- static int Stfirst,
- Stfree; /* pointers for timer queue */
-
- #define PFTP 1
- #define PRCP 2
- #define PDATA 3
- #define PDOMAIN 4
-
- /************************************************************************/
- /*
- * Snetinit ()
- *
- * Handle all the network initialization, including reading up the config
- * file. This also starts up the hardware and gets arps on their merry way.
- *
- */
- int Snetinit(void )
- {
- int i;
- BUG("Snetinit");
- /*
- * set up the file names
- */
- Scon.capture=Ssstemps[0];
- Scon.hpfile=Ssstemps[1];
- Scon.psfile=Ssstemps[2];
- Scon.tekfile=Ssstemps[3];
-
- neteventinit(); /* initializes for error messages to count */
- BUG("After neteventinit");
- for(i=0; i<NPORTS; i++)
- Sptypes[i]=-1; /* clear port type flags */
-
- for(i=0; i<NTIMES; i++)
- Stq[i].next=i+1; /* load linked list */
- Stq[NTIMES-1].next=-1; /* anchor end */
- Stfirst=-1;
- Stfree=0;
- BUG("About to read config file");
- if(!Sreadhosts()) { /* parses config file */
- BUG("after Sreadhosts - successful");
- #ifdef PC
- netparms(Scon.irqnum,Scon.address,Scon.ioaddr);
- #endif
- #ifdef DEBUG
- printf("irqnum = %X\n",Scon.irqnum);
- printf("address = %X\n",Scon.address);
- printf("ioaddr = %X\n",Scon.ioaddr);
- #endif
-
- netconfig(Scon.hw);
- netsetbroad(Scon.broadip); /* set up IP broadcast address */
- BUG("Before netinit");
- if((i=netinit())==0) { /* starts up hardware */
- BUG("After netinit - successful");
- /*
- * Check for the need to RARP and do it
- */
- netgetip(Scon.myipnum); /* get stored ip num */
- BUG("have ip");
- if(comparen(Scon.myipnum,"RARP",4)) { /* need RARP */
- if(netgetrarp()) /* stores in nnipnum at lower layer */
- return(-2); /* failure return */
- netgetip(Scon.myipnum);
- netsetip(Scon.myipnum);
- }
- /*
- * Check for bootp
- */
- if(comparen(Scon.myipnum,"BOOT",4)) {/* need BOOTP */
- BUG("BOOTP");
- if(bootp())
- return(-3);
- }
- /* BUG("After BOOTP");
- * Check for x25 boot
- */
- #ifdef NETX25
- if(comparen(Scon.myipnum,"X25",3)) /* need server and buds */
- if(X25Boot())
- return(-4);
- #endif
- /*
- * Give the lower layers a chance to check to see if anyone else
- * is using the same ip number. Usually generates an ARP packet.
- */
- BUG("about to ARP");
- netarpme(Scon.myipnum);
- #define DEBUG
- BUG("arped-about to crash");
- Ssetgates(); /* finishes IP inits */
- BUG("about to Stask()");
- #undef DEBUG
- Stask();
- BUG("returning");
- return(0);
- }
- BUG("After netinit - failed");
- return(-1); /* netinit() failed */
- }
- BUG("after Sreadhosts - failed");
- return(-5); /* Sreadhosts() failed */
- }
-
- /************************************************************************/
- /* Sgetconfig
- * copy the configuration information into the user's data structure
- * directly. The user can do with it what he feels like.
- */
- void Sgetconfig(cp)
- struct config *cp;
- {
- movebytes(cp,&Scon,sizeof(struct config));
- }
-
- /************************************************************************/
- /* Smadd
- * If machine is there, just returns pointer, else
- * Add a machine to the list. Increments machine number of machine.
- * Puts in parameters copied from the "default" entry.
- *
- */
- struct machinfo *Smadd(mname)
- char *mname;
- {
- int i;
- struct machinfo *m;
- /*
- * First, do we have the name already?
- */
- m=Shostlook(mname);
- if(m)
- return(m);
- /*
- * Don't have name, add another record
- */
- Smptr=(struct machinfo *)malloc(sizeof(struct machinfo));
- if(Smptr==NULL)
- return(NULL);
- for(i=0; i<NUMSPECS-99; i++)
- Sflags[i]=0; /* we have no parms */
- Scopyfrom("default");
- Smptr->sname=NULL;
- Smptr->hname=malloc(strlen(mname)+1);
- if(Smptr->hname)
- strcpy(Smptr->hname,mname); /* copy in name of machine */
- Smptr->mno=++mno;
- Smptr->mstat=NOIP;
- Smptr->next=Smachlist; /* add to front of machlist */
- Smachlist=Smptr;
- return(Smptr);
- }
-
- /*********************************************************************/
- /* Snewns()
- * Rotate to the next nameserver
- * Chooses the next highest number from the nameserv field
- */
- int Snewns(void)
- {
- struct machinfo *m,*low;
- int i;
-
- if(!Sns) /* safety, should never happen */
- Sns=Smachlist;
- low=Sns;
- i=Sns->nameserv; /* what is value now? */
- m=Smachlist;
- while(m) {
- if((m->nameserv)==(unsigned char)(i+1)) {
- Sns=m;
- return(0);
- }
- if((m->nameserv>0) && (m->nameserv<low->nameserv))
- low=m;
- m=m->next;
- }
- if(Sns==low)
- return(1); /* no alternate */
- else
- Sns=low;
- return(0);
- }
-
- /**************************************************************************/
- /* Slookip
- * For FTP to look up the transfer options to use when running
- *
- */
- struct machinfo *Slookip(ipnum)
- unsigned char *ipnum;
- {
- struct machinfo *m;
-
- m=Smachlist;
- while(m) {
- if(comparen(m->hostip,ipnum,4))
- return(m);
- m=m->next;
- }
- return(NULL);
- }
-
- /************************************************************************/
- /* Shostlook
- * The straightforward list searcher. Looks for either the
- * session name matching or the host name matching. NULL if neither.
- */
- struct machinfo *Shostlook(hname)
- char *hname;
- {
- struct machinfo *m;
-
- m=Smachlist;
- while(m!=NULL) {
- if((m->sname && !ncstrcmp(hname,m->sname)) || (m->hname && !ncstrcmp(hname,m->hname)))
- return(m);
- m=m->next;
- }
- return(NULL);
- }
-
- /************************************************************************/
- /* Slooknum
- * get the host record by machine number, used primarily in DOMAIN name
- * lookup.
- */
- struct machinfo *Slooknum(num)
- int num;
- {
- struct machinfo *m;
-
- m=Smachlist;
- while(m) {
- if(m->mno==num)
- return(m);
- m=m->next;
- }
- return(NULL);
- }
-
- /**************************************************************************/
- /*
- * Snetopen ( m, tport )
- *
- * Takes a pointer to a machine record (already looked up with Sgethost) and
- * sends a TCP open call. Uses port *tport*.
- *
- */
- int Snetopen(m,tport)
- struct machinfo *m;
- int tport;
- {
- int j;
-
-
- if(!m || m->mstat<HAVEIP)
- return(-1);
- j=netxopen(m->hostip,tport,m->retrans,m->mtu,m->maxseg,m->window); /* do the open call */
- if(j>=0) {
- Sptypes[j]=-1; /* is allocated to user */
- Stimerset(CONCLASS,CONFAIL,j,m->conto);
- #ifdef OLDWAY
- Stimerset(SCLASS,RETRYCON,j,m->retrans/TICKSPERSEC+2);
- #else
- Stimerset(SCLASS,RETRYCON,j,m->retrans);
- #endif
- }
- return(j);
- }
-
- /***********************************************************************/
- /*
- * Scwritemode ( mode )
- *
- * Set write mode
- *
- */
- static int son=1;
-
- void Scwritemode(mode)
- int mode;
- {
- son=mode;
- }
-
- /***********************************************************************/
- /*
- * Scmode ()
- *
- * Return what the current mode is
- *
- */
- int Scmode(void )
- {
- return(son);
- }
-
- /***********************************************************************/
- /*
- * Stekmode ( mode )
- *
- * Set tek mode
- *
- */
- static int tekon=1;
-
- void Stekmode(mode)
- int mode;
- {
- tekon=mode;
- }
-
- /***********************************************************************/
- /*
- * Stmode ()
- *
- * Return the value of the tekmode
- *
- */
- int Stmode(void )
- {
- return(tekon);
- }
-
- /***********************************************************************/
- /* Srcpmode ( mode )
- *
- * Set the RCP mode either on or off, install the proper watchers
- *
- */
- #ifdef PC
- static int rcpon=1;
-
- void Srcpmode(mode)
- int mode;
- {
- rcpon=mode;
- if(rcpon)
- setrshd(); /* turn on the watcher */
- else
- unsetrshd(); /* turn off the watcher */
- }
-
- #ifdef NOT_USED
- /***********************************************************************/
- /*
- * Srmode ()
- *
- * Return the value of the rcp flag
- *
- */
- int Srmode(void )
- {
- return(rcpon);
- }
- #endif
- #endif
-
- /***********************************************************************/
- /*
- * Sftpmode ( mode )
- *
- * Turn on or off the ftp watcher
- *
- */
- static int ftpon=0;
-
- int Sftpmode(mode)
- int mode;
- {
- BUG("Sftpmode");
- if(ftpon && mode)
- return(-1);
- ftpon=mode;
- if(ftpon)
- setftp(); /* set the ftp watcher */
- else
- unsetftp(); /* clear the ftp watcher */
- return(0);
- }
-
- /***********************************************************************/
- /*
- * Sfmode ()
- *
- * Return whether the ftp watcher is on or off
- *
- */
- int Sfmode(void )
- {
- return(ftpon);
- }
-
- /***********************************************************************/
- /*
- * Snewcap ( s )
- *
- * Set a mew capture file name
- *
- */
- int Snewcap(s)
- char *s;
- {
- if(NULL==(Scon.capture=malloc(strlen(s)+1)))
- return(1);
- strcpy(Scon.capture,s);
- return(0);
- }
-
- /***********************************************************************/
- /*
- * Snewps ( s )
- *
- * Set a new postscript file name
- *
- */
- int Snewpsfile(s)
- char *s;
- {
- if(NULL==(Scon.psfile=malloc(strlen(s)+1)))
- return(1);
- strcpy(Scon.psfile,s);
- return(0);
- }
-
- /***********************************************************************/
- /*
- * Snewhpfile ( s )
- *
- * Set a new HPGL file name
- *
- */
- int Snewhpfile(s)
- char *s;
- {
- if(NULL==(Scon.hpfile=malloc(strlen(s)+1)))
- return(1);
- strcpy(Scon.hpfile,s);
- return(0);
- }
-
- /***********************************************************************/
- /*
- * Snewtekfile ( s )
- *
- * Set a new tek file name
- *
- */
- int Snewtekfile(s)
- char *s;
- {
- if(NULL==(Scon.tekfile=malloc(strlen(s)+1)))
- return(1);
- strcpy(Scon.tekfile,s);
- return(0);
- }
-
- /***********************************************************************/
- /*
- * Sopencap ()
- *
- * Returns a file handle to an open capture file
- *
- */
- FILE *Sopencap(void )
- {
- FILE *retfp;
-
- if(NULL==(retfp=fopen(Scon.capture,"ab")))
- return(NULL);
- fseek(retfp,0L,2); /* seek to end */
- return(retfp);
- }
-
- /**************************************************************************/
- /*
- * Stask ()
- * A higher level version of net sleep -- manages the timer queue. Always
- * call this in your main loop.
- *
- */
- static int32 recent=0L;
-
- void Stask(void)
- {
- long t;
- int i;
-
- netsleep(0);
- /*
- * Check the timer queue to see if something should be posted
- * First check for timer wraparound
- */
-
- t=n_clicks();
- if(t<recent) {
- i=Stfirst;
- while(i>=0) {
- Stq[i].when-=WRAPTIME;
- i=Stq[i].next;
- }
- }
- recent=t; /* save most recent time */
- while (Stfirst>=0 && t> Stq[Stfirst].when) { /* Q is not empty and timer is going off */
- i=Stfirst;
- netputevent(Stq[i].eclass,Stq[i].event,Stq[i].idata);
- Stfirst=Stq[Stfirst].next; /* remove from q */
- Stq[i].next=Stfree;
- Stfree=i; /* add to free list */
- }
- }
-
- /**************************************************************************/
- /*
- * Stimerset ( class, event, dat, howlong )
- *
- * Set an async timer which is checked in Stask -- when time elapses sticks
- * an event in the network event queue
- *
- * class, event, dat is what gets posted when howlong times out.
- *
- */
- int Stimerset(class,event,dat,howlong)
- int class,event,dat,howlong;
- {
- int i,j,jlast,retval;
- int32 gooff;
-
- retval=0;
- gooff=n_clicks()+howlong;
- if(Stfree<0) { /* queue is full, post first event */
- Stfree=Stfirst;
- Stfirst=Stq[Stfirst].next;
- Stq[Stfree].next=-1;
- netputevent(Stq[Stfree].eclass,Stq[Stfree].event,Stq[Stfree].idata);
- retval=-1;
- }
- Stq[Stfree].idata=dat; /* event to occur at that time */
- Stq[Stfree].event=(unsigned char)event;
- Stq[Stfree].eclass=(unsigned char)class;
- Stq[Stfree].when=gooff;
- i=Stfree; /* remove from free list */
- Stfree=Stq[i].next;
- if(Stfirst<0) { /* if no queue yet */
- Stfirst=i;
- Stq[i].next=-1; /* anchor active q */
- }
- else
- if(gooff<Stq[Stfirst].when) { /* goes first on list */
- Stq[i].next=Stfirst; /* at beginning of list */
- Stfirst=i;
- }
- else { /* goes in middle */
- j=jlast=Stfirst; /* search q from beginning */
- while (gooff>=Stq[j].when&&j>=0) {
- jlast=j;
- j=Stq[j].next;
- }
- Stq[i].next=j; /* insert in q */
- Stq[jlast].next=i;
- }
- return(retval);
- }
-
- /****************************************************************************/
- /*
- * Stimerunset ( class, event, dat )
- *
- * Remove all timer events from the queue that match the class/event/dat.
- *
- *
- */
- int Stimerunset(class,event,dat)
- unsigned char event,class;
- int dat;
- {
- int i,ilast,retval;
-
- retval=ilast=-1;
- i=Stfirst;
- while (i>=0 ) { /* search list */
- if(Stq[i].idata==dat&&Stq[i].eclass==class && Stq[i].event==event) {
- retval=0; /* found at least one */
- /*
- * major bug fix -- if first element matched, old code could crash
- */
- if(i==Stfirst) {
- Stfirst=Stq[i].next; /* first one matches */
- Stq[i].next=Stfree; /* attach to free list */
- Stfree=i;
- i=Stfirst;
- continue; /* start list over */
- }
- else {
- Stq[ilast].next=Stq[i].next; /* remove this entry */
- Stq[i].next=Stfree; /* attach to free list */
- Stfree=i;
- i=ilast;
- }
- }
- ilast=i;
- i=Stq[i].next;
- }
- return(retval);
- }
-
- /****************************************************************************/
- /*
- * Scheckpass ( us, ps )
- *
- * Check the password file for the user/password combination from ftp.
- *
- * Returns valid/invalid
- *
- */
- int Scheckpass(us,ps)
- char *us,*ps;
- {
- char buf[81],*p;
- FILE *fp;
-
- if(NULL==(fp=fopen(Scon.pass,"r")))
- return(0);
- while (NULL != fgets(buf,80,fp)) {
- p=strchr(buf,'\n');
- *p='\0'; /* remove \n */
- p=strchr(buf,':'); /* find delimiter */
- *p++='\0';
- if(!strcmp(buf,us) && Scompass(ps,p)) { /* does password check ?*/
- fclose(fp);
- return(1);
- }
- }
- fclose(fp);
- return(0);
- }
-
- /****************************************************************************/
- /*
- * Sneedpass ()
- *
- * Check to see if the password file is used -- 0 if not, 1 if it is.
- *
- */
- int Sneedpass(void )
- {
- if(Scon.pass==NULL)
- return(0);
- return(1);
- }
-
- /****************************************************************************/
- /*
- * Scompass ( ps, en )
- *
- * Compute and check the encrypted password
- *
- */
- int Scompass(ps,en)
- char *ps,*en;
- {
- int ck;
- char *p,c;
-
- ck=0;
- p=ps;
- while (*p) /* checksum the string */
- ck+=(int)*p++;
- c=(char)ck;
- while (*en) {
- if((((*ps^c)|32)&127)!=*en) /* XOR with checksum */
- return(0);
- if(*ps)
- ps++;
- else
- c++; /* increment checksum to hide length */
- en++;
- }
- return(1);
- }
-
- /****************************************************************************/
- /*
- * Sgetevent ( class, what, datp )
- *
- * Gets events from the network and filters those for session related
- */
- int Sgetevent(class,what,datp)
- int class,*what,*datp;
- {
- int retval;
-
- if(retval=netgetevent(SCLASS,what,datp)) { /* session event */
- switch (retval) {
- case FTPACT:
- ftpd(0,*datp);
- break;
-
- case RCPACT: /* give CPU to rsh for rcp */
- rshd(0);
- break;
-
- case UDPTO: /* name server not responding */
- domto(*datp);
- break;
-
- case RETRYCON:
- if(0<netopen2(*datp)) /* connection open yet? */
- Stimerset(SCLASS,RETRYCON,*datp,4); /* 4 is a kludge */
- break;
-
- default:
- break;
- }
- }
-
- Stask(); /* allow net and timers to take place */
-
- if(!(retval=netgetevent((unsigned char)class,what,datp))) return(0);
-
- if(retval==CONOPEN) Stimerunset(CONCLASS,CONFAIL,*datp); /* kill this timer */
-
- if((*datp==997) && (retval==UDPDATA))
- udpdom();
- else {
- if((*what==CONCLASS)&&(Sptypes[*datp]>=0)) { /* might be for session layer */
- switch (Sptypes[*datp]) {
- case PFTP:
- rftpd(retval);
- break;
-
- case PDATA:
- ftpd(retval,*datp);
- break;
-
- case PRCP:
- rshd(retval);
- break;
-
- default:
- break;
- } /* end switch */
- } /* end if */
- else return(retval); /* let higher layer have it */
- }
- return(0);
- }
-
- char *fixdirnm(dirnm)
- char *dirnm;
- {
- int len;
-
- if (!dirnm)
- return (char *)NULL; /* name is nil */
- len = strlen(dirnm);
- while (len > 1 && /* name contains multiple characters */
- (dirnm[len - 1] == '/' || dirnm[len - 1] == '\\') && /* trailing slash */
- dirnm[len - 2] != ':') /* not "disk:/" or "disk:\" */
- dirnm[--len] = '\0'; /* strip off trailing slash character */
-
- return(dirnm);
- }
-