home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / Portable Patmos / src / portable kernel / ncsasock / rexec.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-12  |  4.5 KB  |  222 lines  |  [TEXT/R*ch]

  1. /*
  2.  * BSD-style socket emulation library for the Mac
  3.  * Original author: Tom Milligan
  4.  * Current author: Charlie Reiman - creiman@ncsa.uiuc.edu
  5.  *
  6.  * This source file is placed in the public domian.
  7.  * Any resemblance to NCSA Telnet, living or dead, is purely coincidental.
  8.  *
  9.  *      National Center for Supercomputing Applications
  10.  *      152 Computing Applications Building
  11.  *      605 E. Springfield Ave.
  12.  *      Champaign, IL  61820
  13.  */
  14.  
  15. /*
  16.  * rexec.c
  17.  * Mac implimentation of rexec. Uses NCSA MacTCP sockets.
  18.  * Written by Charlie Reiman - Tom actually had nothing to do with this file
  19.  * Started Friday, July 13, 1990 10:04:33 AM
  20.  */
  21.  
  22. # include <Events.h>
  23. # include <Types.h>
  24. # include <Stdio.h>
  25.  
  26. # include <s_types.h>
  27. # include <netdb.h>
  28. # include <neti_in.h>
  29. # include <s_socket.h>
  30. # include <s_time.h>
  31. # include <neterrno.h>
  32. # include <string.h>
  33.  
  34. # include <MacTCPCommonTypes.h>
  35.  
  36. #include "rexec.h"
  37. #include "sock_ext.h"        /* uses only high level calls */
  38.  
  39. #define BUFZ 256
  40.  
  41. #ifndef min
  42. #define min(a,b) ( ( a < b ) ? a : b )
  43. #endif
  44.  
  45. #define NIL NULL
  46. #define DOERR    if ( anErr < 0 ) return anErr;
  47.  
  48. extern    int    errno;
  49.  
  50. int rexec(
  51.     char **ahost,
  52.     Int4 inport,
  53.     char *user,
  54.     char *passwd,
  55.     char *cmd,
  56.     int *fd2p)
  57.     
  58.     {
  59.     struct    hostent *hp;
  60.     struct  sockaddr_in    sa,me,her;
  61.     int        sockOut;
  62.     int        anErr;        /* an error? */
  63.     Int4     herlen = sizeof(her),melen;
  64.     char    wbuf[BUFZ];
  65.     
  66.     
  67.     hp=gethostbyname(*ahost);
  68.  
  69.  
  70.     if ( hp == NULL )
  71.         {
  72.         int        a,b,c,d;
  73.         
  74.         if ( sscanf(*ahost,"%d.%d.%d.%d",&a,&b,&c,&d) != 4 )
  75.             {
  76.             errno = errno_long = EHOSTUNREACH;
  77.             return -1;
  78.             }
  79.         else
  80.             {
  81.             herlen = (a<<24) | ( b<<16) | (c<<8) | (d);
  82.             bcopy(&herlen,&sa.sin_addr,4);
  83.             }
  84.         }
  85.     else
  86.         bcopy((void *)hp->h_addr,&sa.sin_addr,hp->h_length);
  87.  
  88.     
  89.     sa.sin_port=htons(inport);
  90.     sa.sin_family=AF_INET;
  91.  
  92.     sockOut=s_socket(AF_INET,SOCK_STREAM,0);
  93.     
  94.     if (sockOut<0)
  95.         {
  96.         return -1;
  97.         }
  98.     
  99.     if (s_connect(sockOut,(struct sockaddr *)&sa,sizeof(sa))<0)
  100.         {
  101.         return -1;
  102.         }
  103.         
  104.     if (fd2p)
  105.         {
  106.         /* create listening socket */
  107.         *fd2p=s_socket(AF_INET,SOCK_STREAM,0);
  108.  
  109.         bzero((char *)&me, sizeof(me));
  110.         me.sin_family = AF_INET;
  111.         me.sin_port = htons(0);        /* any port */
  112.         
  113.         if (s_bind(*fd2p, (struct sockaddr *)&me, sizeof(me) ) < 0)
  114.             {
  115.             return -1;
  116.             }
  117.  
  118.         if (s_listen(*fd2p,1) < 0)
  119.             {
  120.             /* 
  121.              * s_listen is the routine that actuall puts the correct
  122.              * IP address to the socket. Up to this point, the socket
  123.              * has had an address of 0, port 0.
  124.              */
  125.             return -1;
  126.             }
  127.         /*
  128.          * Now we must fetch the number of the port so we can tell
  129.          * the rexecd where to find us.
  130.          */
  131.         melen=sizeof(me);
  132.         s_getsockname(*fd2p, (struct sockaddr *)&me , &melen);
  133.         sprintf(wbuf,"%d\0",(long)me.sin_port);    /* tell rexec where to hook up to */
  134.         }
  135.     else
  136.         *wbuf='\0';        /* pass an empty string for no stderr port */
  137.         
  138.     anErr = s_write (sockOut,wbuf,strlen(wbuf)+1);        /* write out string */
  139.     
  140.     DOERR
  141.     
  142.     if (fd2p)    /* do we need to accept? */
  143.         {
  144.         struct        timeval selectPoll;
  145.         fd_set        readfds;
  146.         
  147.         selectPoll.tv_sec=60;    /* block for one minute */
  148.         selectPoll.tv_usec=0;
  149.         FD_ZERO(&readfds);
  150.         FD_SET(*fd2p,&readfds);    /* only looking for connect on one socket */
  151.         
  152.         anErr = s_select(32, &readfds, (fd_set *)0,
  153.                 (fd_set *)0, &selectPoll);
  154.         
  155.         if (anErr < 1 )
  156.             return -1;            
  157.             
  158.         anErr = s_accept_once(*fd2p,(struct sockaddr *)&her,&herlen);
  159.         /*
  160.          * might want to check and make sure that the connected machine
  161.          * is the right one, but that seems a bit execessive.
  162.          */
  163.         DOERR
  164.         
  165.         }
  166.         
  167.     anErr = s_write (sockOut,user,strlen(user)+1);
  168.     DOERR
  169.     anErr = s_write (sockOut,passwd,strlen(passwd)+1);
  170.     DOERR
  171.     anErr = s_write (sockOut,cmd,strlen(cmd)+1);
  172.     DOERR
  173.     
  174.     /*
  175.      * Hey, wouldn't it be great if rexec sent encrypted passwords?
  176.      * And wouldn't it be great if it sent along a case of a really good beer?
  177.      * Like Keystone!
  178.      */
  179.      
  180.     anErr = s_read (sockOut,wbuf,1);    /* fetch answer */
  181.     DOERR
  182.     
  183.     if (*wbuf!=0)
  184.         {
  185.         errno = errno_long = EACCES;
  186.         return -1;  /* permission denied! */
  187.         }
  188.     
  189.     return sockOut;
  190.     }
  191.  
  192. /*
  193.  * Polls an exisiting stderr hookup from a previous rexec for any error
  194.  * text. If there is, it will be returned in str, up to strln bytes
  195.  *
  196.  * Assumes sock is connected properly and str is not null.
  197.  */
  198. int rexecerr(Int4 sock,char *str,Int4 strln)
  199.     {
  200.     fd_set    rfds;
  201.     struct    timeval tv;
  202.     int        selectcode;
  203.     
  204.     FD_ZERO(&rfds);
  205.     
  206.     FD_SET(sock,&rfds);
  207.     
  208.     tv.tv_sec=1;
  209.     tv.tv_usec=0;
  210.     
  211.     selectcode = s_select(sock+1,&rfds,(fd_set *)NULL,(fd_set *)NULL,&tv);
  212.     
  213.     if ( selectcode < 0 )
  214.         return -1;
  215.     else if ( !selectcode )
  216.         return 0;
  217.     else
  218.         if (s_read(sock,str,strln)<0)
  219.             return -1;
  220.         return 1;
  221.     
  222.     }