/********************************************************************
* FUNCTION init_subsys
*
* Initialize the subsystem, and get it ready to send and receive
* the first message of any kind
* 
* RETURNS:
*   status
*********************************************************************/
static status_t
    init_subsys (void)
{
    char *cp, *con;
    int   ret;

    client_addr = NULL;
    port = NULL;
    user = NULL;
    ncxsock = -1;
    ncxconnect = FALSE;


    /* get the client address */
    con = getenv("SSH_CONNECTION");

    if (!con) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): "
                       "Get SSH_CONNECTION variable failed\n" );
        return ERR_INTERNAL_VAL;
    }

    /* get the client addr */
    client_addr = strdup(con);
    if (!client_addr) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): strdup(client_addr) failed\n" );
        return ERR_INTERNAL_MEM;
    }
    cp = strchr(client_addr, ' ');
    if (!cp) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): "
                       "Malformed SSH_CONNECTION variable\n" );
        return ERR_INTERNAL_VAL;
    } else {
        *cp = 0;
    }

    /* get the server connect port */
    cp = strrchr(con, ' ');
    if (cp && cp[1]) {
        port = strdup(++cp);
    }
    if (!port) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): "
                       "Malformed SSH_CONNECTION variable\n" );
        return ERR_INTERNAL_VAL;
    }
        
    /* get the username */
    cp = getenv("USER");
    if (!cp) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): Get USER variable failed\n");
        return ERR_INTERNAL_VAL;
    }
    user = strdup(cp);
    if (!user) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): strdup(user) failed\n" );
        return ERR_INTERNAL_MEM;
    }

    /* make a socket to connect to the NCX server */
    ncxsock = socket(PF_LOCAL, SOCK_STREAM, 0);
    if (ncxsock < 0) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): NCX Socket Creation failed\n" );
        return ERR_NCX_CONNECT_FAILED;
    } 
    ncxname.sun_family = AF_LOCAL;

    /* --------- LEVI --------- */
    char begin[16] = "/tmp/ncxserver_";
    char end[6] = ".sock";
    sprintf(NCX_SOCKETFILE,"%s%s%s",begin,port,end);

    fprintf(errfile,
    		"\n\n====================\n"
    		"Incoming session\n"
    		"--------------------\n"
    		"Client address: %s\n"
    		"User: %s\n"
    		"NETCONF Port: %s\n"
    		"Socket file: %s\n"
    		"====================\n",
    		client_addr,
    		user,
    		port,
    		NCX_SOCKETFILE);
    fflush(errfile);

    strncpy(ncxname.sun_path,
                NCX_SOCKETFILE,
                sizeof(ncxname.sun_path));


//    strncpy(ncxname.sun_path,
//            NCXSERVER_SOCKNAME,
//            sizeof(ncxname.sun_path));

    /* -------- END LEVI --------- */

    /* try to connect to the NCX server */
    ret = connect(ncxsock,
                  (const struct sockaddr *)&ncxname,
                  SUN_LEN(&ncxname));
    if (ret != 0) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): NCX Socket Connect failed\n" );
        return ERR_NCX_OPERATION_FAILED;
    } else {
        SUBSYS_TRACE2( "INFO:  init_subsys(): "
                       "NCX Socket Connected on FD: %d \n", ncxsock );
        ncxconnect = TRUE;
    }

#ifdef USE_NONBLOCKING_IO
    /* set non-blocking IO */
    if (fcntl(ncxsock, F_SETFD, O_NONBLOCK)) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): fnctl() failed\n" );
    }
#endif

    /* connected to the ncxserver and setup the ENV vars ok */
    return NO_ERR;

} /* init_subsys */
/********************************************************************
* FUNCTION io_loop
*
* Handle the IO for the program
* 
* INPUTS:
*              
* RETURNS:
*   status
*********************************************************************/
static status_t
    io_loop (void)
{
    status_t  res;
    boolean   done;
    fd_set    fds;
    int       ret;
    ssize_t   retcnt;

    res = NO_ERR;
    done = FALSE;
    FD_ZERO(&fds);

    while (!done) {
        FD_SET(STDIN_FILENO, &fds);
        FD_SET(ncxsock, &fds);

        ret = select(FD_SETSIZE, &fds, NULL, NULL, NULL);
        if (ret < 0) {
            if ( errno != EINTR ) {
                SUBSYS_TRACE1( "ERROR: io_loop(): select() "
                               "failed with error: %s\n", strerror( errno ) );
                res = ERR_NCX_OPERATION_FAILED;
                done = TRUE;
            }
            else
            {
                SUBSYS_TRACE2( "INFO: io_loop(): select() "
                               "failed with error: %s\n", strerror( errno  ) );
            }
            continue;
        } else if (ret == 0) {
            SUBSYS_TRACE1( "ERROR: io_loop(): select() "
                           "returned 0, exiting...\n" );
            res = NO_ERR;
            done = TRUE;
            continue;
        } /* else some IO to process */

        /* check any input from client */
        if (FD_ISSET(STDIN_FILENO, &fds)) {
            /* get buff from openssh */
            retcnt = do_read(STDIN_FILENO, 
                             msgbuff, 
                             (size_t)BUFFLEN,
                             &res);

            if (res == ERR_NCX_EOF) {
                res = NO_ERR;
                done = TRUE;
                continue;
            } else if (res == ERR_NCX_SKIPPED) {
                res = NO_ERR;
            } else if (res == NO_ERR && retcnt > 0) {
                /* send this buffer to the ncxserver */
                res = send_buff(ncxsock, msgbuff, (size_t)retcnt);
                if (res != NO_ERR) {
                    SUBSYS_TRACE1( "ERROR: io_loop(): send_buff() to ncxserver "
                                   "failed with %s\n", strerror( errno ) );
                    done = TRUE;
                    continue;
                }
            }
        }  /* if STDIN set */

        /* check any input from the ncxserver */
        if (FD_ISSET(ncxsock, &fds)) {
            res = NO_ERR;
            retcnt = do_read(ncxsock, 
                             msgbuff, 
                             (size_t)BUFFLEN,
                             &res);

            if (res == ERR_NCX_EOF) {
                res = NO_ERR;
                done = TRUE;
                continue;
            } else if (res == ERR_NCX_SKIPPED) {
                res = NO_ERR;
            } else if (res == NO_ERR && retcnt > 0) {
                /* send this buffer to STDOUT */
                res = send_buff(STDOUT_FILENO, msgbuff, (size_t)retcnt);
                if (res != NO_ERR) {
                    SUBSYS_TRACE1( "ERROR: io_loop(): send_buff() to client "
                                   "failed with %s\n", strerror( errno ) );
                    done = TRUE;
                    continue;
                }
            }
        }
    }

    return res;

} /* io_loop */
Example #3
0
/********************************************************************
* FUNCTION init_subsys
*
* Initialize the subsystem, and get it ready to send and receive
* the first message of any kind
*
* RETURNS:
*   status
*********************************************************************/
static status_t
init_subsys (int argc, char** argv)
{
    char *cp, *con;
    int   ret;
    int name_size;
    int i;

    client_addr = NULL;
    port = NULL;
    user = NULL;
    ncxsock = -1;
    ncxconnect = FALSE;
    ncxport_inet = -1;

    for(i=1; i<argc; i++) {
        if(strlen(argv[i])>strlen("--tcp-direct-port=") && 0==memcmp(argv[i],"--tcp-direct-port=",strlen("--tcp-direct-port="))) {
            ncxport_inet = atoi(argv[i]+strlen("--tcp-direct-port="));
        }
    }

    /* get the client address */
    con = getenv("SSH_CONNECTION");
    if (!con) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): "
                       "Get SSH_CONNECTION variable failed\n" );
        return ERR_INTERNAL_VAL;
    }

    /* get the client addr */
    client_addr = strdup(con);
    if (!client_addr) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): strdup(client_addr) failed\n" );
        return ERR_INTERNAL_MEM;
    }
    cp = strchr(client_addr, ' ');
    if (!cp) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): "
                       "Malformed SSH_CONNECTION variable\n" );
        return ERR_INTERNAL_VAL;
    } else {
        *cp = 0;
    }

    /* get the server connect port */
    cp = strrchr(con, ' ');
    if (cp && cp[1]) {
        port = strdup(++cp);
    }
    if (!port) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): "
                       "Malformed SSH_CONNECTION variable\n" );
        return ERR_INTERNAL_VAL;
    }

    /* get the username */
    cp = getenv("USER");
    if (!cp) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): Get USER variable failed\n");
        return ERR_INTERNAL_VAL;
    }
    user = strdup(cp);
    if (!user) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): strdup(user) failed\n" );
        return ERR_INTERNAL_MEM;
    }
    if(ncxport_inet != -1)
    {
        struct hostent* hp;
        int tcp_nodelay_option=1;

        /* make a socket to connect to the NCX server */
        ncxsock = socket(AF_INET, SOCK_STREAM, 0);
        if (ncxsock < 0) {
            SUBSYS_TRACE1( "ERROR: init_subsys(): NCX Socket Creation failed\n" );
            return ERR_NCX_CONNECT_FAILED;
        }
        if (setsockopt(ncxsock, IPPROTO_TCP, TCP_NODELAY, (char*) &tcp_nodelay_option, sizeof(tcp_nodelay_option)) < 0) {
            SUBSYS_TRACE1( "ERROR: init_subsys(): NCX Socket Creation failed\n" );
            return ERR_NCX_CONNECT_FAILED;
        }
        hp = gethostbyname("localhost");
        if (hp == NULL) {
            SUBSYS_TRACE1( "ERROR: init_subsys(): NCX Socket Creation failed\n" );
            return ERR_NCX_CONNECT_FAILED;
        }
        memset((char *) &ncxname_inet, 0, sizeof(ncxname_inet));
        ncxname_inet.sin_family = AF_INET;
        ncxname_inet.sin_port = htons((unsigned short)ncxport_inet);
        memcpy((char *) &ncxname_inet.sin_addr, hp->h_addr, hp->h_length);

        name_size = sizeof(ncxname_inet);
        ncxname = (struct sockaddr *) &ncxname_inet;
    } else {
        /* make a socket to connect to the NCX server */
        ncxsock = socket(PF_LOCAL, SOCK_STREAM, 0);
        if (ncxsock < 0) {
            SUBSYS_TRACE1( "ERROR: init_subsys(): NCX Socket Creation failed\n" );
            return ERR_NCX_CONNECT_FAILED;
        }
        ncxname_unix.sun_family = AF_LOCAL;
        strncpy(ncxname_unix.sun_path,
                ncxserver_sockname(argc, argv, port),
                sizeof(ncxname_unix.sun_path));
        name_size = SUN_LEN(&ncxname_unix);
        ncxname = (struct sockaddr *)&ncxname_unix;
    }

    /* try to connect to the NCX server */
    ret = connect(ncxsock,
                  ncxname,
                  name_size);
    if (ret != 0) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): NCX Socket Connect failed\n" );
        return ERR_NCX_OPERATION_FAILED;
    } else {
        SUBSYS_TRACE2( "INFO:  init_subsys(): "
                       "NCX Socket Connected on FD: %d \n", ncxsock );
        ncxconnect = TRUE;
    }

#ifdef USE_NONBLOCKING_IO
    /* set non-blocking IO */
    if (fcntl(ncxsock, F_SETFD, O_NONBLOCK)) {
        SUBSYS_TRACE1( "ERROR: init_subsys(): fnctl() failed\n" );
    }
#endif

    /* connected to the ncxserver and setup the ENV vars ok */
    return NO_ERR;

} /* init_subsys */