Logo Search packages:      
Sourcecode: ksh version File versions

ifs_network.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*           Copyright (c) 1990-2007 AT&T Knowledge Ventures            *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                      by AT&T Knowledge Ventures                      *
*                                                                      *
*                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>                  *
*                                                                      *
***********************************************************************/
/*
 * File: ifs_network.c
 */

#include "ifs_agent.h"
#include <cs.h>
#include <error.h>

/*
 *name: NetFillCache
 *    read data from network to cache buffer
 * rtn:     -1    if timeout
 *     0    if end-of-file or IfsAbort
 *    size  if read successful
 */
int
NetFillCache( nFile, timeout )
NetFile     *nFile;
int   timeout;
{
    int           rtn, num;
    Cs_poll_t     fds;

    if( IfsAbortFlag ) {
      nFile->size = 0;
      return 0;
    }
    nFile->err = 0;
    /* move the cache data to the beginning of netbuf */
    if( nFile->size > 0 ) {
      if( nFile->size >= sizeof(nFile->netbuf) )
          return sizeof(nFile->netbuf);   /* cache buffer full */
      memcpy( nFile->netbuf, nFile->netbuf + nFile->head, nFile->size );
    }
    nFile->head = 0;

    fds.fd = nFile->socket;
    fds.events = CS_POLL_READ;
    while( 1 ) {
      rtn = cspoll( &fds, 1, timeout );
      if( rtn >= 0 )  break;

      /* error occured in select call */
      nFile->err = errno;
      if( errno != EINTR ) {
          logit( "NetRead: select error\n" );
          break;
      }
      if( IfsAbortFlag == 1 ) {
          nFile->size = 0;
          return 0;
      }
      logit( "NetRead: bypass signal\n" );
    }

    if( rtn == 0 ) {
      /* select timeout */
      if( timeout > 0 )
          logit( "NetRead: timeout\n" );
      return -1;
    } else if( fds.status == CS_POLL_READ ) {
      num = sizeof(nFile->netbuf) - nFile->size;
      num = read( fds.fd, nFile->netbuf + nFile->size, num );
      if( num > 0 )
          nFile->size += num;
    }
    return nFile->size;
}

/*
 *name: NetDataReady
 *    check if data ready in the cache or network buffer
 *    try read from network if the cache buffer is empty
 */
int
NetDataReady( nFile )
NetFile     *nFile;
{
    if( nFile->size == 0 )
      NetFillCache( nFile, 0 );
    return nFile->size;
}

/*
 *name: NetEOF
 *    check if the network is closed
 */
int
NetEOF( nFile )
NetFile     *nFile;
{
    if( nFile->size > 0 ) {         /* data exists */
      return 0;
    }
    if( NetFillCache( nFile, 0 ) == 0 && nFile->size == 0 ) {
      /* read successful & no data ready */
      return 1;
    }
    return 0;
}

/*
 *name: NetRead
 *    read a block of memory from NetFile.
 *    read to nFile->buf in NetFile if buf is NULL
 */
int
NetRead( nFile, buf, bufsize )
NetFile     *nFile;
char  *buf;
int   bufsize;
{
    int           readlen;
    int           len;

    if( IfsAbortFlag || nFile == NULL || buf == NULL )
      return -1;
    nFile->err = 0;
    readlen = 0;
    while( 1 ) {
      /* read data from cache buf */
      if( (len = nFile->size) > 0 ) {
          if( len > bufsize )
            len = bufsize;
          memcpy( buf, nFile->netbuf + nFile->head, len );
          nFile->head += len;
          nFile->size -= len;
          readlen += len;
          if( len >= bufsize )
            return readlen;         /* buffer full */
          buf += len;
          bufsize -= len;
      }
      if( NetFillCache( nFile, SOCK_TIMEOUT ) == -1 || nFile->size == 0 ) {
          return( readlen > 0 ? readlen : -1 );
      }
    }
}

/*
 *name: NetGets
 *    read a string (end with '\n') from NetFile.
 */
char*
NetGets( nFile, buf, bufsize )
NetFile     *nFile;
char  *buf;
int   bufsize;
{
    char    *ptr;

    if( IfsAbortFlag || nFile == NULL || buf == NULL )
      return NULL;
    ptr = buf;
    while( bufsize > 1 && NetRead( nFile, ptr, 1 ) == 1 ) {
      bufsize--;
      if( *ptr++ == '\n' )
          break;
    }
    *ptr = '\0';
    return( ptr == buf ? NULL : buf );
}

/*
 *name: NetWrite
 *    write a block of memory to Netfile
 */
int
NetWrite( nFile, buf, bufsize )
NetFile     *nFile;
char  *buf;
int   bufsize;
{
    int           fd, writelen, len;

    if( IfsAbortFlag || nFile == NULL || buf == NULL )
      return -1;
    fd = nFile->socket;
    writelen = 0;
    while( bufsize > 0 ) {
      len = write( fd, buf, bufsize );
      if( len <= 0 ) {
          nFile->err = errno;
          break;
      }
      buf += len;
      bufsize -= len;
      writelen += len;
    }
    return writelen;
}

/*
 *name: NetClose
 *    close a network file opened by NetConnect
 */
int
NetClose( nFile )
NetFile     *nFile;
{
    int           rtn;

    if( nFile == NULL )
      return -1;
    rtn = close( nFile->socket );
    free( nFile );
    return rtn;
}

/*
 *name: NetConnect
 *    make a socket connection to host:port.
 *    connect to proxy hosts if proxy flag is on.
 */
NetFile *
NetConnect( srv, host, port )
struct server_info      *srv;
char              *host;
int               port;
{
    static struct server_info nilsrv;
    NetFile*            nFile;
    unsigned long addr;
    int                 fd;
    char          buf[ STRLEN ];

    if ((srv->flags & IFS_PROXY) || !(addr = csaddr(host)) && srv->proxy) {
      nFile = NetConnect( &nilsrv, srv->proxy ? srv->proxy : PROXY_HOST, PROXY_PORT );
      if( nFile == NULL )
          return NULL;
      sfsprintf( buf, sizeof(buf), "\ntcp!%s!%d\n\n%s\nvcs\n0\n-1\n-1\n",
                  host, port, csname(0) );
      NetWrite( nFile, buf, strlen(buf) );
      if( NetGets( nFile, buf, sizeof(buf) ) != NULL &&
          strcmp( buf, "0\n" ) == 0 ) {
          NetGets( nFile, buf, sizeof(buf) );
          logit( "proxy reply: " );
          logit( buf );
          return nFile;
      }
      NetClose( nFile );
      return NULL;
    }
    if (!addr) {
      cserrno = E_GETHOST;
      return NULL;
    }
    if( (fd = csbind( "tcp", addr, port, 0 )) < 0 )
      return NULL;
    if (!(nFile = (NetFile*)malloc(sizeof(NetFile))))
      return NULL;
    nFile->socket = fd;
    nFile->head = 0;
    nFile->size = 0;
    nFile->err = 0;
    return nFile;
}

Generated by  Doxygen 1.6.0   Back to index