The DejaVU Framework -- hush 3.0
[.] Papers Tutorials Examples Manuals Interfaces Sources Packages Resources ?

source: samlib.c hush-3.0b4/auxiliary/net/cs


[.] - [up] [top] - index README make include source scripts configure
  // samlib.cc
  // Miscellaneous handy functions
  
  // 26-01-1996: creation
  
  include <net/cs/samlib.h>
  
  include <errno.h>
  include <fcntl.h>
  include <stdarg.h>
  include <stdio.h>
  include <stdlib.h>
  include <string.h>
  include <termios.h>
  include <unistd.h>
  include <sys/fcntl.h>
  include <sys/ioctl.h>
  include <sys/time.h>
  include <sys/types.h>
  include <netinet/in.h>
  
  const char* log_file_name = "error.log";
   
  bool log_active = false;
   
  static bool log_opened = false;
  static FILE* fd_log = NULL;
  
  bool data_available(int fd)
  {
      fd_set readfds;
      timeval tv;
  
      FD_ZERO(&readfds);
      FD_SET(fd, &readfds);
      tv.tv_sec = 0;
      tv.tv_usec = 0;
      return select(fd+1, &readfds, NULL, NULL, &tv) == 1;
  }
  
  int read_nonblock(int fd, char* buf, int maxbytes)
  {
      int flags, oldflags, rc;
   
      flags = fcntl(fd, F_GETFL);
      if (flags == -1)
      {
          fprintf(stderr, "read_nonblock : fcntl F_GETFL failed\n");
          return -1;
      }
   
      oldflags = flags;
      flags |= O_NONBLOCK;
   
      if (fcntl(fd, F_SETFL, flags) == -1)
      {
          fprintf(stderr, "read_nonblock : fcntl F_SETFL failed\n");
          return false;
      }
   
      rc = ::read(fd, buf, maxbytes);
   
      if (fcntl(fd, F_SETFL, oldflags) == -1)
      {
          fprintf(stderr, "read_nonblock : fcntl F_SETFL 2 faild\n");
      }
   
      return rc;
  }
  
  void warn(const char* str, ...)
  {
      va_list v;
  
      va_start(v, str);
      vfprintf(stderr, str, v);
      fprintf(stderr, "\n");
  }
  
  void halt(const char* str, ...)
  {
      va_list v;
  
      fprintf(stderr, "\n");
      va_start(v, str);
      vfprintf(stderr, str, v);
      fprintf(stderr, "\n");
  
      exit (1);
  }
  
  byte* safe_alloc (size_t size, const char* func_name)
  {
      byte* p = NULL;
  
      if ((p = (byte*) malloc(size)) == NULL)
      {
          if (func_name != NULL)
              halt("(%s) safe_alloc: Couldn't allocate %lu bytes", func_name, 
                   size); 
          else
              halt("safe_alloc: Couldn't allocate %lu bytes", func_name, size);
      }
  
  // DEBUG
      if (func_name != NULL)
          write_to_log ("(%s) safe_alloc : %u bytes allocated, ptr = %p", 
                        func_name, size, p);
      else
          write_to_log ("safe_alloc : %u bytes allocated, ptr = %p", size, p);
  
      return p;
  }
  
  void safe_free (byte*& p, const char* func_name)
  {
      if (func_name != NULL)
          write_to_log("(%s) freeing ptr %p", func_name, p);
      else
          write_to_log("freeing ptr %p", p);
   
      free(p);
      p = NULL;
  }
  
  void write_to_log (const char* logstr, ...)
  {
      va_list v;
  
      if (!log_active)
          return;
   
      if (!log_opened)
      {
          if ((fd_log = fopen (log_file_name, "wb")) == NULL)
              halt ("Couldn't open logfile");
          log_opened = true;
      }
  
      va_start (v, logstr);
      vfprintf (fd_log, logstr, v);
      fprintf (fd_log, "\n");
  }
  
  int read_package(int fd, char* buf, int maxnrbytes)
  {
      char mybuf[256];
  
      long received = 0;
      int total_received = 0;
      int nsize, hsize;
  
      if (read(fd, &nsize, sizeof(nsize)) != sizeof(nsize))
      {
          warn("read_package : couldn't read size (%s)\n", strerror(errno));
          return -1;
      }
      hsize = ntohl(nsize);
  
      while (total_received < hsize)
      {
          if (total_received < maxnrbytes)
          {
              int max_receive = MIN(hsize - total_received,
                                    maxnrbytes - total_received);
              received = read(fd, buf + total_received, max_receive);
          }
          else
          {
              int max_receive = MIN(hsize - total_received, (int)sizeof(mybuf));
              received = read(fd, mybuf, max_receive);
          }
  
          if (received <= 0)
          {
              warn("read_package : couldn't read data (%s)\n",
                   strerror(errno));
              return -1;
          }
          total_received += received;
      }
      return MIN(total_received, maxnrbytes);
  }
  
  // method used is not the most efficient, but it is the safest way since
  // most messages are written atomicly
  int write_package(int fd, const char* buf, int nrbytes)
  {
      char* mybuf;
      int sent = 0, total_sent = 0;
  
      ulong nsize = htonl(nrbytes);
      if ((mybuf = (char*)malloc(nrbytes + sizeof(nsize))) == NULL)
          return -1;
      memcpy(mybuf, &nsize, sizeof(nsize));
      memcpy(mybuf + sizeof(nsize), buf, nrbytes);
  
      nrbytes += sizeof(nsize);
  
      while (total_sent < nrbytes)
      {
          sent = write(fd, mybuf, nrbytes - total_sent);
          if (sent <= 0)
          {
              warn("write_package : couldn't write data (%s)\n",
                   strerror(errno));
              free(mybuf);
              return -1;
          }
          total_sent += sent;
      }
      free(mybuf);
      return total_sent - sizeof(nsize);  // return only amount of data sent
  }
  
  static struct termios graph_termio; /* graphics mode termio parameters */
  static struct termios text_termio; /* text mode termio parameters */
  
  void unbuffer_stdin()
  {
      /* save text mode termio parameters */
      ioctl(0, TCGETS, &graph_termio);
      text_termio = graph_termio;
   
      /* change termio parameters to allow our own I/O processing */
      graph_termio.c_iflag &= ~(BRKINT|PARMRK|INPCK|IUCLC|IXON|IXOFF);
      graph_termio.c_iflag |=  (IGNBRK|IGNPAR);
   
      graph_termio.c_oflag &= ~(ONOCR);
   
      graph_termio.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|NOFLSH);
      graph_termio.c_lflag |= (ISIG);   /* enable interrupt */
   
      graph_termio.c_cc[VMIN] = 1;
      graph_termio.c_cc[VTIME] = 0;
      graph_termio.c_cc[VSUSP] = 0;   /* disable suspend */
   
      /* set graphics mode termio parameters */
      ioctl(0, TCSETSW, &graph_termio);
  }
  
  void restore_stdin()
  {
      ioctl(0, TCSETSW, &text_termio);
  }
  
  void unbuffer_stdout()
  {
      setvbuf(stdout, NULL, _IONBF, 0);
  }
  

[.] Papers Tutorials Examples Manuals Interfaces Sources Packages Resources ?
Hush Online Technology
hush@cs.vu.nl
09/09/98