home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tel2305s.zip / ENGINE / UTIL.C < prev    next >
C/C++ Source or Header  |  1992-03-08  |  19KB  |  841 lines

  1. /*
  2. *    UTIL.C
  3. *
  4. *    Session interface routines ( use these in user interface )
  5. *
  6. *****************************************************************************
  7. *                                                                            *
  8. *      part of:                                                                *
  9. *     TCP/IP kernel for NCSA Telnet                                            *
  10. *      by Tim Krauskopf                                                        *
  11. *                                                                            *
  12. *      National Center for Supercomputing Applications                        *
  13. *      152 Computing Applications Building                                    *
  14. *      605 E. Springfield Ave.                                                *
  15. *      Champaign, IL  61820                                                    *
  16. *                                                                            *
  17. *     This program is in the public domain.                                 *
  18. *                                                                           *
  19. *****************************************************************************
  20. *
  21. *    Revision history:
  22. *
  23. *    10/87  Initial source release, Tim Krauskopf
  24. *    5/88    clean up for 2.3 release, JKM    
  25. *
  26. */
  27.  
  28. /*
  29. *    Includes
  30. */
  31. /* #define DEBUG  */    /* define for debug printfs */
  32. #include "debug.h"
  33.  
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <stdlib.h>
  37. #if defined(MSC)
  38. #include <malloc.h>
  39. #endif
  40. #if defined(MSC) || defined(__TURBOC__)
  41. #include <conio.h>
  42. #include <io.h>
  43. #endif
  44. #include "whatami.h"
  45. #include "hostform.h"
  46. #include "protocol.h"
  47. #include "data.h"
  48. #include "externs.h"
  49. #include "confile.h"            /* include the configuration variables and definitions, but we are not CONFIG_MASTER */
  50.  
  51. /*
  52. *#define    NETX25    0
  53. */
  54.  
  55. static unsigned char *Ssstemps[]={    /* standard output files */
  56.     "capfile",
  57.     "hp.out",
  58.     "ps.out",
  59.     "tek.out"
  60. };
  61.  
  62. char Sptypes[NPORTS];                    /* port types assigned for session use */
  63. extern struct config Scon;                /* hardware configuration */
  64. extern int ftpdata;                        /* current ftp data port */
  65. #define NTIMES 30                        /* size of timer queue */
  66.  
  67. /*
  68. *  timer queue of events which will be placed into the event queue
  69. *  when the time is up.
  70. */
  71. static struct {
  72.     unsigned char eclass,                /* event queue data */
  73.         event;
  74.     int next,                            /* next item in list */
  75.         idata;
  76.     int32 when;                            /* when timer is to go off */
  77. } Stq[NTIMES];
  78.  
  79. static int Stfirst,
  80.         Stfree;                            /* pointers for timer queue */
  81.  
  82. #define PFTP 1
  83. #define PRCP 2
  84. #define PDATA 3
  85. #define PDOMAIN 4
  86.  
  87. /************************************************************************/
  88. /*
  89. *    Snetinit ()
  90. *
  91. *    Handle all the network initialization, including reading up the config
  92. * file.  This also starts up the hardware and gets arps on their merry way.
  93. *
  94. */
  95. int Snetinit(void )
  96. {
  97.     int i;
  98. BUG("Snetinit");
  99. /*
  100. *  set up the file names
  101. */
  102.     Scon.capture=Ssstemps[0];
  103.     Scon.hpfile=Ssstemps[1];
  104.     Scon.psfile=Ssstemps[2];
  105.     Scon.tekfile=Ssstemps[3];
  106.  
  107.     neteventinit();                 /* initializes for error messages to count */
  108. BUG("After neteventinit");
  109.     for(i=0; i<NPORTS; i++)
  110.         Sptypes[i]=-1;                /* clear port type flags */
  111.  
  112.     for(i=0; i<NTIMES; i++)
  113.         Stq[i].next=i+1;            /* load linked list */
  114.     Stq[NTIMES-1].next=-1;            /* anchor end */
  115.     Stfirst=-1;
  116.     Stfree=0;
  117. BUG("About to read config file");
  118.     if(!Sreadhosts()) {             /* parses config file */
  119. BUG("after Sreadhosts - successful");
  120.         netparms(Scon.irqnum,Scon.address,Scon.ioaddr);
  121. #ifdef DEBUG
  122.         printf("irqnum = %X\n",Scon.irqnum);
  123.         printf("address = %X\n",Scon.address);
  124.         printf("ioaddr = %X\n",Scon.ioaddr);
  125. #endif
  126.  
  127.         netconfig(Scon.hw);
  128.         netsetbroad(Scon.broadip);        /* set up IP broadcast address */
  129. BUG("Before netinit");
  130.         if((i=netinit())==0) {          /* starts up hardware */
  131. BUG("After netinit - successful");
  132. /*
  133. *  Check for the need to RARP and do it
  134. */
  135.             netgetip(Scon.myipnum);    /* get stored ip num */
  136. BUG("have ip");
  137.             if(comparen(Scon.myipnum,"RARP",4)) {   /* need RARP */
  138.                 if(netgetrarp())    /* stores in nnipnum at lower layer */
  139.                     return(-2);            /* failure return */
  140.                 netgetip(Scon.myipnum);
  141.                 netsetip(Scon.myipnum);    
  142.             }
  143. /*
  144.  *    Check for bootp
  145.  */
  146.             if(comparen(Scon.myipnum,"BOOT",4)) {   /* need BOOTP */
  147. BUG("BOOTP");
  148.                 if(bootp())
  149.                     return(-3);
  150.             }
  151. BUG("After BOOTP");
  152. /*
  153.  *    Check for x25 boot
  154.  */
  155. #ifdef    NETX25
  156.             if(comparen(Scon.myipnum,"X25",3))      /* need server and buds */
  157.                 if(X25Boot())
  158.                     return(-4);
  159. #endif
  160. /*
  161. *  Give the lower layers a chance to check to see if anyone else
  162. *  is using the same ip number.  Usually generates an ARP packet.
  163. */
  164. BUG("about to ARP");
  165.             netarpme(Scon.myipnum);
  166. BUG("arped-about to crash");
  167.             Ssetgates();            /* finishes IP inits */
  168. BUG("about to Stask()");
  169.             Stask();
  170. BUG("returning");
  171.             return(0);
  172.           }
  173. BUG("After netinit - failed");
  174.         return(-1);        /* netinit() failed */
  175.       }
  176. BUG("after Sreadhosts - failed");
  177.     return(-5);            /* Sreadhosts() failed */
  178. }
  179.  
  180. /************************************************************************/
  181. /*  Sgetconfig
  182. *   copy the configuration information into the user's data structure
  183. *   directly.  The user can do with it what he feels like.
  184. */
  185. void Sgetconfig(struct config *cp)
  186. {
  187.     movebytes(cp,&Scon,sizeof(struct config));
  188. }
  189.  
  190. /************************************************************************/
  191. /*  Smadd
  192. *   If machine is there, just returns pointer, else
  193. *   Add a machine to the list. Increments machine number of machine.
  194. *   Puts in parameters copied from the "default" entry.
  195. *
  196. */
  197. struct machinfo *Smadd(char *mname)
  198. {
  199.     int i;
  200.     struct machinfo *m;
  201. /*
  202. *  First, do we have the name already?
  203. */
  204.     m=Shostlook(mname);
  205.     if(m)
  206.         return(m);
  207. /*
  208. *   Don't have name, add another record
  209. */
  210.     Smptr=(struct machinfo *)malloc(sizeof(struct machinfo));
  211.     if(Smptr==NULL)
  212.         return(NULL);
  213.     for(i=0; i<NUMSPECS-99; i++)
  214.         Sflags[i]=0;                    /* we have no parms */
  215.     Scopyfrom("default");
  216.     Smptr->sname=NULL;
  217.     Smptr->hname=malloc(strlen(mname)+1);
  218.     if(Smptr->hname)
  219.         strcpy(Smptr->hname,mname);        /* copy in name of machine */
  220.     Smptr->mno=++mno;
  221.     Smptr->mstat=NOIP;
  222.     Smptr->next=Smachlist;            /* add to front of machlist */
  223.     Smachlist=Smptr;
  224.     return(Smptr);
  225. }
  226.  
  227. /*********************************************************************/
  228. /*  Snewns()
  229. *   Rotate to the next nameserver
  230. *   Chooses the next highest number from the nameserv field
  231. */
  232. int Snewns(void)
  233. {
  234.     struct machinfo *m,*low;
  235.     int i;
  236.  
  237.     if(!Sns)                    /* safety, should never happen */
  238.         Sns=Smachlist;
  239.     low=Sns;
  240.     i=Sns->nameserv;            /* what is value now? */
  241.     m=Smachlist;
  242.     while(m) {
  243.         if((m->nameserv)==(unsigned char)(i+1)) {
  244.             Sns=m;
  245.             return(0);
  246.           }
  247.         if((m->nameserv>0) && (m->nameserv<low->nameserv))
  248.             low=m;
  249.         m=m->next;
  250.       }
  251.     if(Sns==low)
  252.         return(1);                /* no alternate */
  253.     else
  254.         Sns=low;
  255.     return(0);
  256. }
  257.  
  258. #ifndef NET14
  259. /**************************************************************************/
  260. /*  Slookip
  261. *   For FTP to look up the transfer options to use when running
  262. *
  263. */
  264. struct machinfo *Slookip(unsigned char *ipnum)
  265. {
  266.     struct machinfo *m;
  267.  
  268.     m=Smachlist;
  269.     while(m) {
  270.         if(comparen(m->hostip,ipnum,4))
  271.             return(m);
  272.         m=m->next;
  273.       }
  274.     return(NULL);
  275. }
  276. #endif
  277.  
  278. /************************************************************************/
  279. /*  Shostlook
  280. *   The straightforward list searcher.  Looks for either the
  281. *   session name matching or the host name matching.  NULL if neither.
  282. */
  283. struct machinfo *Shostlook(char *hname)
  284. {
  285.     struct machinfo *m;
  286.  
  287.     m=Smachlist;
  288.     while(m!=NULL) {
  289.         if((m->sname && !ncstrcmp(hname,m->sname)) || (m->hname && !ncstrcmp(hname,m->hname)))
  290.             return(m);
  291.         m=m->next;
  292.       }
  293.     return(NULL);
  294. }
  295.  
  296. /************************************************************************/
  297. /*  Slooknum
  298. *   get the host record by machine number, used primarily in DOMAIN name
  299. *   lookup.
  300. */
  301. struct machinfo *Slooknum(int num)
  302. {
  303.     struct machinfo *m;
  304.  
  305.     m=Smachlist;
  306.     while(m) {
  307.         if(m->mno==num)
  308.             return(m);
  309.         m=m->next;
  310.       }
  311.     return(NULL);
  312. }
  313.  
  314. /**************************************************************************/
  315. /*
  316. *    Snetopen ( m, tport )
  317. *
  318. *    Takes a pointer to a machine record (already looked up with Sgethost) and
  319. * sends a TCP open call.  Uses port *tport*.  
  320. *
  321. */
  322. int Snetopen(struct machinfo *m,int tport)
  323. {
  324.     int j;
  325.  
  326.     if(!m || m->mstat<HAVEIP)
  327.         return(-1);
  328.     j=netxopen(m->hostip,tport,m->retrans,m->mtu,m->maxseg,m->window);    /* do the open call */
  329.     if(j>=0) {
  330.         Sptypes[j]=-1;            /* is allocated to user */
  331.         Stimerset(CONCLASS,CONFAIL,j,m->conto);
  332. #ifdef OLDWAY
  333.         Stimerset(SCLASS,RETRYCON,j,m->retrans/TICKSPERSEC+2);
  334. #else
  335.         Stimerset(SCLASS,RETRYCON,j,m->retrans);
  336. #endif
  337.       } /* end if */
  338.     return(j);
  339. }   /* end Snetopen() */
  340.  
  341. /***********************************************************************/
  342. /*
  343. *    Scwritemode ( mode )
  344. *
  345. *    Set write mode
  346. *
  347. */
  348. static int son=1;
  349.  
  350. void Scwritemode(int mode)
  351. {
  352.     son=mode;
  353. }
  354.  
  355. #ifndef NET14
  356. /***********************************************************************/
  357. /*
  358. *    Scmode ()
  359. *
  360. *    Return what the current mode is 
  361. *
  362. */
  363. int Scmode(void )
  364. {
  365.     return(son);
  366. }
  367.  
  368. /***********************************************************************/
  369. /*
  370. *    Stekmode ( mode )
  371. *
  372. *    Set tek mode
  373. *
  374. */
  375. static int tekon=1;
  376.  
  377. void Stekmode(int mode)
  378. {
  379.     tekon=mode;
  380. }
  381.  
  382. /***********************************************************************/
  383. /*
  384. *    Stmode ()
  385. *
  386. *    Return the value of the tekmode
  387. *
  388. */
  389. int Stmode(void )
  390. {
  391.     return(tekon);
  392. }
  393. #endif
  394.  
  395. /***********************************************************************/
  396. /*    Srcpmode ( mode )
  397. *
  398. *    Set the RCP mode either on or off, install the proper watchers
  399. *
  400. */
  401. static int rcpon=1;
  402.  
  403. void Srcpmode(int mode)
  404. {
  405.     rcpon=mode;
  406. #ifdef RCP
  407.     if(rcpon)
  408.         setrshd();                                /* turn on the watcher */
  409.     else
  410.         unsetrshd();                            /* turn off the watcher */
  411. #endif
  412. }
  413.  
  414. #ifdef NOT_USED
  415. /***********************************************************************/
  416. /*
  417. *    Srmode ()
  418. *
  419. *    Return the value of the rcp flag
  420. *
  421. */
  422. int Srmode(void )
  423. {
  424.     return(rcpon);
  425. }
  426. #endif
  427.  
  428. /***********************************************************************/
  429. /*
  430. *    Sftpmode ( mode )
  431. *
  432. *    Turn on or off the ftp watcher
  433. *
  434. */
  435. static int ftpon=0;
  436.  
  437. int Sftpmode(int mode)
  438. {
  439. BUG("Sftpmode");
  440.     if(ftpon && mode)
  441.         return(-1);
  442.     ftpon=mode;
  443. #ifdef FTP
  444.     if(ftpon)
  445.         setftp();                                /* set the ftp watcher */
  446.     else
  447.         unsetftp();                                /* clear the ftp watcher */
  448. #endif
  449.     return(0);
  450. }
  451.  
  452. #ifndef NET14
  453. #ifdef NOT_USED
  454. /***********************************************************************/
  455. /*
  456. *    Sfmode ()
  457. *
  458. *    Return whether the ftp watcher is on or off
  459. *
  460. */
  461. int Sfmode(void )
  462. {
  463.     return(ftpon);
  464. }
  465. #endif
  466.  
  467. /***********************************************************************/
  468. /*
  469. *    Snewcap ( s )
  470. *
  471. *   Set a new capture file name
  472. *
  473. */
  474. int Snewcap(char *s)
  475. {
  476.     if(NULL==(Scon.capture=malloc(strlen(s)+1)))
  477.         return(1);
  478.     strcpy(Scon.capture,s);
  479.     return(0);
  480. }
  481.  
  482. /***********************************************************************/
  483. /*
  484. *    Snewps ( s )
  485. *
  486. *    Set a new postscript file name
  487. *
  488. */
  489. int Snewpsfile(char *s)
  490. {
  491.     if(NULL==(Scon.psfile=malloc(strlen(s)+1)))
  492.         return(1);
  493.     strcpy(Scon.psfile,s);
  494.     return(0);
  495. }
  496.  
  497. /***********************************************************************/
  498. /*
  499. *    Snewhpfile ( s )
  500. *
  501. *    Set a new HPGL file name
  502. *
  503. */
  504. int Snewhpfile(char *s)
  505. {
  506.     if(NULL==(Scon.hpfile=malloc(strlen(s)+1)))
  507.         return(1);
  508.     strcpy(Scon.hpfile,s);
  509.     return(0);
  510. }
  511.  
  512. /***********************************************************************/
  513. /*
  514. *    Snewtekfile ( s )
  515. *
  516. *    Set a new tek file name
  517. *
  518. */
  519. int Snewtekfile(char *s)
  520. {
  521.     if(NULL==(Scon.tekfile=malloc(strlen(s)+1)))
  522.         return(1);
  523.     strcpy(Scon.tekfile,s);
  524.     return(0);
  525. }
  526.  
  527. /***********************************************************************/
  528. /*
  529. *    Sopencap ()
  530. *
  531. *    Returns a file handle to an open capture file
  532. *
  533. */
  534. FILE *Sopencap(void )
  535. {
  536.     FILE *retfp;
  537.  
  538.     if(NULL==(retfp=fopen(Scon.capture,"ab"))) 
  539.         return(NULL);
  540.     fseek(retfp,0L,2);        /* seek to end */
  541.     return(retfp);
  542. }
  543. #endif
  544.  
  545. /**************************************************************************/
  546. /*
  547. *    Stask ()
  548. *    A higher level version of net sleep -- manages the timer queue.  Always
  549. * call this in your main loop.
  550. *
  551. */
  552. static int32 recent=0L;
  553.  
  554. void Stask(void)
  555. {
  556.     long t;
  557.     int i;
  558.  
  559.     netsleep(0);
  560. /*
  561. *  Check the timer queue to see if something should be posted
  562. *  First check for timer wraparound
  563. */
  564.  
  565.     t=n_clicks();
  566.     if(t<recent) {
  567.         i=Stfirst;
  568.         while(i>=0) {
  569.             Stq[i].when-=WRAPTIME;
  570.             i=Stq[i].next;
  571.           }
  572.       }
  573.     recent=t;                            /* save most recent time */
  574.     while (Stfirst>=0 && t> Stq[Stfirst].when) {    /* Q is not empty and timer is going off */
  575.         i=Stfirst;
  576.         netputevent(Stq[i].eclass,Stq[i].event,Stq[i].idata);
  577.         Stfirst=Stq[Stfirst].next;    /* remove from q */
  578.         Stq[i].next=Stfree;
  579.         Stfree=i;                        /* add to free list */
  580.       }
  581. }
  582.  
  583. /**************************************************************************/
  584. /*
  585. *    Stimerset ( class, event, dat, howlong )
  586. *
  587. *    Set an async timer which is checked in Stask -- when time elapses sticks
  588. * an event in the network event queue
  589. *
  590. *    class, event, dat is what gets posted when howlong times out.
  591. *
  592. */
  593. int Stimerset(int class,int event,int dat,int howlong)
  594. {
  595.     int i,j,jlast,retval;
  596.     int32 gooff;
  597.  
  598.     retval=0;
  599.     gooff=n_clicks()+howlong;
  600.     if(Stfree<0) {                /* queue is full, post first event */
  601.         Stfree=Stfirst;
  602.         Stfirst=Stq[Stfirst].next;
  603.         Stq[Stfree].next=-1;
  604.         netputevent(Stq[Stfree].eclass,Stq[Stfree].event,Stq[Stfree].idata);
  605.         retval=-1;
  606.       }
  607.     Stq[Stfree].idata=dat;                /* event to occur at that time */
  608.     Stq[Stfree].event=(unsigned char)event;
  609.     Stq[Stfree].eclass=(unsigned char)class;
  610.     Stq[Stfree].when=gooff;
  611.     i=Stfree;                            /* remove from free list */
  612.     Stfree=Stq[i].next;
  613.     if(Stfirst<0) {                    /* if no queue yet */
  614.         Stfirst=i;
  615.         Stq[i].next=-1;                /* anchor active q */
  616.       }
  617.     else 
  618.         if(gooff<Stq[Stfirst].when) {    /* goes first on list */
  619.             Stq[i].next=Stfirst;                /* at beginning of list */
  620.             Stfirst=i;
  621.           }
  622.         else {                                    /* goes in middle */
  623.             j=jlast=Stfirst;                /* search q from beginning */
  624.             while (gooff>=Stq[j].when&&j>=0) {
  625.                 jlast=j;
  626.                 j=Stq[j].next;
  627.               }
  628.             Stq[i].next=j;                    /* insert in q */
  629.             Stq[jlast].next=i;
  630.           }
  631.     return(retval);
  632. }
  633.  
  634. /****************************************************************************/
  635. /*
  636. *    Stimerunset ( class, event, dat )
  637. *
  638. *    Remove all timer events from the queue that match the class/event/dat.
  639. *
  640. *
  641. */
  642. int Stimerunset(unsigned char class,unsigned char event,int dat)
  643. {
  644.     int i,ilast,retval;
  645.  
  646.     retval=ilast=-1;
  647.     i=Stfirst;
  648.     while (i>=0 ) {                    /* search list */
  649.         if(Stq[i].idata==dat&&Stq[i].eclass==class && Stq[i].event==event) {
  650.             retval=0;                    /* found at least one */
  651. /*
  652. * major bug fix -- if first element matched, old code could crash
  653. */
  654.             if(i==Stfirst) {
  655.                 Stfirst=Stq[i].next;            /* first one matches */
  656.                 Stq[i].next=Stfree;            /* attach to free list */
  657.                 Stfree=i;
  658.                 i=Stfirst;
  659.                 continue;                        /* start list over */
  660.               }
  661.             else {
  662.                 Stq[ilast].next=Stq[i].next;    /* remove this entry */
  663.                 Stq[i].next=Stfree;            /* attach to free list */
  664.                 Stfree=i;
  665.                 i=ilast;
  666.               }
  667.           }
  668.         ilast=i;
  669.         i=Stq[i].next;
  670.       }
  671.     return(retval);
  672. }
  673.  
  674. #ifndef NET14
  675. /****************************************************************************/
  676. /*
  677. *    Scheckpass ( us, ps )
  678. *
  679. *    Check the password file for the user/password combination from ftp.
  680. *
  681. *    Returns valid/invalid
  682. *
  683. */
  684. int Scheckpass(char *us,char *ps)
  685. {
  686.     char buf[81],*p;
  687.     FILE *fp;
  688.     
  689.     if(NULL==(fp=fopen(Scon.pass,"r"))) 
  690.         return(0);
  691.     while (NULL != fgets(buf,80,fp)) {
  692.         p=strchr(buf,'\n');
  693.         *p='\0';                            /* remove \n */
  694.         p=strchr(buf,':');                /* find delimiter */
  695.         *p++='\0';
  696.         if(!strcmp(buf,us) && Scompass(ps,p)) {            /* does password check ?*/
  697.             fclose(fp);
  698.             return(1);
  699.           }
  700.       }
  701.     fclose(fp);
  702.     return(0);
  703. }
  704.  
  705. /****************************************************************************/
  706. /*
  707. *    Sneedpass ()
  708. *
  709. *    Check to see if the password file is used -- 0 if not, 1 if it is.
  710. *
  711. */
  712. int Sneedpass(void )
  713. {
  714.     if(Scon.pass==NULL)
  715.         return(0);
  716.     return(1);
  717. }
  718.  
  719. /****************************************************************************/
  720. /*
  721. *    Scompass ( ps, en )
  722. *
  723. *    Compute and check the encrypted password
  724. *
  725. */
  726. int Scompass(char *ps,char *en)
  727. {
  728.     int ck;
  729.     char *p,c;
  730.  
  731.     ck=0;
  732.     p=ps;
  733.     while (*p)                            /* checksum the string */
  734.         ck+=(int)*p++;
  735.     c=(char)ck;
  736.     while (*en) {
  737.         if((((*ps^c)|32)&127)!=*en)        /* XOR with checksum */
  738.             return(0);
  739.         if(*ps)
  740.             ps++;
  741.         else
  742.             c++;                        /* increment checksum to hide length */
  743.         en++;
  744.       }
  745.     return(1);
  746. }
  747. #endif
  748.  
  749. /****************************************************************************/
  750. /*
  751. *    Sgetevent ( class, what, datp )
  752. *
  753. *    Gets events from the network and filters those for session related
  754. */
  755. int Sgetevent(int class,int *what,int *datp)
  756. {
  757.     int retval;
  758.  
  759.     if(retval=netgetevent(SCLASS,what,datp)) {    /* session event */
  760.         switch (retval) {
  761. #ifdef FTP
  762.             case FTPACT:
  763.                 ftpd(0,*datp);
  764.                 break;
  765. #endif
  766.  
  767. #ifdef RCP
  768.             case RCPACT:                /* give CPU to rsh for rcp */
  769.                 rshd(0);
  770.                 break;
  771. #endif
  772.  
  773.             case UDPTO:                    /* name server not responding */
  774.                 domto(*datp);
  775.                 break;
  776.  
  777.             case RETRYCON:
  778.                 if(0<netopen2(*datp))     /* connection open yet? */
  779.                     Stimerset(SCLASS,RETRYCON,*datp,4);  /* 4 is a kludge */
  780.                 break;
  781.  
  782.             default:
  783.                 break;
  784.           }
  785.       }
  786.  
  787.     Stask();                        /* allow net and timers to take place */
  788.  
  789.     if(!(retval=netgetevent((unsigned char)class,what,datp))) return(0);
  790.  
  791.     if(retval==CONOPEN) Stimerunset(CONCLASS,CONFAIL,*datp);   /* kill this timer */
  792.  
  793.     if((*datp==997) && (retval==UDPDATA))
  794.         udpdom();
  795.     else {
  796.         if((*what==CONCLASS) && (Sptypes[*datp]>=0)) {    /* might be for session layer */
  797.             switch (Sptypes[*datp]) {
  798. #ifdef FTP
  799.                 case PFTP:
  800.                     rftpd(retval);
  801.                     break;
  802.  
  803.                 case PDATA:
  804.                     ftpd(retval,*datp);
  805.                     break;
  806. #endif
  807.  
  808. #ifdef RCP
  809.                 case PRCP:
  810.                     rshd(retval);
  811.                     break;
  812. #endif
  813.  
  814.                 default:
  815.                     break;
  816.               }    /* end switch */
  817.           }    /* end if */
  818.         else
  819.             return(retval);                /* let higher layer have it */
  820.       } /* end else */
  821.     return(0);
  822. }
  823.  
  824. #ifndef NET14
  825. char *fixdirnm(char *dirnm)
  826. {
  827.     int len;
  828.  
  829.     if (!dirnm)
  830.         return (char *)NULL;            /* name is nil */
  831.     len = strlen(dirnm);
  832.     while (len > 1 &&                    /* name contains multiple characters */
  833.       (dirnm[len - 1] == '/' || dirnm[len - 1] == '\\') && /* trailing slash */
  834.       dirnm[len - 2] != ':')                    /* not "disk:/" or "disk:\"  */
  835.         dirnm[--len] = '\0';    /* strip off trailing slash character */
  836.  
  837.     return(dirnm);
  838. }
  839. #endif
  840.  
  841.