1.  /* TLICatty v3 dedicated client
  2.   * (c) Copyright 2005 Michal Spadlinski <gim@skrzynka.pl> http://gim.org.pl
  3.   *
  4.   */
  5.  
  6.  #define __EXTENSIONS__ /* Solaris setbuffer(),fdopen() */
  7.  #define __USE_BSD /* Linux setbuffer() */
  8.  #include <stdio.h>
  9.  #include <stdlib.h>
  10.  #include <string.h>
  11.  #define __EXTENSIONS__ /* Solaris bzero() */
  12.  #define __USE_XOPEN_EXTENDED /* Linux bzero() */
  13.  #include <strings.h>
  14.  #include <time.h>
  15.  #include <signal.h>
  16.  #include <unistd.h>
  17.  #define _XOPEN_SOURCE
  18.  #include <xti.h>
  19.  #include <fcntl.h>
  20.  
  21.  #include <arpa/inet.h>
  22.  #include <netinet/in.h>/* INADDR_ANY */
  23.  #include <sys/select.h>
  24.  #include <sys/socket.h>/* AF_INET */
  25.  #include <sys/stropts.h>
  26.  #include <sys/types.h>
  27.  #include <sys/wait.h>
  28.  #include <sys/time.h>
  29.  #include <netdb.h>
  30.  #include <unistd.h>
  31.  
  32.  #define DEF_PORT 0xdeaf
  33.  /* powinno byc tak jak to z config.h z tlicatty */
  34.  #define MAXBUF 10240
  35.  
  36.  #ifndef HL_AIX
  37.  #define DEF_T_OPEN_TCP_IPV4 "/dev/tcp" /* device-name TCP IP V 4 */
  38.  #else
  39.  #define DEF_T_OPEN_TCP_IPV4 "/dev/xti/tcp" /* device-name TCP */
  40.  #endif
  41.  
  42.  extern int t_errno;
  43.  
  44.  int cl_transport = 0;
  45.  
  46.  void sigchld_handler (int sig)
  47.  {
  48.   int pid;
  49.  
  50.   while ((pid = waitpid (-1, NULL, WNOHANG)) > 0);
  51.   signal (SIGCHLD, sigchld_handler);
  52.  }
  53.  
  54.  void sigint_handler(int sig)
  55.  {
  56.   printf("\n (G+) SIGINT cought! Closing connection\n");
  57.   t_snddis(cl_transport, NULL);
  58.   t_unbind(cl_transport);
  59.   t_close(cl_transport);
  60.   exit(0);
  61.  }
  62.  
  63.  int check_discon(int fd)
  64.  {
  65.   if (t_errno == TLOOK) {
  66.   if (t_look(fd) == T_DISCONNECT)
  67.   {
  68.   t_rcvdis(fd, NULL);
  69.   t_unbind(fd);
  70.   t_close(fd);
  71.   printf(" (G-) server closed connection\n");
  72.   return 1;
  73.   }
  74.   }
  75.   return 0;
  76.  }
  77.  int main(int argc, char **argv)
  78.  {
  79.   int fl, n, rurka[2], child, ret;
  80.   struct sockaddr_in serv;
  81.   struct t_call make_a_call;
  82.   struct hostent *host_info;
  83.   struct timeval tv;
  84.   char buf[MAXBUF];
  85.   fd_set readset;
  86.  
  87.   if (argc < 3)
  88.   {
  89.   printf("usage: %s hostname nickname\n", argv[0]);
  90.   return 1;
  91.   }
  92.   signal(SIGINT, SIG_IGN);
  93.   setbuffer(stdout, 0, 0);
  94.   if (pipe(rurka) < 0)
  95.   {
  96.   perror(" (G!) pipe()");
  97.   return 1;
  98.   }
  99.  
  100.   if ((cl_transport = t_open(DEF_T_OPEN_TCP_IPV4, O_RDWR, 0)) < 0)
  101.   {
  102.   t_error(" (G!) t_open()");
  103.   return 1;
  104.   }
  105.   printf(" (G+) endpoint opened\n");
  106.  
  107.   /* chcemy jakikolwiek adres lokalny */
  108.   if (t_bind(cl_transport, NULL, NULL) < 0)
  109.   {
  110.   t_error(" (G!) t_bind()");
  111.   t_close(cl_transport);
  112.   return 1;
  113.   }
  114.   printf(" (G+) endpoint binded\n");
  115.  
  116.   bzero((char *)&serv, sizeof(struct sockaddr_in));
  117.   serv.sin_family = AF_INET;
  118.  
  119.   if ((child = fork()) < 0)
  120.   {
  121.   printf(" (G+) running synchronous resolver\n");
  122.   close(rurka[0]);
  123.   close(rurka[1]);
  124.   if ((host_info = gethostbyname(argv[1])) != NULL) {
  125.   memcpy(&serv.sin_addr, host_info->h_addr, sizeof(struct in_addr));
  126.   } else {
  127.   perror(" (G!) gethostbyname()");
  128.   t_snddis(cl_transport, NULL);
  129.   t_unbind(cl_transport);
  130.   t_close(cl_transport);
  131.   return 0;
  132.   }
  133.   printf(" (G+) address resolved: %s\n",inet_ntoa(serv.sin_addr));
  134.   } else if (child == 0) {
  135.   close(rurka[0]);
  136.   host_info = gethostbyname(argv[1]);
  137.   if (host_info == NULL)
  138.   {
  139.   write(rurka[1], host_info->h_addr, 1);
  140.   close(rurka[1]);
  141.   exit(1);
  142.   }
  143.   write(rurka[1], host_info->h_addr, sizeof(struct in_addr));
  144.   close(rurka[1]);
  145.   exit (0);
  146.   } else {
  147.   printf(" (G+) running asynchronous resolver\n");
  148.   close(rurka[1]);
  149.   do {
  150.   tv.tv_sec = 0;
  151.   tv.tv_usec = 10;
  152.   FD_ZERO(&readset);
  153.   FD_SET(rurka[0], &readset);
  154.   printf(".");
  155.   } while ((ret=select(rurka[0]+1, &readset, NULL, NULL,
  156.   &tv)) ==0);
  157.   printf("\n");
  158.  
  159.   if (ret>0) {
  160.   waitpid(child, NULL, 0);
  161.   ret = read(rurka[0], &serv.sin_addr,
  162.   sizeof(struct in_addr));
  163.   if (ret == sizeof(struct in_addr))
  164.   printf(" (G+) address resolved: %s\n", inet_ntoa(serv.sin_addr));
  165.   else
  166.   ret = -2;
  167.   }
  168.   if (ret <0) {
  169.   if (ret == -1)
  170.   perror(" (G!) select()");
  171.   else
  172.   perror(" (G!) read()");
  173.   t_snddis(cl_transport, NULL);
  174.   t_unbind(cl_transport);
  175.   t_close(cl_transport);
  176.   return 1;
  177.   }
  178.   }
  179.   /*serv.sin_addr.s_addr = inet_addr(argv[1]);*/
  180.   serv.sin_port = htons(DEF_PORT);
  181.  
  182.   bzero((char *)&make_a_call, sizeof(struct t_call));
  183.   make_a_call.addr.maxlen = sizeof(struct sockaddr_in);
  184.   make_a_call.addr.len = sizeof(struct sockaddr_in);
  185.   make_a_call.addr.buf = (char *) &serv;
  186.   make_a_call.opt.maxlen = 0;
  187.   make_a_call.opt.len = 0;
  188.   make_a_call.udata.maxlen = 0;
  189.   make_a_call.udata.len = 0;
  190.  
  191.   if (t_connect(cl_transport, &make_a_call, NULL) < 0)
  192.   {
  193.   if (check_discon(cl_transport))
  194.   return 1;
  195.   t_error(" (G!) t_connect()");
  196.   t_unbind(cl_transport);
  197.   t_close(cl_transport);
  198.   return 1;
  199.   }
  200.   printf(" (G+) We're in! Waiting for user input\n");
  201.  
  202.   signal(SIGINT, sigint_handler);
  203.   while(1)
  204.   {
  205.   if (!argv[3])
  206.   printf("<%s> ", argv[2]);
  207.   if(fgets(buf, MAXBUF, stdin) == NULL)
  208.   break;
  209.  
  210.   if (t_snd(cl_transport, buf, strlen(buf), 0) != strlen(buf))
  211.   {
  212.   if (check_discon(cl_transport))
  213.   return 1;
  214.   t_error(" (G!) t_snd()");
  215.   t_unbind(cl_transport);
  216.   t_close(cl_transport);
  217.   return 1;
  218.   }
  219.   /*printf(" (G+) data sent\n");*/
  220.   if ((n=t_rcv(cl_transport, buf, MAXBUF-1, &fl)) <0)
  221.   {
  222.   if (check_discon(cl_transport))
  223.   return 1;
  224.   t_error(" (G!) t_rcv()");
  225.   t_unbind(cl_transport);
  226.   t_close(cl_transport);
  227.   return 1;
  228.   }
  229.   buf[n] = 0;
  230.   if (!argv[3])
  231.   printf("<cattyv3> ");
  232.   printf(buf);
  233.   }
  234.   printf("\n (G+) Closing connection\n");
  235.   t_snddis(cl_transport, NULL);
  236.   t_unbind(cl_transport);
  237.   t_close(cl_transport);
  238.   return 0;
  239.  }

This document should validate, please check by clicking: Valid XHTML 1.1