Logo Search packages:      
Sourcecode: ksh version File versions  Download package

csclient.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1990-2007 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                                                                      *
***********************************************************************/
#pragma prototyped
/*
 * Glenn Fowler
 * AT&T Research
 *
 * client line by line interaction
 */

#include "cslib.h"

#include "FEATURE/termios"
#if !_lib_tcgetattr || !_lib_tcsetattr
#undef      _hdr_termios
#endif
#if _hdr_termios
#include <termios.h>
#endif

#if _hdr_termios

static struct State_s
{
      struct termios    new_term;   /* raw term for -r            */
      struct termios    old_term;   /* original term for -r       */
} state;

static void
restore(void)
{
      tcsetattr(0, TCSANOW, &state.old_term);
}

#endif

/*
 * if fd<0 then establish client connection to service
 * if argv specified then each is a command line to be executed
 * if CS_CLIENT_ARGV not set then additional commands read from stdin
 */

int
csclient(Cs_t* cs, int fd, const char* service, const char* prompt, char** argv, unsigned int flags)
{
      register int      i;
      char*       s;
      Sfio_t*           tmp;
      int         done;
      int         promptlen;
      int         timeout;
      ssize_t           n;
      int         sdf[2];
      Cspoll_t    fds[2];
      char        buf[8 * 1024];

      if (fd < 0 && (fd = csopen(cs, service, CS_OPEN_TEST)) < 0)
      {
            if (errno == ENOENT)
                  error(3, "%s: server not running", service);
            else
                  error(ERROR_SYSTEM|3, "%s: cannot open connect stream", service);
      }
#if _hdr_termios
      if (flags & CS_CLIENT_RAW)
      {
            tcgetattr(0, &state.old_term);
            atexit(restore);
            state.new_term = state.old_term;
            state.new_term.c_iflag &= ~(BRKINT|IGNPAR|PARMRK|INLCR|IGNCR|ICRNL);
            state.new_term.c_lflag &= ~(ECHO|ECHOK|ICANON|ISIG);
            state.new_term.c_cc[VTIME] = 0;
            state.new_term.c_cc[VMIN] = 1;
            tcsetattr(0, TCSANOW, &state.new_term);
      }
#endif
      sdf[0] = fd;
      sdf[1] = 1;
      if (argv && *argv)
      {
            fds[0].fd = 1;
            fds[0].events = CS_POLL_WRITE;
      }
      else
      {
            argv = 0;
            fds[0].fd = 0;
            fds[0].events = CS_POLL_READ;
      }
      fds[1].fd = fd;
      fds[1].events = CS_POLL_READ;
      done = 0;
      if (promptlen = (!argv && prompt && isatty(fds[0].fd) && isatty(1)) ? strlen(prompt) : 0)
            write(1, prompt, promptlen);
      timeout = CS_NEVER;
      tmp = 0;
      while (cspoll(cs, fds, elementsof(fds), timeout) > 0)
            for (i = 0; i < elementsof(fds); i++)
                  if (fds[i].status & (CS_POLL_READ|CS_POLL_WRITE))
                  {
                        if (!i && argv)
                        {
                              if (!*argv)
                              {
                                    argv = 0;
                                    fds[0].fd = 0;
                                    if (flags & CS_CLIENT_ARGV)
                                    {
                                          if (done++)
                                                return 0;
                                          timeout = 500;
                                    }
                                    fds[0].events = CS_POLL_READ;
                                    continue;
                              }
                              if (!tmp && !(tmp = sfstropen()))
                                    error(ERROR_SYSTEM|3, "out of space");
                              for (;;)
                              {
                                    s = *argv++;
                                    if ((flags & CS_CLIENT_SEP) && *s == ':' && !*(s + 1))
                                          break;
                                    if (sfstrtell(tmp))
                                          sfputc(tmp, ' ');
                                    sfprintf(tmp, "%s", s);
                                    if (!(flags & CS_CLIENT_SEP) || !*argv)
                                          break;
                              }
                              sfputc(tmp, '\n');
                              n = sfstrtell(tmp);
                              s = sfstruse(tmp);
                        }
                        else if ((n = read(fds[i].fd, s = buf, sizeof(buf) - 1)) < 0)
                              error(ERROR_SYSTEM|3, "/dev/fd/%d: read error", fds[i].fd);
                        if (!n)
                        {
                              if (done++)
                                    return 0;
                              if (!i)
                                    write(sdf[i], "quit\n", 5);
                              continue;
                        }
                        if (!i)
                        {
#if _hdr_termios
                              register char*    u;
                              register int      m;

                              s[n] = 0;
                              if ((u = strchr(s, 035)))
                              {
                                    if ((m = u - s) > 0 && write(sdf[i], s, m) != m)
                                          error(ERROR_SYSTEM|3, "/dev/fd/%d: write error", sdf[i]);
                                    tcsetattr(0, TCSANOW, &state.old_term);
                                    if (promptlen)
                                          write(1, prompt, promptlen);
                                    if ((n = read(fds[i].fd, s = buf, sizeof(buf) - 1)) <= 0)
                                    {
                                          write(1, "\n", 1);
                                          return 0;
                                    }
                                    buf[n - 1] = 0;
                                    if (*u == 'q' || *u == 'Q')
                                          return 0;
                                    tcsetattr(0, TCSANOW, &state.new_term);
                                    if (*u)
                                          error(1, "%s: unknown command", u);
                                    continue;
                              }
#endif
                        }
                        if (write(sdf[i], s, n) != n)
                              error(ERROR_SYSTEM|3, "/dev/fd/%d: write error", sdf[i]);
                        if (sdf[i] == 1 && promptlen)
                              write(1, prompt, promptlen);
                  }
      return error_info.errors != 0;
}

int
_cs_client(int fd, const char* service, const char* prompt, char** argv, unsigned int flags)
{
      return csclient(&cs, fd, service, prompt, argv, flags);
}

Generated by  Doxygen 1.6.0   Back to index