home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / ABUSESRC.ZIP / AbuseSrc / imlib / port / unix / jnet.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-24  |  6.8 KB  |  324 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <fcntl.h>
  4. #include <unistd.h>
  5. #include <sys/ioctl.h>
  6. #include <sys/stat.h>
  7. #include <sys/types.h>
  8. #include <sys/time.h>
  9. #include <string.h>
  10. #include <signal.h>
  11. #include <netinet/in.h>
  12. #include <sys/socket.h>
  13.  
  14. #ifdef __sgi
  15. #include <bstring.h>
  16. #endif
  17.  
  18. #ifdef _AIX
  19. #include <sys/select.h>
  20. #include <strings.h>
  21. extern "C" {
  22. #endif
  23. #include <netdb.h>
  24.  
  25. #ifdef _AIX
  26. } ;
  27. #endif
  28.  
  29. #include "jnet.hpp"
  30. #include "macs.hpp"
  31. #include "jmalloc.hpp"
  32.  
  33. int net_init(int protocol) 
  34.   if (protocol==TCPIP_PROTOCOL)    // UNIX always has TCPIP!
  35.     return 1;
  36.   else return 0;
  37. }
  38.  
  39.  
  40. out_socket::~out_socket()
  41. { ; }
  42.  
  43. void net_uninit() { ; }
  44.  
  45. char last_sock_err[200];
  46. int current_sock_err=0;
  47.  
  48. void set_sock_err(int x) { current_sock_err=x; }
  49.  
  50.  
  51. #define PK_BUFFER_SIZE 2000
  52.  
  53.  
  54.  
  55. class unix_out_socket : public out_socket
  56. {
  57.   int fd;
  58.   int type;      // SOCK_DGRAM, or SOCK_STREAM
  59.   public :
  60.   uchar pk_buffer[PK_BUFFER_SIZE];
  61.   long pk_buffer_ro,pk_buffer_last;
  62.   unix_out_socket(int FD) { fd=FD; pk_buffer_ro=pk_buffer_last=0; }
  63.   unix_out_socket();
  64.   void fill_buffer();
  65.   int get_fd() { return fd; }
  66.   virtual int try_connect(char *rhost, int port);
  67.   virtual int ready_to_read();
  68.   virtual int ready_to_write();
  69.   virtual int send(packet &pk);
  70.   virtual int get(packet &pk);
  71.   virtual ~unix_out_socket();
  72. } ;
  73.  
  74.  
  75. class unix_in_socket : public in_socket
  76. {
  77.   int fd;
  78.   sockaddr_in host;
  79.   int port;
  80.   public :
  81.   unix_in_socket(int Port);
  82.   virtual out_socket *check_for_connect();
  83.   virtual ~unix_in_socket();
  84. } ;
  85.  
  86.  
  87. int unix_out_socket::ready_to_read()
  88. {
  89.   if (pk_buffer_last>pk_buffer_ro) return 1;
  90.   struct timeval tv={0,0};
  91.   fd_set set,ex_set;
  92.   FD_ZERO(&set);
  93.   FD_SET(fd,&set);
  94.  
  95.   FD_ZERO(&ex_set);
  96.   FD_SET(fd,&ex_set);
  97.   select(FD_SETSIZE,&set,NULL,&ex_set,&tv);                // check for exception
  98.   return (FD_ISSET(fd,&set) || FD_ISSET(fd,&ex_set));
  99. }
  100.  
  101. int unix_out_socket::ready_to_write()
  102. {
  103.   struct timeval tv={0,0};
  104.   fd_set set,ex_set;
  105.   FD_ZERO(&set);
  106.   FD_SET(fd,&set);
  107.   select(FD_SETSIZE,NULL,&set,NULL,&tv);                // check for exception
  108.   return (FD_ISSET(fd,&set));
  109. }
  110.  
  111. unix_in_socket::unix_in_socket(int Port)
  112. {
  113.   port=Port;
  114.   fd=socket(AF_INET,SOCK_STREAM,0);
  115.   memset( (char*) &host,0, sizeof(host));
  116.   host.sin_family = AF_INET;
  117.   host.sin_port = htons(port);
  118.   host.sin_addr.s_addr = htonl (INADDR_ANY);
  119.   if (bind(fd, (struct sockaddr *) &host, sizeof(sockaddr_in))==-1)
  120.   {
  121.     set_sock_err(SOCK_BIND_FAIL);
  122.     sprintf(last_sock_err,"Unable to bind to port %d",port);
  123.   }
  124.   else
  125.   {
  126.     if (listen(fd,1)==-1)
  127.     {
  128.       set_sock_err(SOCK_LISTEN_FAIL);
  129.       sprintf(last_sock_err,"Unable to listen to port %d",port);      
  130.     }
  131.   }
  132.  
  133. }
  134.  
  135.  
  136. out_socket *unix_in_socket::check_for_connect()
  137.   struct timeval tv={0,0};
  138.   fd_set set,ex_set;
  139.   FD_ZERO(&set);
  140.   FD_SET(fd,&set);
  141.  
  142.  
  143.   select(FD_SETSIZE,&set,NULL,NULL,&tv);                // check for exception
  144.  
  145.   if (FD_ISSET(fd,&set))
  146.   {
  147.     int len=sizeof(sockaddr_in);
  148.     int new_fd=accept(fd, (struct sockaddr *) &host, &len);
  149.     if (new_fd<0)
  150.     {
  151.       set_sock_err(SOCK_ACCEPT_FAIL);
  152.       sprintf(last_sock_err,"Accept failure on port %d",port);      
  153.       return NULL;
  154.     }
  155.  
  156.     unsigned long gaddr=ntohl(host.sin_addr.s_addr);
  157.     return new unix_out_socket(new_fd);
  158.   } else return NULL;
  159. }
  160.   
  161.  
  162. unix_out_socket::unix_out_socket()
  163. {
  164.   pk_buffer_ro=pk_buffer_last=0;
  165.   fd=-1;
  166. }
  167.     
  168.  
  169. int unix_out_socket::try_connect(char *rhost, int port)
  170. {
  171.   if (strlen(rhost)>5 && 
  172.       rhost[0]=='t' && 
  173.       rhost[1]=='c' && 
  174.       rhost[2]=='p' &&
  175.       rhost[1]=='/')
  176.     type=SOCK_STREAM;
  177.   else type=SOCK_DGRAM;
  178.  
  179.   if (fd==-1)
  180.     fd=socket(AF_INET,type,0);
  181.   if (fd==-1)
  182.   {
  183.     set_sock_err(SOCK_CREATE_FAIL);
  184.     sprintf(last_sock_err,"Failed to create socket (too many file descriptors open?)");
  185.     return 0; 
  186.   }
  187.  
  188.   hostent *hp=gethostbyname(rhost);
  189.   if (!rhost)
  190.   {
  191.     set_sock_err(SOCK_NAMELOOKUP_FAIL);
  192.     sprintf(last_sock_err,"Unable to get address for name %s",rhost);      
  193.     return 0; 
  194.   } else
  195.   {
  196.     sockaddr_in host;
  197.     memset( (char*) &host,0, sizeof(host));
  198.     host.sin_family = AF_INET;
  199.     host.sin_port = htons(port);
  200.     host.sin_addr.s_addr = htonl (INADDR_ANY);
  201.     memcpy(&host.sin_addr,hp->h_addr,hp->h_length);
  202.     
  203.     if (connect(fd, (struct sockaddr *) &host, sizeof(host))==-1)
  204.     {
  205.       set_sock_err(SOCK_CONNECT_FAIL);
  206.       sprintf(last_sock_err,"Unable to connect to address %s on port %d",rhost,port);
  207.       return 0; 
  208.     }
  209.  
  210.     return 1;
  211.   }
  212. }
  213.  
  214.  
  215.  
  216. unix_out_socket::~unix_out_socket()
  217. {  close(fd); }
  218.  
  219. unix_in_socket::~unix_in_socket()
  220. {  close(fd);  }
  221.  
  222.  
  223. void unix_out_socket::fill_buffer()
  224. {
  225.   while (!ready_to_read()) ;
  226.   pk_buffer_last=read(get_fd(),pk_buffer,PK_BUFFER_SIZE);
  227.   pk_buffer_ro=0;
  228. }
  229.  
  230. int unix_out_socket::get(packet &pk)
  231.   pk.ro=pk.wo=2;
  232.  
  233.   ushort size=0;
  234.   if (pk_buffer_last==pk_buffer_ro)
  235.     fill_buffer();
  236.  
  237.   if (pk_buffer_last-pk_buffer_ro<2)  // make sure the two byte for the size are in the same packet
  238.   {
  239.     uchar two[2];
  240.     two[0]=pk_buffer[pk_buffer_ro];
  241.     fill_buffer();
  242.     if (pk_buffer_last-pk_buffer_ro<2)  // if still not enough info, something is screwy
  243.     {
  244.       printf("Incomplete packet\n");
  245.       return 0;
  246.     }
  247.  
  248.     two[1]=pk_buffer[pk_buffer_ro];
  249.     pk_buffer_ro++;
  250.     size=lstl((*((ushort *)two)));
  251.   } else
  252.   {
  253.     memcpy(&size,pk_buffer+pk_buffer_ro,2); pk_buffer_ro+=2;
  254.     size=lstl(size);
  255.   }
  256.   pk.rend=size+2;
  257.   pk.make_bigger(pk.rend);
  258.  
  259.   uchar *pk_off=pk.buf+2;
  260.   int rs;
  261.   while (size)
  262.   {
  263.     if (pk_buffer_last==pk_buffer_ro)
  264.       fill_buffer();    
  265.     if (pk_buffer_last-pk_buffer_ro>size)
  266.       rs=size;
  267.     else
  268.       rs=pk_buffer_last-pk_buffer_ro;
  269.     
  270.     memcpy(pk_off,pk_buffer+pk_buffer_ro,rs);
  271.     pk_buffer_ro+=rs;
  272.     size-=rs;
  273.     pk_off+=rs;         
  274.   }
  275.   
  276.   return 1;
  277. }
  278.  
  279. int unix_out_socket::send(packet &pk)
  280. {  
  281.   while (!ready_to_write()) ;
  282.   ushort size=lstl(pk.wo-2);
  283.   memcpy(pk.buf,&size,2);
  284.   return write(fd,pk.buf,pk.wo)==pk.wo;
  285. }
  286.  
  287. in_socket *create_in_socket(int port)
  288. { return new unix_in_socket(port); }
  289.  
  290. out_socket *create_out_socket(char *name, int port)
  291. { unix_out_socket *s=new unix_out_socket();
  292.   if (s->try_connect(name,port))
  293.     return s;
  294.   else   
  295.     delete s;
  296.   return NULL;
  297. }
  298.  
  299. uchar *get_local_address()                             // same format as above (be sure to jfree this)
  300. {
  301.   char name[80];
  302.   uchar *ip=(uchar *)jmalloc(4,"IP address");
  303.  
  304.   if (gethostname(name,80)!=0)
  305.   { ip[0]=127; ip[1]=ip[2]=0; ip[3]=1; }
  306.   else
  307.   {
  308.     struct hostent *me=gethostbyname(name);
  309.     memcpy(ip,me->h_addr,4);
  310.   }
  311. }
  312.  
  313.  
  314.  
  315.  
  316.  
  317.  
  318.  
  319.  
  320.  
  321.