/* * Send DNETMANAGE script command to server and process result. * Routine assumes CGILIB was initialized with cgi_init_env() and that * cgi_begin_output() hasn't been called. * * Author: David Jones * Revised: 26-FEB-1998 */ #include #include #include #ifdef VMS #ifndef __GNUC__ #include #include #else #define caddr_t caddr_t_gcc #define u_char u_char_gcc #define u_long u_long_gcc #define u_short u_short_gcc #endif #include #include #else #include #include #include #include #endif #include #include #include "scriptlib.h" /* net_link_* function prototypes */ #include "cgilib.h" /* cgi_* function prototypes */ static error_abort ( char *line, char *msg ) { int status; status = cgi_begin_output(1); if ( (status&1) == 0 ) exit ( status ); status = cgi_printf ( "content-type: text/plain\nstatus: %s\n\n%s\n", line, msg ); exit ( status ); } void server_query ( char *query ) { int mgr_port, status, sd, i, j, timeout, rem_port, length; char *target, *lbrack, *rbrack; struct sockaddr local, remote; struct hostent *hostinfo; char *remote_host; char manage_arg[128], manage_rsp[256], myhost[256]; /* * create a socket and bind to random port. */ sd = socket ( AF_INET, SOCK_STREAM, 0 ); if ( sd < 0 ) error_abort ( "500 error", "error creating socket" ); for ( j = 0; j < sizeof(local.sa_data); j++ ) { local.sa_data[j] = remote.sa_data[j] = 0; } status = gethostname ( myhost, sizeof(myhost)-1 ); if ( status >= 0 ) { hostinfo = gethostbyname(myhost); if ( hostinfo ) for ( j = 0; j < hostinfo->h_length; j++ ) { local.sa_data[j+2] = hostinfo->h_addr_list[0][j]; } } for ( mgr_port = 5900; mgr_port < 5950; mgr_port++ ) { local.sa_family = AF_INET; local.sa_data[0] = mgr_port >> 8; local.sa_data[1] = (mgr_port&255); status = bind ( sd, &local, sizeof(local) ); printf ( "bind local socket: %d %d %s\n", status, mgr_port, strerror(errno) ); if ( status >= 0 ) break; } /* * get host and port info from CGI variables and lookup host. */ remote_host = cgi_info ( "SERVER_NAME" ); if ( !remote_host ) remote_host = "localhost"; hostinfo = gethostbyname ( remote_host ); if ( !hostinfo ) error_abort ( "500 error", "error looking up hostname" ); rem_port = atoi ( cgi_info ( "SERVER_PORT" ) ); remote.sa_family = hostinfo->h_addrtype; for ( j = 0; j < hostinfo->h_length; j++ ) { remote.sa_data[j+2] = hostinfo->h_addr_list[0][j]; } remote.sa_data[0] = rem_port >> 8; remote.sa_data[1] = (rem_port&255); /* * Send command to make server switch managment * port and host. */ sprintf ( manage_arg, "%d.%d.%d.%d:%d %s", local.sa_data[2]&255, local.sa_data[3]&255, local.sa_data[4]&255, local.sa_data[5]&255, mgr_port, query ); status = net_link_write ( "", 12 ); if ( (status&1) == 1 ) status = net_link_query ( manage_arg, manage_rsp, sizeof(manage_rsp)-1, &length ); if ( (status&1) == 1 ) { /* * Verify response. */ manage_rsp[length] = '\0'; if ( 0 != strncmp ( "200 ", manage_rsp, 4 ) ) error_abort ( "500 error from server", manage_rsp ); } else { /* I/O error to net link */ exit(1); } /* * Switch port number if included in response. */ lbrack = strchr ( manage_rsp, '[' ); rbrack = lbrack ? strchr ( lbrack, ']' ) : (char *) 0; if ( lbrack && rbrack ) { *rbrack = '\0'; rem_port = atoi ( lbrack+1 ); printf("alternate target port: %d\n", rem_port ); if ( rem_port > 0 ) { remote.sa_data[0] = rem_port >> 8; remote.sa_data[1] = (rem_port&255); } } /* * connect to server. */ status = connect ( sd, &remote, sizeof(remote) ); if ( status != 0 ) error_abort ( "500 error", strerror(errno) ); else { int length; char response[10240]; /* * Send request followed by newline. */ status = send ( sd, "TRIGGER\n", 8, 0 ); if ( status < 0 ) fprintf(stderr,"status of write: %d %d\n", status, errno ); status = send ( sd, "\r\n\r\n", 4, 0 ); /* * Read and save response. */ if ( status > 0 ) { int i, j, pos, cr; char ch; cgi_begin_output(1); cr = 0; pos = 0; while (0 < (length=recv(sd, &response[pos], 1024,0))) { for ( i = 0, j = pos; i < length; i++ ) { ch = response[pos+i]; if ( ch == '\r' ) { if ( cr == 1 ) response[j++] = '\r'; cr = 1; } else if ( cr == 1 ) { if ( ch != '\n' ) response[j++] = '\r'; response[j++] = ch; cr = 0; } else { response[j++] = ch; cr = 0; } } response[j] = '\0'; pos = j; if ( (pos+2048) >= sizeof(response) ) break; if ( pos > 4 ) if ( 0 == strncmp ( "201 ", response, 4 ) ) break; } cgi_printf("content-type: text/plain\n\n"); cgi_printf("Port %d response:\n", rem_port ); cgi_printf("%s", response ); printf("%s", response ); printf("\n"); } } }