/******************************************************************** * 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 */
/******************************************************************** * 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 */