STATUS gca_ns_init( VOID ) { #ifdef GCF_EMBEDDED_GCN char *ptr, host[ 50 ]; char *pm_default[ PM_MAX_ELEM ]; i4 count; STATUS status = OK; /* ** We do not want to initialize the embedded Name Server ** interface if this is the actual Name Server. The Name ** Server initializes the interface before initializing ** GCA, so check to see if IIGCn_static is initialized, ** indicating that gcn_init() has already been called. */ if ( IIGCn_static.maxsessions ) return( OK ); /* ** Check to see if tracing of Name Server code ** is enabled (for whoever we are) before resetting ** PM for the Name Server. */ gcu_get_tracesym( "II_GCN_TRACE", "!.gcn_trace_level", &ptr ); if ( ptr && *ptr ) CVal( ptr, &IIGCn_static.trace ); /* ** Save current PM defaults and set up for Name Server. */ for( count = 0; count < PM_MAX_ELEM; count++ ) pm_default[ count ] = PMgetDefault( count ); PMsetDefault( 0, SystemCfgPrefix ); /* Name Server defaults */ PMsetDefault( 1, PMhost() ); PMsetDefault( 2, ERx( "gcn" ) ); for( count = 3; count < PM_MAX_ELEM; count++ ) PMsetDefault( count, NULL ); /* ** Initialize embedded Name Server. */ GChostname( host, sizeof( host ) ); if ( gcn_srv_init() != OK || gcn_srv_load( host, NULL ) != OK ) status = E_GC0013_ASSFL_MEM; /* ** Reset PM defaults. */ for( count = 0; count < PM_MAX_ELEM; count++ ) PMsetDefault( count, pm_default[ count ] ); return( status ); #else /* GCA_EMBEDDED_GCN */ return( OK ); #endif /* GCA_EMBEDDED_GCN */ }
/* ** Name: GClanman_init ** Description: ** LANMAN inititialization function. This routine is called from ** GCpinit() -- the routine GCC calls to initialize protocol drivers. ** ** This function does initialization specific to the protocol: ** Creates Events and Mutex's for the protocol ** Finds and saves a pointer to it's input event Q. ** Fires up the thread which will do asynch I/O ** History: ** 11-Nov-93 (edg) ** created. ** 15-jul-95 (emmag) ** Use a NULL Discretionary Access Control List (DACL) for ** security, to give implicit access to everyone. ** 23-Feb-1998 (thaal01) ** Make space for port_id, stops gcc crashing on startup, sometimes. ** 13-may-2004 (somsa01) ** Updated config.dat string used to retrieve port information such ** that we do not rely specifically on the GCC port. ** 06-Aug-2009 (Bruce Lunsford) Sir 122426 ** Change arglist pointer in _beginthreadex for async_thread from ** uninitialized "dummy" to NULL to eliminate compiler warning ** and possible startup problem. */ STATUS GClanman_init(GCC_PCE * pptr) { char *ptr, *host, *server_id, *port_id; char config_string[256]; char buffer[MAX_COMPUTERNAME_LENGTH + 1]; int real_name_size = MAX_COMPUTERNAME_LENGTH + 1; i4 i; int tid; HANDLE hThread; int status; SECURITY_ATTRIBUTES sa; char port_id_buf[8]; port_id = port_id_buf; iimksec (&sa); /* ** Look for trace variable. */ NMgtAt( "II_LANMAN_TRACE", &ptr ); if ( !(ptr && *ptr) && PMget("!.lanman_trace_level", &ptr) != OK ) { GCLANMAN_trace = 0; } else { GCLANMAN_trace = atoi( ptr ); } /* ** Create MUTEX and EVENT for the input queue of this protocol ** driver. */ if ( ( hMutexThreadInQ = CreateMutex(&sa, FALSE, NULL) ) == NULL ) { return FAIL; } GCTRACE(3)( "GClanman_init: MutexInQ Handle = %d\n", hMutexThreadInQ ); if ( ( hEventThreadInQ = CreateEvent(&sa, FALSE, FALSE, NULL)) == NULL ) { CloseHandle( hMutexThreadInQ ); return FAIL; } GCTRACE(3)( "GClanman_init: EventInQ Handle = %d\n", hEventThreadInQ ); GCTRACE(4)( "Start GClanman_init\n" ); /* ** Get set up for the PMget call. */ PMinit(); if( PMload( NULL, (PM_ERR_FUNC *)NULL ) != OK ) PCexit( FAIL ); /* ** Construct the network port identifier. */ host = PMhost(); server_id = PMgetDefault(3); if (!server_id) server_id = "*" ; STprintf( config_string, ERx("!.lanman.port"), SystemCfgPrefix, host, server_id); /* ** Search config.dat for a match on the string we just built. ** If we don't find it, then use the value for II_INSTALLATION ** failing that, default to II. */ PMget( config_string, &port_id ); if (port_id == NULL ) { NMgtAt("II_INSTALLATION", &ptr); if (ptr != NULL && *ptr != '\0') { STcopy(ptr, port_id); } else { STcopy(SystemVarPrefix, port_id); } } NMgtAt( "II_NETBIOS_NODE", &ptr ); if ( !ptr || !*ptr ) { /* ** Get Computer Name into buffer. */ *buffer = (char)NULL; GetComputerName( buffer, &real_name_size ); if ( !*buffer ) STcopy( "NONAME", buffer ); ptr = buffer; } /* ** MyName holds ID for outgoing connections. */ STpolycat( 2, ptr, "_", MyName ); /* ** Create listen port ID. */ STpolycat( 3, ptr, "_", port_id, GCc_listen_port ); CVupper( MyName ); CVupper( GCc_listen_port ); STcopy( GCc_listen_port, pptr->pce_port ); GCTRACE(2)("GClanman_init: port = %s\n", pptr->pce_port ); /* ** Go thru the the protocol threads event list and find the index ** of the lanman thread. Set the Global Tptr for easy reference ** to the event q's for this protocols thread. */ for ( i = 0; i < IIGCc_proto_threads.no_threads; i++ ) { THREAD_EVENTS *p = &IIGCc_proto_threads.thread[i]; if ( !STcompare( LANMAN_ID, p->thread_name ) ) { Tptr = p; break; } } if ( Tptr == NULL ) { CloseHandle( hEventThreadInQ ); CloseHandle( hMutexThreadInQ ); return FAIL; } /* ** Finally we start the asynchronous I/O thread */ hThread = (HANDLE)_beginthreadex(&sa, GC_STACK_SIZE, (LPTHREAD_START_ROUTINE) GClanman_async_thread, NULL, (unsigned long)NULL, &tid); if (hThread) { CloseHandle(hThread); } else { status = errno; GCTRACE(1)("GClanman_init: Couldn't create thread errno = %d '%s'\n", status, strerror(status) ); return FAIL; } return OK; }
int main( int argc, char **argv ) { EX_CONTEXT context; char name[ GCC_L_PORT + 1 ]; u_i2 apivers; PTR hndl; #ifdef LNX PCsetpgrp(); #endif MEadvise( ME_INGRES_ALLOC ); if ( EXdeclare( GCX_exit_handler, &context ) != OK ) { gcu_erlog( 0, 1, E_GC480F_EXCEPTION, NULL, 0, NULL ); PCexit( OK ); return( 0 ); } GChostname( GCD_global.host, sizeof( GCD_global.host ) ); gcu_erinit( GCD_global.host, GCD_LOG_ID, "" ); if ( initialize( argc, argv ) != OK ) gcd_exit(); gcd_init_mib(); if ( gcd_gca_init( ) != OK ) gcd_exit(); gcu_erinit( GCD_global.host, GCD_LOG_ID, GCD_global.gcd_lcl_id ); if ( gcd_adm_init() != OK ) gcd_exit(); apivers = gcd_msg_version( MSG_DFLT_PROTO ); if ( gcd_get_env( apivers, &hndl ) != OK ) gcd_exit(); if ( gcd_pool_init() != OK ) gcd_exit(); if ( gcd_gcc_init() != OK ) gcd_exit(); /* ** Log Server startup. */ { char server_flavor[256], server_type[32]; char *tmpbuf = PMgetDefault(3); ER_ARGUMENT erlist[2]; SIstd_write(SI_STD_OUT, "PASS\n"); if ( ! STbcompare( tmpbuf, 0, "*", 0, TRUE ) ) STcopy( "(DEFAULT)", server_flavor ); else STcopy( tmpbuf, server_flavor ); STcopy(PMgetDefault(2), server_type); CVupper(server_type); erlist[0].er_value = server_flavor; erlist[0].er_size = STlength(server_flavor); erlist[1].er_value = server_type; erlist[1].er_size = STlength(server_type); gcu_erlog( 0, GCD_global.language, E_GC4802_LOAD_CONFIG, NULL, 2, (PTR)&erlist ); gcu_erlog( 0, GCD_global.language, E_GC4800_STARTUP, NULL, 0, NULL ); } GCexec(); gcd_gcc_term(); gcd_pool_term(); gcd_rel_env(0); gcd_adm_term(); gcd_gca_term(); gcu_erlog( 0, GCD_global.language, E_GC4801_SHUTDOWN, NULL, 0, NULL ); EXdelete(); PCexit( OK ); return( 0 ); }
/* ** Name: GCwintcp_init ** Description: ** WINTCP inititialization function. This routine is called from ** GCwinsock_init() -- the routine GCC calls to initialize protocol ** drivers. ** ** This function does initialization specific to the protocol: ** Reads any protocol-specific env vars. ** Sets up the winsock protocol-specific control info. ** History: ** 05-Nov-93 (edg) ** created. ** 23-Feb-1998 (thaal01) ** Allow space for port_id, stops GCC crashing on startup sometimes. ** 07-Jul-1998 (macbr01) ** Bug 91972 - jasgcc not receiving incoming communications. This is ** due to incorrect usage of PMget() in function GCwintcp_init(). ** Changed to test return code of PMget() instead of testing passed ** in parameter for not equal to NULL. ** 15-jul-1998 (canor01) ** Move assignment of port_id to port_id_buf to prevent possible ** access violation. Clean up comments. ** 09-feb-2004 (somsa01) ** When working with instance identifiers as port IDs, make sure ** we initialize sbprt with the trailing number, if set. ** 13-may-2004 (somsa01) ** Updated config.dat string used to retrieve port information such ** that we do not rely specifically on the GCC port. Also, corrected ** function used to convert subport into a number. ** 26-Jan-2006 (loera01) Bug 115671 ** Added GCWINTCP_log_rem_host to allow of gethostbyaddr() to be ** disabled. ** 06-Feb-2007 (Ralph Loen) SIR 117590 ** Removed GCWINTCP_log_rem_host, since gethostbyaddr() is no ** longer invoked for network listens. ** 22-Feb-2008 (rajus01) Bug 119987, SD issue 125582 ** Bridge server configuration requires listening on a specified ** three character listen address. During protocol initialization ** the bridge server fails to start when three character listen ** address is specified. For example, ** the following configuration entries in config.dat ** ii.<host>.gcb.*.wintcp.port: <xxn>, ** ii.<host>.gcb.*.wintcp.status:<prot_stat> ** are for command line configuration. When these entries are ** present in addition to the CBF VNODE configuration (shown below ) ** ii.rajus01.gcb.*.wintcp.port.v1:<xxn> ** ii.rajus01.gcb.*.wintcp.status.v1:<prot_stat> ** the bridge server fails even though the port is available for use. ** It has been found that the global 'sbprt' variable gets set ** by the bridge server during protocol initialization to 'n' in the ** three charater listen address 'xxn'. Later, while resolving the ** three character portname into port number by GCwintcp_port routine ** it assumes that this port is already in use even though it is not ** the case. ** Added server_type to determine the GCF server type. ** The error messages from errlog.log are the following: ** rajus01 ::[R3\BRIDGE\12c4 , 4804 , ffffffff]: Tue Feb 19 ** 19:49:27 2008 E_GC2808_NTWK_OPEN_FAIL Network open failed for ** protocol TCP_IP, port R3; status follows. ** rajus01 ::[R3\BRIDGE\12c4 , 4804 , ffffffff]: Tue Feb 19 ** 19:49:27 2008 E_CL2787_GC_OPEN_FAIL An attempted network open ** failed. ** Change description: ** The code that clears the third character in the listen address ** specified in the config.dat has been removed. This ** appears to be a wrong assumption in the protocol driver based ** on the documentation in "Appendix A:TCP/IP protocol, Listen ** Address Format seciton of Connectivity Guide". With these ** changes the protocol driver will behave the way UNIX does. ** ** WARNING: This DOES introduce the behavioural changes in the ** following cases when starting one or more servers by increa- ** sing the startup count in config.dat. ** ** Case 1: ** Both tcp_ip and win_tcp status are set to ON with Listen ** Addresses II5 and II5 for example. ** New behaviour: The GCF server will come up and listen on ** one protocol using port II5, but will fail on the other ** protocol. ** Original behaviour: ** The GCF server will listen on port II5 on the first ** protocol and the second one will listen on II6. ** This seems to be a bug in the driver as this is not the ** behaviour documented in the connectivity guide. ** Case 2: ** Both tcp_ip and win_tcp status are set to ON with Listen ** Addresses (win_tcp=II, tcp_ip = II1). ** Original behaviour: ** First GCF server will come up OK (II0, II1). The second ** GCF server will come up fine too ( II2, II3 ). ** New Behaviour: ** First GCF server will come up fine. The second GCF server ** will fail for tcp_ip protocol, but will come up on win_tcp ** protocol. This doesn't seem to be much of an issue because ** the second GCF server will still come up using win_tcp. ** 13-Apr-2010 (Bruce Lunsford) SIR 122679 ** Set wsd->pce_driver from GCC PCT rather than from ex-global ** WS_wintcp. */ STATUS GCwintcp_init(GCC_PCE * pptr, GCC_WINSOCK_DRIVER *wsd) { char *ptr = NULL; char real_name_size[] = "100"; char *host, *server_id, *port_id; char config_string[256]; char install[32]; //II_INSTALLATION code /* ** Get set up for the PMget call. */ PMinit(); if( PMload( NULL, (PM_ERR_FUNC *)NULL ) != OK ) PCexit( FAIL ); /* ** Construct the network port identifier. */ host = PMhost(); server_id = PMgetDefault(3); if (!server_id) server_id = "*" ; STprintf( config_string, ERx("!.wintcp.port"), SystemCfgPrefix, host, server_id); /* ** Search config.dat for a match on the string we just built. ** If we don't find it, then use the value for II_INSTALLATION ** failing that, default to II. */ if ((PMget( config_string, &port_id ) != OK) || (port_id == NULL )) { NMgtAt("II_INSTALLATION", &ptr); port_id = install; if (ptr != NULL && *ptr != '\0') { STcopy(ptr, port_id); } else { STcopy(SystemVarPrefix, port_id); } } STcopy(port_id, pptr->pce_port); GCTRACE(1)("GCwintcp_init: port = %s\n", pptr->pce_port ); /* ** Fill in protocol-specific info */ wsd->addr_len = sizeof( struct sockaddr_in ); wsd->sock_fam = AF_INET; wsd->sock_type = SOCK_STREAM; wsd->sock_proto = 0; wsd->block_mode = FALSE; wsd->pce_driver = pptr->pce_driver; /* ** Get trace variable */ ptr = NULL; NMgtAt( "II_WINTCP_TRACE", &ptr ); if ( !(ptr && *ptr) && PMget("!.wintcp_trace_level", &ptr) != OK ) { GCWINTCP_trace = 0; } else { GCWINTCP_trace = atoi( ptr ); } return OK; }
i4 main( i4 argc, char **argv ) { STATUS generic_status = OK; CL_ERR_DESC system_status; EX_CONTEXT context; STATUS status; GCC_ERLIST erlist; STATUS (*call_list[7])(); i4 i, call_count; i4 cmd_args = 0; char usage[] = { "Usage: iigcb -from <protocol>" }; char usage1[] = { " -to <protocol> <hostname> < listen_address>" }; #ifdef LNX PCsetpgrp(); #endif MEfill( sizeof( system_status ), 0, (PTR)&system_status ); MEadvise( ME_INGRES_ALLOC ); EXdeclare( GCX_exit_handler, &context ); SIeqinit(); /* ** Parse command line. */ for( i = 1; i < argc; i++ ) if ( ! STcompare( argv[i], "-from" ) ) { if ( ++i >= argc ) { SIfprintf( stderr, "\n%s%s\n\n", usage, usage1 ); SIflush( stderr ); SIstd_write(SI_STD_OUT, "\nFAIL\n"); EXdelete(); PCexit( FAIL ); } STcopy( argv[i], gcb_from_addr.n_sel ); CVupper( gcb_from_addr.n_sel ); ++cmd_args; } else if ( ! STcompare( argv[ i ], "-to" ) ) { if ( (i + 3) >= argc ) { SIfprintf( stderr, "\n%s%s\n\n", usage, usage1 ); SIflush( stderr ); SIstd_write(SI_STD_OUT, "\nFAIL\n"); EXdelete(); PCexit( FAIL ); } STcopy( argv[ ++i ], gcb_to_addr.n_sel ); STcopy( argv[ ++i ], gcb_to_addr.node_id ); STcopy( argv[ ++i ], gcb_to_addr.port_id ); CVupper( gcb_to_addr.n_sel ); ++cmd_args; } if ( cmd_args ) if ( cmd_args == 2 ) gcb_pm_reso.cmd_line = TRUE; else { SIfprintf( stderr, "\n%s%s\n\n", usage, usage1 ); SIflush( stderr ); SIstd_write(SI_STD_OUT, "\nFAIL\n"); EXdelete(); PCexit( FAIL ); } /* ** Perform general initialization. The bridge may be run ** for async lines as a part of Ingres/Net. Otherwise, ** Bridge authorization is required. */ if ( gcb_pm_reso.cmd_line && ! STcasecmp( gcb_from_addr.n_sel, ERx("async") ) ) status = gcc_init( FALSE, CI_INGRES_NET, argc, argv, &generic_status, &system_status ); else { #ifdef CI_INGRES_BRIDGE status = gcc_init( FALSE, CI_INGRES_BRIDGE, argc, argv, &generic_status, &system_status ); #else generic_status = E_GC2A0F_NO_AUTH_BRIDGE; status = FAIL; #endif } if ( status != OK ) { gcc_er_log( &generic_status, &system_status, NULL, NULL ); generic_status = E_GC2A01_INIT_FAIL; gcc_er_log( &generic_status, NULL, NULL, NULL ); SIstd_write(SI_STD_OUT, "\nFAIL\n"); EXdelete(); PCexit( FAIL ); } /* ** Perform standalong Bridge Server initialization. */ IIGCc_global->gcc_flags |= GCC_STANDALONE; gcb_init_mib(); /* ** Initialize the protocol layers. */ call_list[0] = GCcinit; call_list[1] = gcb_alinit; call_list[2] = gcc_pbinit; call_count = 3; if ( gcc_call( &call_count, call_list, &generic_status, &system_status ) != OK ) { gcc_er_log( &generic_status, &system_status, NULL, NULL ); generic_status = E_GC2A01_INIT_FAIL; gcc_er_log( &generic_status, NULL, NULL, NULL ); SIstd_write(SI_STD_OUT, "\nFAIL\n"); } else { { /* ** Obtain and fix up the configuration name, then log it. */ char server_flavor[256], server_type[32]; char *tmpbuf = PMgetDefault(3); if (!STbcompare( tmpbuf, 0, "*", 0, TRUE )) STcopy("(DEFAULT)", server_flavor); else STcopy(tmpbuf, server_flavor); STcopy(PMgetDefault(2), server_type); CVupper(server_type); erlist.gcc_parm_cnt = 2; erlist.gcc_erparm[0].value = server_flavor; erlist.gcc_erparm[0].size = STlength(server_flavor); erlist.gcc_erparm[1].value = server_type; erlist.gcc_erparm[1].size = STlength(server_type); generic_status = E_GC2A10_LOAD_CONFIG; gcc_er_log( &generic_status, (CL_ERR_DESC *)NULL, (GCC_MDE *)NULL, &erlist); } erlist.gcc_parm_cnt = 1; erlist.gcc_erparm[0].size = STlength( IIGCc_rev_lvl ); erlist.gcc_erparm[0].value = IIGCb_rev_lvl; generic_status = E_GC2A03_STARTUP; gcc_er_log( &generic_status, NULL, NULL, &erlist ); /* ** Invoke GCexec to enter the main phase of Protocol bridge ** execution. GCexec does not return until bridge shutdown ** is initiated by invoking GCshut. */ GCexec(); generic_status = E_GC2A04_SHUTDOWN; gcc_er_log( &generic_status, &system_status, NULL, NULL ); } /* ** GCexec has returned. Bridge shutdown is in process. ** Initialize the call list to specify termination rotutines. ** Call in reverse order of initialization but don't call ** termination routines whose initialization routines were ** not called (call_count has the number of successful ** initialization calls). */ call_list[0] = gcb_alterm; call_list[1] = gcc_pbterm; call_list[2] = GCcterm; if ( gcc_call( &call_count, &call_list[ 3 - call_count ], &generic_status, &system_status ) ) gcc_er_log( &generic_status, &system_status, NULL, NULL ); /* ** Do general server termination. */ if ( gcc_term( &generic_status, &system_status ) != OK ) gcc_er_log( &generic_status, &system_status, NULL, NULL ); EXdelete(); PCexit( OK ); } /* end main */