STATUS MOsidout( STATUS errstat, PTR ptr, i4 destlen, char *dest ) { static i4 usehex = -1; STATUS (*outfunc)( STATUS, PTR, i4, char * ); char *pmvalue; if ( usehex < 0 ) { /* Set static config value if not already set. We don't need to worry ** about the unlikely event of two threads getting here simultaneously ** since even if both try to init this, it gets set to the correct value ** regardless and PM protects itself as needed. Note also we assume PM ** has already be initialized and loaded, which is a safe assumption as ** this routines is not called during server initialization. */ if ( OK == PMget("!.hex_session_ids", &pmvalue) && NULL != pmvalue && 0 == STcasecmp(pmvalue, "on") ) usehex = 1; else usehex = 0; } if ( usehex ) outfunc = MOptrxout; else outfunc = MOptrout; return (*outfunc)( errstat, ptr, destlen, dest ); }
/* ** tcp6_set_version - sets version for TCP. ** ** Check to see if driver being restricted to IPv4 or IPv6 only. ** Default is both IPv4(AF_INET) + IPv6(AF_INET6) ** ** VERSION -> meaning . . . ** ALL or unspecified -> (default) Use both IPv4 and IPv6 addresses ** with new (IPv6-enabled) driver ** 4 -> Use old IPv4-only driver (ie, back off to old driver) ** 46 -> Use only IPv4 addresses with new (IPv6-enabled) driver ** 6 -> Use only IPv6 addresses with new (IPv6-enabled) driver ** */ static int tcp6_set_version() { char *p; if( tcpip_version == -1 ) /* Only do 1st time in for performance */ { TCP_TRACE(2)("tcp6_set_version: entered first time\n"); tcpip_version = 0; NMgtAt( "II_TCPIP_VERSION", &p ); if ( !(p && *p) && PMget("!.tcp_ip.version", &p) != OK ) ip_family = AF_UNSPEC; else if (STbcompare(p, 0, "ALL", 0, TRUE) == 0) ip_family = AF_UNSPEC; else { tcpip_version = atoi(p); /* 4*=IPv4 or 6=IPv6 */ if ((tcpip_version == 4) || (tcpip_version == 46)) ip_family = AF_INET; else if (tcpip_version == 6) ip_family = AF_INET6; else { TCP_TRACE(2)("tcp6_set_version: failed! II_TCPIP_VERSION=%s\n", p); return(FAIL); } } TCP_TRACE(2)("tcp6_set_version: exiting version=%d, family=%d\n", tcpip_version, ip_family); } /* end if first time */ return(OK); }
bool ascs_chk_priv( char *user_name, char *priv_name ) { char pmsym[128], userbuf[DB_OWN_MAXNAME+1], *value, *valueptr ; char *strbuf = 0; int priv_len; /* ** privileges entries are of the form ** ii.<host>.*.privilege.<user>: SERVER_CONTROL,NET_ADMIN,... ** ** Currently known privs are: SERVER_CONTROL,NET_ADMIN, ** MONITOR,TRUSTED */ STlcopy( user_name, userbuf, DB_OWN_MAXNAME ); STtrmwhite( userbuf ); STprintf(pmsym, "$.$.privileges.user.%s", userbuf); /* check to see if entry for given user */ /* Assumes PMinit() and PMload() have already been called */ if( PMget(pmsym, &value) != OK ) return FALSE; valueptr = value ; priv_len = STlength(priv_name) ; /* ** STindex the PM value string and compare each individual string ** with priv_name */ while ( *valueptr != EOS && (strbuf=STindex(valueptr, "," , 0))) { if (!STscompare(valueptr, priv_len, priv_name, priv_len)) return TRUE ; /* skip blank characters after the ','*/ valueptr = STskipblank(strbuf+1, 10); } /* we're now at the last or only (or NULL) word in the string */ if ( *valueptr != EOS && !STscompare(valueptr, priv_len, priv_name, priv_len)) return TRUE ; return FALSE; }
/* ** tcp6_set_trace - sets trace level for TCP. */ static VOID tcp6_set_trace() { static bool init_trace=FALSE; char *trace; if(init_trace) return; init_trace=TRUE; NMgtAt( "II_TCP_TRACE", &trace ); if ( !( trace && *trace ) && PMget("!.tcp_trace_level", &trace) != OK ) tcp_trace = 0; else tcp_trace = atoi(trace); }
/*{ ** Name: CXcluster_nodes - Retrun information about configured nodes. ** ** Description: ** ** Function will return information about the nodes configured ** in this installation. ** ** Inputs: ** ** pnodecnt - Pointer to u_i4 to hold node count, or NULL. ** ** hconfig - Address of pointer to be filled with pointer ** to an initialized CX_CONFIGURATION, or NULL. ** DO NOT alter the contents of the cached ** CX_CONFIGURATION through the returned address! ** ** Outputs: ** ** *pnodecnt - Filled in with # nodes. ** ** *hconfig - Holds pointer to cached CX_CONFIGURATION. ** ** Returns: ** OK - Normal successful completion. ** FAIL - Problem with configuration found. ** ** Exceptions: ** none ** ** Side Effects: ** none. ** ** History: ** 18-apr-2001 (devjo01) ** Created. (Much of code lifted from DMFCSP) ** 15-Apr-2005 (fanch01) ** Modified cx_nodes array references to be valid from element zero. */ STATUS CXcluster_nodes( u_i4 *pnodecnt, CX_CONFIGURATION **hconfig ) { static i4 config_valid = 0; static CX_CONFIGURATION config = { 0 }; STATUS status = OK; u_i4 nodecnt; PM_SCAN_REC scanrec; char *resname; char *resvalue; char *nodename; i4 nodename_l; i4 clusterid; CX_NODE_INFO *pni; i4 i, rad; char param[80]; if ( !config_valid ) { status = PMinit(); if ( OK == status ) { status = PMload( (LOCATION *)NULL, (PM_ERR_FUNC *)0); } else if ( PM_DUP_INIT == status ) { status = OK; } if ( status == OK ) { nodecnt = 0; /* ** Start the scan */ status = PMscan( "^II\\.[^.]*\\.CONFIG\\.CLUSTER\\.ID$", &scanrec, (char *) NULL, &resname, &resvalue ); while ( status == OK ) { /* ** Extract out node name and convert value to integer */ nodename = PMgetElem( 1, resname ); nodename_l = STlength(nodename); CVal( resvalue, &clusterid ); /* Ignore entries with zero cluster id. */ if ( 0 != clusterid ) { /* ** Check id is withing range */ if ( (clusterid > CX_MAX_NODES) || (clusterid < 0) ) { TRdisplay( ERx( \ "%@ CSP node config: Node %s has an invalid id: %d, valid range (0 - %d)\n"), nodename, clusterid, CX_MAX_NODES ); status = FAIL; break; } /* ** Adjust clusterid so array references are zero based. */ clusterid--; /* ** Check that specified id is not already used. */ if ( config.cx_nodes[clusterid].cx_node_name_l != 0 ) { /* ** Location is already being used issue a message ** accordingly */ if (STxcompare( nodename, nodename_l, config.cx_nodes[clusterid].cx_node_name, config.cx_nodes[clusterid].cx_node_name_l, TRUE, FALSE) == 0) { TRdisplay( ERx("%@ Cluster configuration: Node %~t already exists in correct location.\n"), nodename_l, nodename ); } else { TRdisplay( ERx("%@ Cluster configuration: Node %~t has same id as Node %~t.\n"), nodename_l, nodename, config.cx_nodes[clusterid].cx_node_name_l, config.cx_nodes[clusterid].cx_node_name ); } status = FAIL; break; } /* ** Make sure nodename is unique */ for (i = 1; i <= nodecnt; i++) { if (STxcompare( config.cx_nodes[config.cx_xref[i]].cx_node_name, config.cx_nodes[config.cx_xref[i]].cx_node_name_l, nodename, nodename_l, TRUE, FALSE) == 0) { TRdisplay( ERx("%@ Cluster configuration: Node %s already exists.\n"), nodename ); status = FAIL; break; } } /* ** Add to configuration */ nodecnt++; config.cx_xref[nodecnt] = clusterid; pni = &config.cx_nodes[clusterid]; STmove( nodename, '\0', CX_MAX_NODE_NAME_LEN, pni->cx_node_name ); pni->cx_node_name_l = STnlength(CX_MAX_NODE_NAME_LEN, pni->cx_node_name ); pni->cx_node_number = clusterid + 1; pni->cx_host_name_l = pni->cx_rad_id = 0; STprintf(param,"ii.%s.gcn.local_vnode", nodename); if ( OK == PMget(param, &resvalue) ) { STmove( resvalue, '\0', CX_MAX_HOST_NAME_LEN, pni->cx_host_name ); pni->cx_host_name_l = STnlength( CX_MAX_HOST_NAME_LEN, pni->cx_host_name ); } STprintf(param,"ii.%s.config.numa.rad", nodename); if ( OK == PMget(param, &resvalue) && OK == CVan(resvalue, &rad) && rad > 0 ) { pni->cx_rad_id = rad; } /* ** Find next element */ status = PMscan( (char *) NULL, &scanrec, (char *) NULL, &resname, &resvalue ); } } /* ** End condition */ if ( status == PM_NOT_FOUND ) status = OK; } if (status != OK ) { TRdisplay( ERx("%@ Cluster configuration Error\n") ); return (FAIL); } config.cx_node_cnt = nodecnt; config_valid = 1; } if ( pnodecnt ) *pnodecnt = config.cx_node_cnt; if ( hconfig ) *hconfig = &config; return OK; } /*CXcluster_nodes*/
ADF_CB * FEadfcb () { if (!done) { char *cp; DB_STATUS rval; PTR srv_cb_ptr; SIZE_TYPE srv_size; SIZE_TYPE dbinfo_size; PTR dbinfoptr; STATUS tmtz_status; STATUS date_status; char date_type_alias[100]; char col[] = "udefault"; STATUS status = OK; CL_ERR_DESC sys_err; ADUUCETAB *ucode_ctbl; /* unicode collation information */ PTR ucode_cvtbl; done = TRUE; /* first, get the size of the ADF's server control block */ srv_size = adg_srv_size(); /* allocate enough memory for it */ if ((srv_cb_ptr = MEreqmem(0, srv_size, FALSE, (STATUS *)NULL)) == NULL) { EXsignal(EXFEBUG, 1, ERx("FEadfcb(alloc)")); } /* ** Fix up code so that "now" works properly for frontends. ** Only allocating enough for one (1) dbmsinfo() request. */ dbinfo_size = sizeof(ADF_TAB_DBMSINFO); if ((dbinfoptr = MEreqmem(0, dbinfo_size, TRUE, (STATUS*)NULL)) == NULL) { IIUGbmaBadMemoryAllocation(ERx("FEadfcb")); } dbinfo = (ADF_TAB_DBMSINFO *) dbinfoptr; dbinfo->tdbi_next = NULL; dbinfo->tdbi_prev = NULL; dbinfo->tdbi_length = dbinfo_size; dbinfo->tdbi_type = ADTDBI_TYPE; dbinfo->tdbi_s_reserved = -1; dbinfo->tdbi_l_reserved = (PTR)-1; dbinfo->tdbi_owner = (PTR)-1; dbinfo->tdbi_ascii_id = ADTDBI_ASCII_ID; dbinfo->tdbi_numreqs = 1; /* ** Now define request. */ dbinfo->tdbi_reqs[0].dbi_func = IIUGnfNowFunc; dbinfo->tdbi_reqs[0].dbi_num_inputs = 0; dbinfo->tdbi_reqs[0].dbi_lenspec.adi_lncompute = ADI_FIXED; STcopy("_BINTIM", dbinfo->tdbi_reqs[0].dbi_reqname); dbinfo->tdbi_reqs[0].dbi_reqcode = 1; dbinfo->tdbi_reqs[0].dbi_lenspec.adi_fixedsize = 4; dbinfo->tdbi_reqs[0].dbi_dtr = DB_INT_TYPE; /* ** set timezone in ADF cb - Any errors must be reported ** after adg_init() called. */ if ( (tmtz_status = TMtz_init(&cb.adf_tzcb)) == OK) { tmtz_status = TMtz_year_cutoff(&cb.adf_year_cutoff); } /* Always use INGRESDATE by default, and check ** 'ii.<node>.config.date_alias' (kibro01) b118702 */ cb.adf_date_type_alias = AD_DATE_TYPE_ALIAS_INGRES; STprintf(date_type_alias,ERx("ii.%s.config.date_alias"),PMhost()); date_status = PMget(date_type_alias, &cp); if (date_status == OK && cp != NULL && STlength(cp)) { if (STbcompare(cp, 0, ERx("ansidate"), 0, 1) == 0) cb.adf_date_type_alias = AD_DATE_TYPE_ALIAS_ANSI; else if (STbcompare(cp, 0, ERx("ingresdate"), 0, 1) == 0) cb.adf_date_type_alias = AD_DATE_TYPE_ALIAS_INGRES; else cb.adf_date_type_alias = AD_DATE_TYPE_ALIAS_NONE; } /* set timezone table to NULL in ADF cb, adg_init() will fill it */ /* cb.adf_tz_table = NULL; - not needed, done in declaration above */ /* Start up ADF */ rval = adg_startup(srv_cb_ptr, srv_size, dbinfo, 0); if (DB_FAILURE_MACRO(rval)) { /* ** Before bailing out, try to be helpful. Since the environment ** is likely not set up correctly, write hard coded messages ** since error message fetch will likely fail in this situation. */ char *tempchar; i4 dummy; LOCATION temploc; NMgtAt("II_SYSTEM", &tempchar); if (tempchar && *tempchar) { LOfroms(PATH, tempchar, &temploc); if (LOexist(&temploc)) { tempchar = ERx("FEadfcb: II_SYSTEM DOES NOT EXIST\n"); SIwrite(STlength(tempchar), tempchar, &dummy, stderr); } else { NMloc(ADMIN, FILENAME, ERx("config.dat"), &temploc); if (LOexist(&temploc)) { tempchar = ERx("FEadfcb: II_SYSTEM IS NOT SET CORRECTLY\n"); SIwrite(STlength(tempchar), tempchar, &dummy, stderr); } } } else { tempchar = ERx("FEadfcb: II_SYSTEM IS NOT SET\n"); SIwrite(STlength(tempchar), tempchar, &dummy, stderr); } EXsignal(EXFEBUG, 1, ERx("FEadfcb(start)")); } /* put the pointer to ADF's server control block in the ADF_CB */ cb.adf_srv_cb = srv_cb_ptr; /* set up the error message buffer */ cb.adf_errcb.ad_ebuflen = DB_ERR_SIZE; cb.adf_errcb.ad_errmsgp = ebuffer; /* initialize the ADF_CB */ rval = adg_init(&cb); if (DB_FAILURE_MACRO(rval)) { EXsignal(EXFEBUG, 1, ERx("FEadfcb(init)")); } /* find out which natural language we should speak */ cb.adf_slang = iiuglcd_langcode(); /* Always QUEL; for SQL explictly change this with 'IIAFdsDmlSet()'. */ cb.adf_qlang = DB_QUEL; /* lets get the multinational info */ /* ** Defaults for all of these are initially set statically, above. */ NMgtAt(ERx("II_DATE_FORMAT"), &cp); if ( cp != NULL && *cp != EOS ) { FEapply_date_format(&cb,cp); } NMgtAt(ERx("II_MONEY_FORMAT"), &cp); if ( cp != NULL && *cp != EOS ) { FEapply_money_format(&cb,cp); } NMgtAt(ERx("II_MONEY_PREC"), &cp); if ( cp != NULL && *cp != EOS ) { FEapply_money_prec(&cb,cp); } NMgtAt(ERx("II_DECIMAL"), &cp); if ( cp != NULL && *cp != EOS ) { FEapply_decimal(&cb,cp); } NMgtAt(ERx("II_UNICODE_SUBS"), &cp); if ( !cp ) { cb.adf_unisub_status = AD_UNISUB_OFF; } else { /* As with SET unicode_substitution take the first char */ cb.adf_unisub_status = AD_UNISUB_ON; *cb.adf_unisub_char = cp[0]; } NMgtAt(ERx("II_NULL_STRING"), &cp); if ( cp != NULL && *cp != EOS ) { FEapply_null(&cb,cp); } /* If there was a Timezone error other than the expected ingbuild ** error TM_PMFILE_OPNERR, then lets report it now. */ if (tmtz_status && (tmtz_status != TM_PMFILE_OPNERR)) { LOCATION loc_root; STATUS status = OK; status = NMloc(FILES, PATH, ERx("zoneinfo"), &loc_root); #if defined(conf_BUILD_ARCH_32_64) && defined(BUILD_ARCH64) status = LOfaddpath(&loc_root, ERx("lp64"), &loc_root); #endif #if defined(conf_BUILD_ARCH_64_32) && defined(BUILD_ARCH32) { /* ** Reverse hybrid support must be available in ALL ** 32bit binaries */ char *rhbsup; NMgtAt("II_LP32_ENABLED", &rhbsup); if ( (rhbsup && *rhbsup) && ( !(STbcompare(rhbsup, 0, "ON", 0, TRUE)) || !(STbcompare(rhbsup, 0, "TRUE", 0, TRUE)))) status = LOfaddpath(&loc_root, "lp32", &loc_root); } #endif /* ! LP64 */ if ( status == OK ) { status = LOexist(&loc_root); } if ( status == OK ) { IIUGerr(tmtz_status, 0, 0); /* As this may disappear from the screen quickly, ** let's pause to allow the users to reflect on the ** fact that the timezone info is (probably) wrong. */ if (!IIugefa_err_function) PCsleep(5000); } } /* Initialize unicode collation for UTF8 installations */ if (CMischarset_utf8()) { if (status = aduucolinit(col, MEreqmem, &ucode_ctbl, &ucode_cvtbl, &sys_err)) { EXsignal(EXFEBUG, 1, ERx("FEadfcb(alloc)")); } cb.adf_ucollation = (PTR) ucode_ctbl; /* Set unicode normalization to NFC just in case ** Front end will need it. */ if ((status = adg_setnfc(&cb)) != E_DB_OK) EXsignal(EXFEBUG, 1, ERx("FEadfcb(alloc)")); } /* lets not do this again! */ } return &cb; }
main(int argc, char **argv) { char *value = NULL; char *host, *server_type, *command_line; char *server_location, *env, *arguments; u_i4 command_line_length; char config_string[256]; char iidbms[256]; STARTUPINFO si; PROCESS_INFORMATION ProcessInfo; BOOL Status; SECURITY_ATTRIBUTES sa; HANDLE hRead, hWrite; HANDLE hStdout; char buffer[512]; DWORD bufferl = sizeof(buffer); DWORD pipe_size = 0; /* Use default buffer size */ DWORD datal = 0; bool havequote, failed = FALSE; MEadvise( ME_INGRES_ALLOC ); switch (argc) { case 1: server_type = ERx("dbms"); server_location = ERx("*"); break; case 2: server_type = argv[1]; server_location = ERx("*"); break; default: server_type = argv[1]; if (STcompare(server_type, "recovery") == 0) server_location = ERx("*"); else server_location = argv[2]; break; } get_sys_dependencies(); /* ** Get the host name, formally used iipmhost. */ host = PMhost(); /* ** Build the string we will search for in the config.dat file. */ STprintf( config_string, ERx("%s.%s.%s.%s.image_name"), SystemCfgPrefix, host, server_type, server_location ); /* ** Get set up for the PMget call. */ PMinit(); if( PMload( NULL, (PM_ERR_FUNC *)NULL ) != OK ) PCexit( FAIL ); /* ** Go search config.dat for a match on the string we just built. */ PMget( config_string, &value ); if ( value == NULL ) { NMgtAt( SystemLocationVariable, &env ); if (STcompare(server_type, "recovery") == 0) { STprintf(iidbms, ERx("%s\\%s\\bin\\%sdbms"), env, SystemLocationSubdirectory, SystemCfgPrefix); } else { STprintf(iidbms, ERx("%s\\%s\\bin\\%s%s"), env, SystemLocationSubdirectory, SystemCfgPrefix, server_type); } } else if ( *value == '/' || *value == '\\' || (*(value+1) == ':' && *(value+2) == '\\') ) { /* Must be a qualified path name */ STcopy( value, iidbms ); } else { NMgtAt( SystemLocationVariable, &env ); STprintf( iidbms, ERx("%s\\%s\\bin\\%s"), env, SystemLocationSubdirectory, value ); } /* ** Initialize the startinfo structure. */ ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); /* ** Get the original command line. */ arguments = GetCommandLine(); havequote = FALSE; while (*arguments != '\0' && *arguments != '\n') { if ( *arguments == '"' ) havequote = (havequote) ? FALSE : TRUE; if ( CMwhite(arguments) && havequote == FALSE ) break; arguments++; } /* ** Put together a command line to create a process with. ** - 4 blank separators, quotes, null termination */ command_line_length = STlength(arguments) + STlength(iidbms) + STlength(iirun) + 6 + 1; if((command_line = (char *) MEreqmem(0, command_line_length, TRUE, NULL)) == NULL) { error(ERx("Request for memory failed"),NULL); } STprintf( command_line, "%s \"%s\" %s", iirun, iidbms, arguments ); /* ** Save standard out's handle, to be restored later. */ hStdout = GetStdHandle(STD_OUTPUT_HANDLE); /* ** Initialize the security attributes structure that will ** be used to make the pipe handles inheritable. */ sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* Make object inheritable */ /* ** Define a anonymous pipe to catch the server's startup message. */ if((Status = CreatePipe(&hRead,&hWrite,&sa,pipe_size)) != TRUE) { error(ERx("CreatePipe failed"),ERx("error code = ")); } SetStdHandle(STD_OUTPUT_HANDLE,hWrite); /* ** Initialize the security attributes structure that will ** be used to make the pipe handles inheritable. */ sa.nLength = sizeof(sa); sa.lpSecurityDescriptor = NULL; sa.bInheritHandle = TRUE; /* Make object inheritable */ /* ** Initialize the startup information structure. */ ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); /* ** Start it up. */ /* ** Start iirun which will start the server. */ if ((Status = CreateProcess(NULL,command_line,&sa,NULL,TRUE, HIGH_PRIORITY_CLASS, NULL, NULL,&si,&ProcessInfo)) != TRUE) { DWORD dwError = GetLastError(); switch(dwError) { case ERROR_ACCESS_DENIED: error(ERROR_REQ_PRIVILEGE, ERx("")); break; case ERROR_ELEVATION_REQUIRED: error(ERROR_DENIED_PRIVILEGE, ERROR_REQ_ELEVATION); break; default: error(ERx("CreateProcess failed"),ERx("error code = ")); break; } } SetStdHandle(STD_OUTPUT_HANDLE,hStdout); for (;;) { char *tmpptr; if((Status = ReadFile(hRead,&buffer,bufferl,&datal,NULL)) != TRUE) { error(ERx("ReadFile failed"),ERx("error code = ")); } buffer[datal] = '\0'; if ((tmpptr = STstrindex(buffer, "PASS\n", 0, FALSE))) { *tmpptr = '\0'; if (STlength(buffer)) SIfprintf(stdout, "%s", buffer); break; } SIfprintf(stdout, "%s", buffer); if ((tmpptr = STstrindex(buffer, bad_msg, 0, FALSE))) { *tmpptr = '\0'; if (STlength(buffer)) SIfprintf(stdout, "%s", buffer); failed = TRUE; break; } } /* ** Close handles since we don't need them anymore. */ CloseHandle(ProcessInfo.hThread); CloseHandle(ProcessInfo.hProcess); CloseHandle(hRead); CloseHandle(hWrite); if (failed && STscompare(server_type, STlength(server_type), "gcb", 3) != 0 && STscompare(server_type, STlength(server_type), "gcc", 3) != 0 && STscompare(server_type, STlength(server_type), "jdbc", 4) != 0) { SIfprintf( stderr,"\n%s: server would not start.\n", iirundbms ); SIfprintf(stderr, " %s must be set in your environment.\n", SystemLocationVariable ); SIfprintf(stderr, " Has the csinstall program been run?\n"); SIfprintf(stderr, " %s_DATABASE, %s_CHECKPOINT, %s_JOURNAL and %s_DUMP\n", SystemVarPrefix, SystemVarPrefix, SystemVarPrefix, SystemVarPrefix ); SIfprintf(stderr, " must also be set. See %s_CONFIG\\symbol.tbl.\n", SystemVarPrefix ); SIfprintf(stderr, " Check the file '%%%s%%\\%s\\files\\errlog.log'\n", SystemLocationVariable, SystemLocationSubdirectory ); SIfprintf(stderr, " for more details concerning internal errors.\n"); SIfprintf(stderr, " See your Installation and Operation Guide for more\n"); SIfprintf(stderr, " information concerning server startup.\n"); PCexit(FAIL); } else { PCexit(OK); } }
/* ** 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; }
/* ** 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; }
/*{ ** Name: RSstats_init - initialize monitor statistics ** ** Description: ** Initializes the Replicator Server statistics memory segment. ** ** Inputs: ** none ** ** Outputs: ** none ** ** Returns: ** OK Function completed normally. */ STATUS RSstats_init() { STATUS status; char *val; i4 num_targs; SIZE_TYPE pages_alloc; u_i4 stats_size; RS_TARGET_STATS *targ; RS_TARGET_STATS *targ_end; RS_TABLE_STATS *tbl; RS_CONN *conn; RS_TBLDESC *tbl_info; CL_SYS_ERR sys_err; char server_num[4]; PMsetDefault(1, PMhost()); STprintf(server_num, ERx("%d"), (i4)RSserver_no); PMsetDefault(3, server_num); status = PMget(ERx("II.$.REPSERV.$.SHARED_STATISTICS"), &val); if (status == OK && STbcompare(val, 0, ERx("ON"), 0, TRUE) == 0) shared_stats = TRUE; num_targs = RSnum_conns - TARG_BASE; stats_size = sizeof(RS_MONITOR) + sizeof(RS_MONITOR) % sizeof(ALIGN_RESTRICT); targ_size = sizeof(RS_TARGET_STATS) + sizeof(RS_TARGET_STATS) % sizeof(ALIGN_RESTRICT); if (shared_stats) tbl_size = sizeof(RS_TABLE_STATS) + sizeof(RS_TABLE_STATS) % sizeof(ALIGN_RESTRICT); else tbl_size = 0; num_pages = (stats_size + num_targs * (targ_size + RSrdf_svcb.num_tbls * tbl_size)) / ME_MPAGESIZE + 1; if (shared_stats) { STprintf(sm_key, ERx("%s.%03d"), RS_STATS_FILE, RSserver_no); status = MEget_pages(ME_SSHARED_MASK | ME_CREATE_MASK | ME_MZERO_MASK | ME_NOTPERM_MASK, num_pages, sm_key, (PTR *)&mon_stats, &pages_alloc, &sys_err); if (status == ME_ALREADY_EXISTS) { status = MEsmdestroy(sm_key, &sys_err); if (status == OK) status = MEget_pages(ME_SSHARED_MASK | ME_CREATE_MASK | ME_MZERO_MASK | ME_NOTPERM_MASK, num_pages, sm_key, (PTR *)&mon_stats, &pages_alloc, &sys_err); } } else { mon_stats = (RS_MONITOR *)MEreqmem(0, num_pages * ME_MPAGESIZE, TRUE, &status); } if (status != OK) return (status); mon_stats->server_no = RSserver_no; mon_stats->local_db_no = RSlocal_conn.db_no; PCpid(&mon_stats->pid); mon_stats->startup_time = TMsecs(); mon_stats->num_targets = num_targs; mon_stats->num_tables = RSrdf_svcb.num_tbls; STcopy(RSlocal_conn.vnode_name, mon_stats->vnode_name); STcopy(RSlocal_conn.db_name, mon_stats->db_name); mon_stats->target_stats = (RS_TARGET_STATS *)((PTR)mon_stats + stats_size); targ_end = (RS_TARGET_STATS *)((PTR)mon_stats->target_stats + mon_stats->num_targets * (targ_size + tbl_size * mon_stats->num_tables)); for (conn = &RSconns[TARG_BASE], targ = mon_stats->target_stats; targ < targ_end; ++conn, targ = (RS_TARGET_STATS *)((PTR)targ + targ_size + tbl_size * mon_stats->num_tables)) { targ->db_no = conn->db_no; STcopy(conn->vnode_name, targ->vnode_name); STcopy(conn->db_name, targ->db_name); if (shared_stats) { targ->table_stats = (RS_TABLE_STATS *)((PTR)targ + targ_size); for (tbl_info = RSrdf_svcb.tbl_info, tbl = targ->table_stats; tbl < targ->table_stats + mon_stats->num_tables; ++tbl, ++tbl_info) { tbl->table_no = tbl_info->table_no; STcopy(tbl_info->table_owner, tbl->table_owner); STcopy(tbl_info->table_name, tbl->table_name); } } } return (OK); }
/* ** Name: scs_check_external_password ** ** Description: ** Check the external password for a role ** ** Inputs: ** scb - SCB ** ** authname - Role/User name being checked ** ** password - Role/User password ** ** auth_role - TRUE if authenticating a role ** ** Returns: ** E_DB_OK - Access is allowed ** ** E_DB_WARN - Access is denied ** ** E_DB_ERROR - Failure determining access ** ** History: ** 9-mar-94 (robf) ** Created ** 11-mar-94 (robf) ** Distinguish between access disallowed and some other ** error. Add SCF activity in case auth. server take a while ** 15-mar-94 (robf) ** Rework to allow for user or role authentication, add ** parameter auth_role. Make routine external, ** name scs_check_external_password, and move to scseauth.c ** 22-mar-1996 (stial01) ** Cast length passed to sc0m_allocate to i4. ** 16-jul-96 (stephenb) ** Add effective user to parameter list and pass to authentication ** server (fix primarily for ICE authentication, but useful ** information for the user anyway). ** 16-Nov-1998 (jenjo02) ** When suspending on BIO read, use CS_BIOR_MASK. */ DB_STATUS scs_check_external_password ( SCD_SCB *scb, DB_OWN_NAME *authname, DB_OWN_NAME *e_authname, DB_PASSWORD *password, bool auth_role ) { DB_STATUS status = E_DB_WARN; STATUS cl_stat; STATUS local_status; char pmname[64]; char *pmvalue; char target[64]; GCA_FS_PARMS fs_parms; SCS_REBUFF *re_buff = NULL; char *work_buff; i4 resume = 0; CS_SID sid; PTR save_data_area; char *q; char *gcmvalue; i4 error_index; i4 error_status; char *act_string; char blank_string[32] = ""; for (;;) { if (auth_role) act_string = "Validating external role password"; else act_string = "Validating external user password"; MEcopy((PTR)act_string, STlength(act_string), scb->scb_sscb.sscb_ics.ics_act1); scb->scb_sscb.sscb_ics.ics_l_act1 = (i4)STlength(act_string); /* ** Find the authentication mechanism for this role */ if (auth_role) { STprintf(pmname, "ii.$.secure.role_auth.%*s", scs_trimwhite(sizeof(*authname), (char*)authname), (char*)authname); } else { STprintf(pmname, "ii.$.secure.user_auth.%*s", scs_trimwhite(sizeof(*authname), (char*)authname), (char*)authname); } cl_stat = PMget(pmname, &pmvalue); if (cl_stat != OK) { sc0e_put(E_SC035A_EXTPWD_NO_AUTH_MECH, 0, 1, scs_trimwhite(sizeof(*authname), (char*)authname), (PTR)authname, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0 ); status = E_DB_ERROR; break; } /* ** Now we know the target mechanism, set up target destination ** ** Legal values are either 'value' which maps to value/authsvr ** or @value which is sent untranslated. */ if (*pmvalue != '@') STprintf(target,"%s/authsvr",pmvalue); else STprintf(target,"%s", pmvalue+1); /* ** Allocate buffer for processing the request */ status = sc0m_allocate(SCU_MZERO_MASK, (i4)sizeof(SCS_REBUFF), DB_SCF_ID, (PTR)SCS_MEM, SCRE_TAG, (PTR*)&re_buff); if (status != E_DB_OK) { /* sc0m_allocate puts error codes in return status */ sc0e_0_put(status, 0); status = E_DB_ERROR; break; } work_buff = re_buff->work_buff; gcmvalue = re_buff->gcmvalue; CSget_sid(&sid); save_data_area = work_buff; /* ** Build the fastselect request */ fs_parms.gca_user_name = NULL; fs_parms.gca_password = NULL; fs_parms.gca_account_name = NULL; fs_parms.gca_completion = cep_complete; fs_parms.gca_closure = NULL; fs_parms.gca_peer_protocol = GCA_PROTOCOL_LEVEL_61; fs_parms.gca_partner_name = target; fs_parms.gca_modifiers = GCA_RQ_GCM; fs_parms.gca_buffer = work_buff; fs_parms.gca_b_length = RQ_BUFF_SIZE; fs_parms.gca_message_type = GCM_SET; q = save_data_area; q += sizeof(i4); /* Past error_status */ q += sizeof(i4); /* Past error_index */ q += sizeof(i4); /* Past future[0] */ q += sizeof(i4); /* Past future[1] */ q += gcm_put_int(q, -1);/* Client perms */ q += gcm_put_int(q, 1); /* Row count */ q += gcm_put_int(q, 1); /* Element count */ if (auth_role) q += gcm_put_str(q, "exp.scf.auth_server.role_authenticate"); /* Class id */ else q += gcm_put_str(q, "exp.scf.auth_server.user_authenticate"); /* Class id */ q += gcm_put_str(q, "0"); /* Instance */ /* ** Now build the value. ** This consists of: ** Role: ** flag - 4 byte integer, currently 0 ** real user - 32 byte blank-padded ** effective user - 32 byte blank-padded ** role - 32 byte blank-padded ** password - 24 byte blank-padded ** User: ** flag - 4 byte integer, currently 1 ** real user - 32 byte blank-padded ** effective user - 32 byte blank-padded ** password - 24 byte blank-padded ** These are all padded into a single GCM value. ** Note: This assumes no NULL values in any of the fields. */ if (auth_role) { STprintf(gcmvalue,"%-4.4s%32.32s%32.32s%32.32s%-24.24s", "0", (char*)&scb->scb_sscb.sscb_ics.ics_rusername, e_authname ? (char*)e_authname : blank_string, (char*)authname, (char*)password); } else { STprintf(gcmvalue,"%-4.4s%32.32s%32.32s%-24.24s", "1", (char*)authname, e_authname ? (char*)e_authname : blank_string, (char*)password); } q += gcm_put_str(q, gcmvalue ); /* Value */ fs_parms.gca_msg_length = (i4)(q - save_data_area); break; } /* ** Now do the fastselect */ resume = 0; if (status == E_DB_OK) do { cl_stat = IIGCa_call(GCA_FASTSELECT, (GCA_PARMLIST *)&fs_parms, GCA_ASYNC_FLAG | GCA_ALT_EXIT | resume, (PTR)CS_find_scb(sid), (i4) -1, &local_status); if (cl_stat != OK) { sc0e_0_put(cl_stat, 0); sc0e_0_put(E_SC0357_EXTPWD_GCA_FASTSELECT, 0); status = E_DB_ERROR; break; } else { /* wait for completion routine to wake us */ cl_stat = CSsuspend(CS_BIOR_MASK, 0, 0); if (cl_stat != OK) { sc0e_0_put(cl_stat, 0); sc0e_0_put(E_SC0356_EXTPWD_GCA_CSSUSPEND, 0); status = E_DB_ERROR; resume = 0; break; } else /* completion handler called */ { switch ( cl_stat = fs_parms.gca_status ) { case OK: resume = 0; break; case E_GCFFFE_INCOMPLETE: resume = GCA_RESUME; break; case E_GC0032_NO_PEER: case E_GC0138_GCN_NO_SERVER: case E_GC0139_GCN_NO_DBMS: resume = 0; sc0e_put(E_SC0355_EXTPWD_GCA_NOPEER, 0, 2, scs_trimwhite(sizeof(*authname), (char*)authname), (PTR)authname, (i4)STlength(target), (PTR)target, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0 ); status = E_DB_ERROR; break; default: resume = 0; sc0e_0_put(cl_stat, 0); sc0e_0_put(E_SC0354_EXTPWD_GCA_COMPLETION, 0); status = E_DB_ERROR; break; } } } } while( resume != 0 ); /* ** Check if select worked OK, if not skip to the end */ if (status == E_DB_OK) { /* ** Got result of fastselect, so unpack and see what happened */ q = save_data_area; q += gcm_get_int(q, &error_status); q += gcm_get_int(q, &error_index); if (error_status != 0) { if (error_index == -1) { sc0e_0_put(error_status, 0); sc0e_0_put(E_SC0359_EXTPWD_GCM_ERROR, 0); status = E_DB_ERROR; } else { /* Access is denied */ status = E_DB_WARN; } } else { /* Access is allowed */ status = E_DB_OK; } } /* Reset activity */ scb->scb_sscb.sscb_ics.ics_l_act1 = 0; /* ** Free buffer if allocated */ if (re_buff) { if (sc0m_deallocate(0, (PTR *) &re_buff) != E_DB_OK) { sc0e_0_put(status, 0); } } return(status); }
main(int argc, char **argv) { STATUS status = OK; VMS_STATUS vStatus; char srcbuf[NAME_FILE_SIZE]; char dstbuf[NAME_FILE_SIZE]; char delFile[NAME_FILE_SIZE]; struct dsc$descriptor_s filename_d = { sizeof (delFile) - 1, DSC$K_DTYPE_T, DSC$K_CLASS_S, delFile }; FILE *srcFile = NULL; FILE *dstFile = NULL; FILE *nameFile = NULL; LOCATION loc; bool clusterArg = FALSE; bool unclusterArg = FALSE; bool writeOutput = FALSE; bool validSyntax; bool clustered = FALSE; bool v1DecryptErr = FALSE; bool rewrite = FALSE; bool isLogin = FALSE; i4 total_recs = 0; char local_host[MAX_LOC+CM_MAXATTRNAME]; char config_host[MAX_LOC+CM_MAXATTRNAME]; i2 i,j; i4 active_rec; i4 offset; char *onOff = NULL; bool srcOpened=FALSE; bool dstOpened=FALSE; bool printable = TRUE; GCN_QUEUE *gcn_q; GCN_QUEUE *merge_q; i4 rec_len = 0; QUEUE *q; u_i1 local_mask[ 8 ]; /* Must be 8 bytes */ char name[MAX_LOC+CM_MAXATTRNAME]; i4 count; char *p = NULL; i4 dcryptFail = 0; i2 pc; char *pv[ 3 ]; GCN_DB_REC0 tmp_rec; SYSTIME timestamp; MEadvise(ME_INGRES_ALLOC); SIeqinit(); GChostname( local_host, sizeof(local_host)); STcopy (PMhost(), config_host); if (argc == 1) validSyntax = TRUE; /* ** Parse input arguments. */ for (i = 1; i < argc; i++) { validSyntax = FALSE; for (j = 0; j < argLen; j++) { if (!STncasecmp(arg[j],argv[i], STlength(argv[i]))) { switch(j) { case HELP1: case HELP2: case HELP3: case HELP4: usage(); break; case VERBOSE: validSyntax = TRUE; verboseArg = TRUE; break; case CLUSTER: validSyntax = TRUE; clusterArg = TRUE; writeOutput = TRUE; break; case UNCLUSTER: validSyntax = TRUE; unclusterArg = TRUE; writeOutput = TRUE; break; } } /* if (!STncasecmp(arg[j],argv[i], STlength(argv[i]))) */ if (validSyntax) break; } /* for (j = 0; j < argLen; j++) */ if (!validSyntax) break; } /* for (i = 1; i < argc; i++) */ if (!validSyntax) { usage(); PCexit(1); } if (clusterArg && unclusterArg) { SIprintf("Cannot specify both -c and -u\n\n"); usage(); PCexit(1); } if (verboseArg) SIprintf("Local host is %s\n", local_host); /* ** Generate key seeds for encoding and decoding. */ STpolycat( 2, GCN_LOGIN_PREFIX, local_host, name ); gcn_init_mask( name, sizeof( local_mask ), local_mask ); QUinit(&gcn_qhead); QUinit(&merge_qhead); PMinit(); /* ** See if this is a clustered installation. If it is, ** the node, login, and attribute files have no file extension. */ if ( PMload( (LOCATION *)NULL, (PM_ERR_FUNC *)NULL ) != OK ) { SIprintf("Error reading config.dat, exiting\n"); goto cvt_exit; } PMsetDefault( 0, SystemCfgPrefix ); PMsetDefault( 1, config_host ); PMsetDefault( 2, ERx("gcn") ); status = PMget( ERx("!.cluster_mode"), &onOff); if (onOff && *onOff) ; else onOff = "OFF"; if (verboseArg) SIprintf("Cluster mode is %s\n", onOff); if (!clusterArg && !unclusterArg) clustered = !STncasecmp(onOff, "ON", STlength(onOff)); /* ** Rewrite the named GCN files. For clustered installations, the ** node, login and attribute files have no hostname extension. */ for ( i = 0; i < NBR_NAMED_FILES; i++ ) { /* ** Ticket files are simply deleted. */ if (i == IILTICKET || i == IIRTICKET) { STprintf(delFile, "II_SYSTEM:[INGRES.FILES.NAME]II%s*;*", named_file[i].file); if (verboseArg) SIprintf("Deleting %s\n", delFile); filename_d.dsc$w_length = STlength(delFile); vStatus = lib$delete_file(&filename_d,0,0,0,0,0,0,0,0,0); if (!vStatus & STS$M_SUCCESS) SIprintf("delete of %s failed, status is 0x%d\n", delFile, vStatus); continue; } rewrite = FALSE; if (!clusterArg && !unclusterArg) writeOutput = FALSE; if ( ( status = NMloc( FILES, PATH & FILENAME, (char *)NULL, &loc ) ) != OK ) { SIprintf("iicvtgcn: Could not find II_SYSTEM:[ingres.files]\n"); goto cvt_exit; } LOfaddpath( &loc, "name", &loc ); if (clustered || unclusterArg) { if (named_file[i].add_cluster_node) STprintf( srcbuf, "II%s_%s", named_file[i].file,config_host); else STprintf(srcbuf, "II%s", named_file[i].file); } else STprintf( srcbuf, "II%s_%s", named_file[i].file,config_host); if (verboseArg) SIprintf("Opening %s for input\n", srcbuf); LOfstfile( srcbuf, &loc ); /* ** Ignore non-existent files. */ if ( LOexist( &loc ) != OK ) { if (verboseArg) SIprintf("%s does not exist\n", srcbuf); continue; } /* ** Open the existing file as "regular" RACC. */ status = SIfopen( &loc, "r", (i4)SI_RACC, sizeof( GCN_DB_REC0 ), &srcFile ); /* ** If the file exists but can't be opened, it's already optimized. */ if (status == E_CL1904_SI_CANT_OPEN && ( LOexist( &loc ) == OK ) ) { /* ** Open the existing file as "optimized" RACC. */ status = SIfopen( &loc, "r", (i4)GCN_RACC_FILE, sizeof( GCN_DB_REC0 ), &srcFile ); if (status != OK) { SIprintf( "iicvtgcn: Error opening %s, status is %x\n", srcbuf, status ); continue; } if (verboseArg) SIprintf("%s is already optimized\n", srcbuf); } else if (status != OK) { SIprintf( "iicvtgcn: Error opening %s, status is %x\n", srcbuf, status ); continue; } /* ** A successful open as SI_RACC means the file is not optimized. ** This file needs a rewrite. */ else { if (verboseArg) SIprintf("Rewriting %s as optimized\n", srcbuf); writeOutput = TRUE; } srcOpened = TRUE; while ( status == OK ) { /* ** Read the source data and store in a queue for analysis. */ status = SIread( srcFile, sizeof( GCN_DB_REC0 ), &count, (PTR)&tmp_rec ); if ( status == ENDFILE ) break; if ( status != OK ) { SIprintf("iicvtgcn: Error reading %s, status is %x\n", srcbuf, status); goto cvt_exit; } else if (tmp_rec.gcn_invalid && tmp_rec.gcn_tup_id != -1) continue; else { gcn_q = (GCN_QUEUE *)MEreqmem(0, sizeof(GCN_QUEUE),0,NULL); if (!gcn_q) { SIprintf("iicvtgcn: Cannot allocate memory, exiting\n"); goto cvt_exit; } MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), (PTR)&gcn_q->buf); QUinsert(&gcn_q->q, &gcn_qhead); /* ** EOF record found. */ if (gcn_q->buf.gcn_tup_id == -1) { gcn_q->buf.gcn_l_uid = 0; gcn_q->buf.gcn_uid[0] = '\0'; gcn_q->buf.gcn_l_obj = 0; gcn_q->buf.gcn_obj[0] = '\0'; gcn_q->buf.gcn_l_val = 0; gcn_q->buf.gcn_val[0] = '\0'; gcn_q->buf.gcn_invalid = TRUE; break; } } } /* while ( status == OK ) */ /* ** Decrypt passwords for IILOGIN files. If any V1 records are found, ** the IILOGIN file will need to be rewritten. */ isLogin = FALSE; for (q = gcn_qhead.q_prev; q != &gcn_qhead; q = q->q_prev) { gcn_q = (GCN_QUEUE *)q; /* ** EOF record found. */ if (gcn_q->buf.gcn_tup_id == -1) { gcn_q->buf.gcn_invalid = TRUE; break; } if (i == IILOGIN) { isLogin = TRUE; MEcopy((PTR)&gcn_q->buf, sizeof(GCN_DB_REC0), (PTR)&tmp_rec); if (verboseArg) SIprintf("\tEncoding vnode %s\n", gcn_q->buf.gcn_obj); if (unclusterArg) status = gcn_recrypt( FALSE, local_mask, gcn_q->buf.gcn_val, &v1DecryptErr, &writeOutput); else if (clusterArg) status = gcn_recrypt( TRUE, local_mask, gcn_q->buf.gcn_val, &v1DecryptErr, &writeOutput); else status = gcn_recrypt( clustered, local_mask, gcn_q->buf.gcn_val, &v1DecryptErr, &writeOutput); if (status != OK) { if (verboseArg) SIprintf("Cannot decrypt password from " \ "vnode %s status %x\n", gcn_q->buf.gcn_obj, status); dcryptFail++; MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), (PTR)&gcn_q->buf); continue; } if (v1DecryptErr) { if (verboseArg) SIprintf("Cannot decrypt password from " \ "vnode %s\n", gcn_q->buf.gcn_obj); dcryptFail++; MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), (PTR)&gcn_q->buf); continue; } } /* if (LOGIN) */ } /* for (q = gcn_qhead.q_prev; q != &gcn_qhead; q = q->q_prev) */ if (dcryptFail && verboseArg && isLogin) { if (clustered || unclusterArg ) SIprintf("\n%d vnode(s) could not be decrypted.\n" \ "Probably some login entries were created on " \ "another node.\nTry executing iicvtgcn on another " \ "node to merge the other node's entries.\n\n", dcryptFail); else SIprintf("\n%d vnode(s) could not be decrypted.\n" \ "Probably the login file was created on " \ "another host.\nTry executing iicvtgcn on " \ "a different host.\n\n", dcryptFail); } if (!writeOutput) { if (srcOpened) SIclose(srcFile); srcOpened = FALSE; cleanup_queues(); continue; } /* ** Open the destination file with special GCN_RACC_FILE flag, for ** optimized writes. */ if (clustered || clusterArg) { if (named_file[i].add_cluster_node) STprintf( dstbuf, "II%s_%s", named_file[i].file, local_host); else STprintf(dstbuf, "II%s", named_file[i].file); } else STprintf( dstbuf, "II%s_%s", named_file[i].file, local_host); if (clusterArg && !named_file[i].add_cluster_node) rewrite = TRUE; LOfstfile( dstbuf, &loc ); if (rewrite) { status = SIfopen( &loc, "rw", (i4)GCN_RACC_FILE, sizeof( GCN_DB_REC0 ), &dstFile ); if ( status != OK ) { status = SIfopen( &loc, "w", (i4)GCN_RACC_FILE, sizeof( GCN_DB_REC0 ), &dstFile ); if (status == OK) { SIclose( dstFile); status = SIfopen( &loc, "rw", (i4)GCN_RACC_FILE, sizeof( GCN_DB_REC0 ), &dstFile ); } } } else status = SIfopen( &loc, "w", (i4)GCN_RACC_FILE, sizeof( GCN_DB_REC0 ), &dstFile ); if ( status != OK ) { SIprintf( "iicvtgcn: Error opening %s, status is %x\n",dstbuf, status ); goto cvt_exit; } dstOpened = TRUE; if (verboseArg) SIprintf("%s %s\n", rewrite ? "Rewriting " : "Writing ", dstbuf); /* ** If this is a merge operation (-c), login, attribute or ** node files may change the location of EOF, since the ** file to be merged may have different records than ** the destination file. ** Before merging, the output file is read and fed into a queue. ** Then each merge record is compared to each output record. ** If the entire records match, nothing is done. ** If a global login record matches only the vnode name ** global or private records will be added if not present; ** otherwise, nothing is done. ** Node or attribute records may be added if only one field ** fails to match. */ status = SIfseek(dstFile, (i4)0, SI_P_START); if (rewrite) { while ( status == OK ) { /* ** Read the source data and store in a queue for analysis. */ status = SIread( dstFile, sizeof( GCN_DB_REC0 ), &count, (PTR)&tmp_rec ); if ( status == ENDFILE ) break; if ( status != OK ) { SIprintf("iicvtgcn: Error reading %s, status is %x\n", dstbuf, status); goto cvt_exit; } else if (tmp_rec.gcn_invalid && tmp_rec.gcn_tup_id != -1) continue; else { merge_q = (GCN_QUEUE *)MEreqmem(0, sizeof(GCN_QUEUE),0,NULL); if (!merge_q) { SIprintf("iicvtgcn: Cannot allocate memory, exiting\n"); goto cvt_exit; } MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), (PTR)&merge_q->buf); QUinsert(&merge_q->q, &merge_qhead); /* ** EOF record found. */ if (merge_q->buf.gcn_tup_id == -1) break; } if ( status == ENDFILE ) break; } /* while ( status == OK ) */ /* ** Go through the input queue. Compare each record with ** the output (merge) queue. If the record is invalid ** or doesn't match, it's ignored. */ dcryptFail = 0; total_recs = 0; for (q = gcn_qhead.q_prev; q != &gcn_qhead; q = q->q_prev) { SYSTIME timestamp; gcn_q = (GCN_QUEUE *)q; if (gcn_q->buf.gcn_tup_id == -1) break; if ( !gcn_merge_rec( gcn_q, isLogin ) ) continue; if (isLogin) { /* ** Login passwords get encrypted as V0 in a cluster ** environment. */ MEcopy((PTR)&gcn_q->buf, sizeof(GCN_DB_REC0), (PTR)&tmp_rec); status = gcn_recrypt( TRUE, local_mask, gcn_q->buf.gcn_val, &v1DecryptErr, &writeOutput); if (status != OK) { if (verboseArg) SIprintf("Cannot decrypt password from " \ "vnode %s status %x\n", gcn_q->buf.gcn_obj, status); dcryptFail++; MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), (PTR)&gcn_q->buf); continue; } if (v1DecryptErr) { if (verboseArg) SIprintf("Cannot decrypt password from " \ "vnode %s\n", gcn_q->buf.gcn_obj); dcryptFail++; MEcopy((PTR)&tmp_rec, sizeof(GCN_DB_REC0), (PTR)&gcn_q->buf); continue; } } merge_q = (GCN_QUEUE *)MEreqmem(0, sizeof(GCN_QUEUE),0,NULL); if (!merge_q) { SIprintf("iicvtgcn: Cannot allocate memory, exiting\n"); goto cvt_exit; } MEcopy((PTR)&gcn_q->buf, sizeof(GCN_DB_REC0), (PTR)&merge_q->buf); total_recs++; QUinsert(&merge_q->q, &merge_qhead); } if (dcryptFail && verboseArg && isLogin) { if (clustered || unclusterArg ) SIprintf("\n%d vnode(s) could not be decrypted.\n" \ "Probably some login entries were created on " \ "another node.\nTry executing iicvtgcn on another " \ "node to merge the other node's entries.\n\n", dcryptFail); else SIprintf("\n%d vnode(s) could not be decrypted.\n" \ "Probably the login file was created on " \ "another host.\nTry executing iicvtgcn on " \ "a different host.\n\n", dcryptFail); } if (verboseArg) SIprintf("Total records merged: %d\n", total_recs); /* ** If no records to merge, clean up and continue. */ if (!total_recs) { cleanup_queues(); continue; } status = SIfseek(dstFile, (i4)0, SI_P_START); active_rec = 0; for (q = merge_qhead.q_prev; q != &merge_qhead; q = q->q_prev) { merge_q = (GCN_QUEUE *)q; if (verboseArg) SIprintf("Rewriting %s record vnode %s val %s\n", !STcasecmp("*", merge_q->buf.gcn_uid) ? "global" : "private", merge_q->buf.gcn_obj, merge_q->buf.gcn_val); if (merge_q->buf.gcn_tup_id == -1) continue; status = SIwrite(sizeof( GCN_DB_REC0 ), (char *)&merge_q->buf, &count, dstFile ); if ( status != OK) { SIprintf( "iicvtgcn: Failed to write file %s, " \ "status is %x\n", srcbuf, status ); goto cvt_exit; } active_rec++; } /* ** Write new EOF record. */ tmp_rec.gcn_tup_id = -1; tmp_rec.gcn_l_uid = 0; tmp_rec.gcn_uid[0] = '\0'; tmp_rec.gcn_l_obj = 0; tmp_rec.gcn_obj[0] = '\0'; tmp_rec.gcn_l_val = 0; tmp_rec.gcn_val[0] = '\0'; tmp_rec.gcn_invalid = TRUE; offset = active_rec * sizeof(GCN_DB_REC0); status = SIfseek(dstFile, (i4)offset, SI_P_START); status = SIwrite(sizeof( GCN_DB_REC0 ), (PTR)&tmp_rec, &count, dstFile ); } else { for (q = gcn_qhead.q_prev; q != &gcn_qhead; q = q->q_prev) { gcn_q = (GCN_QUEUE *)q; gcn_q->buf.gcn_l_val = STlength(gcn_q->buf.gcn_val); if (verboseArg) SIprintf("Writing %s record vnode %s val %s\n", !STcasecmp("*", gcn_q->buf.gcn_uid) ? "global" : "private", gcn_q->buf.gcn_obj, gcn_q->buf.gcn_val); status = SIwrite(sizeof( GCN_DB_REC0 ), (char *)&gcn_q->buf, &count, dstFile ); if ( status != OK) { SIprintf( "iicvtgcn: Failed to write file %s, " \ "status is %x\n", srcbuf, status ); goto cvt_exit; } } } /* if (rewrite) */ cleanup_queues(); SIclose( srcFile ); srcOpened = FALSE; SIclose( dstFile ); dstOpened = FALSE; } /* for (i = 0; i < NBR_NAMED_FILES; i++ ) */ cvt_exit: cleanup_queues(); if (srcOpened) SIclose(srcFile); if (dstOpened) SIclose(dstFile); PCexit( OK ); }
static VOID gcn_nq_filename( char *type, char *host, char *filename ) { i4 len, plen, slen; char *onOff = NULL; bool clustered = FALSE; STATUS status; /* ** Filename template: II<type>[_<host>] */ plen = 2; len = STlength( type ); slen = (host && *host) ? STlength( host ) + 1 : 0; /* ** Adjust filename for platform limitations: ** drop prefix if type and suffix OK; ** drop suffix if prefix and type OK; ** otherwise, drop both prefix and suffix. */ if ( plen + len + slen > LO_NM_LEN ) if ( len + slen <= LO_NM_LEN ) plen = 0; else if ( plen + len <= LO_NM_LEN ) slen = 0; else plen = slen = 0; /* ** See if this is a clustered installation. If it is, ** the node, login, and attribute files have no file extension. */ if ( PMload( (LOCATION *)NULL, (PM_ERR_FUNC *)NULL ) != OK ) { SIprintf("Error reading config.dat\n"); return; } PMsetDefault( 0, "ii" ); PMsetDefault( 1, host ); PMsetDefault( 2, ERx("gcn") ); status = PMget( ERx("!.cluster_mode"), &onOff); if (onOff && *onOff) clustered = !STncasecmp(onOff, "ON", STlength(onOff)); if (clustered && (!STncasecmp("LOGIN", type, STlength(type)) || !STncasecmp("NODE", type, STlength(type)) || !STncasecmp("ATTR", type, STlength(type)))) slen = 0; CVupper(type); STprintf( filename, "%s%s%s%s", plen ? "II" : "", type, slen ? "_" : "", slen ? host : "" ); /* ** Finally, truncate the filename if it is too long ** (hopefully this will never happen). */ if ( STlength( filename ) > LO_NM_LEN ) filename[ LO_NM_LEN ] = '\0'; return; }
i4 main( i4 argc, char * argv[]) { char c='\0'; char *tz_file=NULL; char *tz_name=NULL; char *tz_def; char tzname[TM_MAX_TZNAME+1]; char tzfile[MAX_LOC+1]; char ioptarg[MAX_LOC + 1]; char tz_pmvalue[MAX_LOC + 1]; char tz_pmname[MAX_LOC + 1]; char *p, *ip, *pm_value; char *tm_tztype; char chr='/'; char *out_file; i4 ioptind=1, i; char *tm_tztime; i4 timecnt, tempi, temptype, temptz; char buf[sizeof(TM_TZ_CB)+TM_MAX_TIMECNT*(sizeof(i4)+1)]; FILE *fid; LOCATION loc_root, tmp_loc; STATUS status=OK; TM_TZ_CB *tm_tz_cb; struct timevect time_v; appname = argv[0]; if( TMtz_getopt(argc, argv, "n:name:f:file", &ioptind, ioptarg, &c) == OK) { switch (c) { case 'f': tz_file = ioptarg; break; case 'n': tz_name = ioptarg; break; default: break; } } else { TMtz_usage(); PCexit(FAIL); } if( tz_file == NULL) { if( tz_name == NULL) { /* Get II_TIMEZONE_NAME value */ NMgtAt(ERx("II_TIMEZONE_NAME"), &tz_def); if (!tz_def || !(*tz_def)) { SIprintf("%s: %s_TIMEZONE_NAME is not set\n", appname, SystemVarPrefix); PCexit(FAIL); } STncpy(tzname, tz_def, TM_MAX_TZNAME); tzname[ TM_MAX_TZNAME ] = EOS; } else { STncpy(tzname, tz_name, TM_MAX_TZNAME); tzname[ TM_MAX_TZNAME ] = EOS; } PMinit(); if( PMload( NULL, (PM_ERR_FUNC *)NULL) != OK) { SIprintf("%s: Error loading PM %s_CONFIG/config.dat file\n", appname, SystemVarPrefix); PCexit(FAIL); } /* Get timezone file name */ STprintf( tz_pmname, ERx("%s.*.tz.%s"), SystemCfgPrefix, tzname); if( PMget( tz_pmname, &pm_value) != OK) { SIprintf("%s: Error locating %s in PM config.dat file\n", appname, tz_pmname); PCexit(FAIL); } do { if((status = NMloc(FILES, PATH, ERx("zoneinfo"), &loc_root)) != OK) break; #if defined(conf_BUILD_ARCH_32_64) && defined(BUILD_ARCH64) if((status = LOfaddpath(&loc_root, ERx("lp64"), &loc_root)) != OK) break; #endif #if defined(conf_BUILD_ARCH_64_32) && defined(BUILD_ARCH32) { /* ** Reverse hybrid support must be available in ALL ** 32bit binaries */ char *rhbsup; NMgtAt("II_LP32_ENABLED", &rhbsup); if ( (rhbsup && *rhbsup) && ( !(STbcompare(rhbsup, 0, "ON", 0, TRUE)) || !(STbcompare(rhbsup, 0, "TRUE", 0, TRUE)))) status = LOfaddpath(&loc_root, "lp32", &loc_root); } #endif /* reverse hybrid */ STcopy( pm_value, tz_pmvalue); /* ** Compose the directory path */ for( p = tz_pmvalue, ip = tz_pmvalue; (p = STchr(ip, chr)) != NULL;) { *p = EOS; if((status = LOfaddpath(&loc_root, ip, &loc_root)) != OK) break; ip = CMnext(p); } /* ** Add file name to the directory path */ if((status = LOfroms(FILENAME, ip, &tmp_loc)) != OK) break; status = LOstfile( &tmp_loc, &loc_root); } while( FALSE); if( status != OK) { SIprintf("%s: Error composing timezone file name for %s\n", appname, tz_pmvalue); PCexit(FAIL); } } else { STcopy("<unknown>", tzname); STncpy( tzfile, tz_file, MAX_LOC); tzfile[ MAX_LOC ] = EOS; if( LOfroms(FILENAME&PATH, tzfile, &loc_root) != OK) { SIprintf("%s: Error composing timezone file name for %s\n", appname, tz_pmvalue); PCexit(FAIL); } } /* ** Now open the timezone information file */ do { if((status = SIfopen( &loc_root, ERx("r"), SI_VAR, sizeof buf, &fid)) != OK) break; status = SIread(fid, sizeof buf, &i, buf); status = SIclose(fid); } while(FALSE); if( status != OK) { LOtos( &loc_root, &out_file); SIprintf("%s: Error opening %s for timezone %s\n", appname, out_file, tzname); PCexit(FAIL); } tm_tz_cb = (TM_TZ_CB *)&buf; I4ASSIGN_MACRO( tm_tz_cb->timecnt, timecnt); /* Make sure the input file has correct file size */ if( timecnt > TM_MAX_TIMECNT || timecnt < 0 || i != sizeof(TM_TZ_CB) + timecnt*(sizeof(i4)+1)) { LOtos( &loc_root, &out_file); SIprintf( "%s: Invalid file format for timezone file %s for timezone %s\n", appname, out_file, tzname); SIprintf( " File size: %d, Expected file size: %d, time periods: %d\n", i, sizeof(TM_TZ_CB) + timecnt*(sizeof(i4)+1), timecnt); PCexit(FAIL); } /* Now we are all set to display the content of timezone information file */ LOtos( &loc_root, &out_file); SIprintf("\n\n"); SIprintf("timezone name: %s\n", tzname); SIprintf("timezone file: %s\n", out_file); SIprintf("-------------------------------------"); SIprintf("-------------------------------------\n"); if(timecnt == 0) { I4ASSIGN_MACRO( tm_tz_cb->tzinfo[0].gmtoff, tempi); SIprintf(" Fixed GMT offset (secs): %d\n", tempi); } else { SIprintf("\tPeriod Begin"); SIprintf("\t\tGMT offset\n"); SIprintf("\t(YYYY_MM_DD HH:MM)"); SIprintf("\t(Minute)\n\n"); tm_tztype = buf + sizeof(TM_TZ_CB); tm_tztime = tm_tztype + timecnt; i=0; while( i < timecnt) { I4ASSIGN_MACRO( *tm_tztime, tempi); /* Adjust for timezone */ if( i == 0) temptype = (i4)tm_tztype[i+1]; else temptype = (i4)tm_tztype[i-1]; I4ASSIGN_MACRO( tm_tz_cb->tzinfo[temptype].gmtoff, temptz); /* Get real timezone */ tempi += temptz; temptype = (i4)tm_tztype[i]; I4ASSIGN_MACRO( tm_tz_cb->tzinfo[temptype].gmtoff, temptz); TMtz_cvtime( tempi, &time_v); SIprintf("\t%04d_%02d_%02d %02d:%02d\t%d\t%s\n", time_v.tm_year+1900, time_v.tm_mon+1, time_v.tm_mday, time_v.tm_hour, time_v.tm_min, temptz/60, tm_tz_cb->tzlabel + tm_tz_cb->tzinfo[temptype].abbrind); tm_tztime += sizeof(i4); i++; } } PCexit(OK); }
/* ** Name: main -main routine. ** ** Description: ** This routine is the main control routine for iirundbms. Starting an ** iidbms server consists of: ** 1) Opening and reading the PM data ** 2) Validating server arguments, converting to VMS internal format. ** 3) Creating mailbox for communication with server. ** 4) creating server processing. ** 5) Sending server process its commands. ** 6) Checking whether server startup succeeded or not. ** ** iirundbms command line format is: ** iirundbms <server type> <server flavor> ** where server type is something like "dbms", "recovery", "star", and ** server flavor is something like "public", "nonames", "benchmark". ** ** Inputs: ** argc - number of arguments (should be 1, 2 or 3) ** argv - argument array. ** ** Outputs: ** None ** ** Returns: ** a VMS status code is returned. ** ** History: ** 31-jan-1994 (bryanp) ** Added comment header. ** 21-Jan-1998 (horda03) Bug 68559 ** For GCC servers where a server flavour has been specified, ** command line to start the server must specify the server ** flavour in the form; "-instance=<server_flavor>" in order ** for the GCC to pickup the correct configuration details. ** 22-feb-1998 (chash01) ** RMCMD (Visual DBA backend server) startup takes two VMS CREPRC ** calls, one ihere, one in rmcmd.exe. When RMCMD server starts ** the PID returned by CREPRC in this module is no longer valid. ** WE have to first decode pid in the t_user_data field returned by ** RMCMD server in termination mailbox before print PID and ** server name to terminal. ** 31-Aug-2007 (ashco01) Bug #113490 & Bug #119021. ** Corrected detection of 'instance name' for GCB & GCD. ** 05-Dec-2007 (ashco01) Bug #119561. ** Ensure that all Ingres back-end detached processes define the ** SYS$SCRATCH logical as this is referenced via II_TEMPORARY ** when placing temporary DCL files. ** 10-Dec-2007 (ashco01) Bug #119561 ** Define SYS$SCRATCH within all detached processes. */ main( int argc, char **argv ) { static $DESCALLOC( prcnam ); unsigned int pqlcnt = 0; $DESCALLOC( uicdsc ); char *param; char prcbuf[16]; ACCDEF2 accmsg; unsigned int pid; unsigned short chan; unsigned short term; unsigned int mbxunt; int dviitem; char buf[128], tmp[128]; II_VMS_MASK_LONGWORD efc_state; char *log_start_commands; IOSB iosb; ER_ARGUMENT dummy_arg; i4 i; STATUS status; i4 gcc = 0; i4 gcc_instance = 0; i4 gcb = 0; i4 gcb_instance = 0; i4 gcd = 0; i4 gcd_instance = 0; /* ** setup the type and server_flavor parameters */ if ( argc >= 2 ) { server_type = argv[1]; /* Are we starting a GCB, GCC or GCD ? */ if (STbcompare( server_type, 3, "gcc", 3, TRUE ) == 0) gcc++; if (STbcompare( server_type, 3, "gcb", 3, TRUE ) == 0) gcb++; if (STbcompare( server_type, 3, "gcd", 3, TRUE ) == 0) gcd++; } if ( argc >= 3 ) { server_flavor = argv[2]; /* Need to precede server_flavor with "-instance=" ** if we're starting a GCB, GCC or GCD. */ gcc_instance = gcc; gcb_instance = gcb; gcd_instance = gcd; } /* ** initialize PM routines and setup the default ** search parameters for config.dat */ status = PMinit( ); if (status) { pmerr_func(status, 0, &dummy_arg); return (status); } switch( status = PMload((LOCATION *)NULL, pmerr_func) ) { case OK: /* Loaded sucessfully */ break; case PM_FILE_BAD: /* syntax error */ if (status != FAIL) /* As of Nov 1993, PM.H defines PM_FILE_BAD 1 */ pmerr_func(status, (i4)0, &dummy_arg); return (status); default: /* unable to open file */ if (status != FAIL) /* FAIL is a useless status to report... */ pmerr_func(status, (i4)0, &dummy_arg); return (status); } #ifdef EDBC PMsetDefault( 0, ERx( "ed" ) ); #else PMsetDefault( 0, ERx( "ii" ) ); #endif PMsetDefault( 1, PMhost( ) ); PMsetDefault( 2, server_type ); PMsetDefault( 3, server_flavor ); /* read and process pm parameters */ for ( i = 0; pm_option[i].PM_name != NULL; i++ ) { status = PMget( pm_option[i].PM_name, ¶m ); if ( status != OK ) continue; switch ( pm_option[i].type ) { unsigned int *target; case TYPE_CLRFLG: if ( STbcompare(param, 0, "off", 0, TRUE) != 0 && STbcompare(param, 0, "on", 0, TRUE) != 0 ) { SIprintf("IIRUNDBMS: %s value must be ON or OFF\n", pm_option[i].PM_name); SIflush(stdout); log_errmsg( "Must be ON or OFF", SS$_BADPARAM, 1 ); return (SS$_BADPARAM); } target = (unsigned int *)pm_option[i].target; if ( STbcompare(param, 0, pm_option[i].keyword, 0, TRUE) == 0) *target &= ~(int)pm_option[i].parameter; if ( msg_echo && (STscompare( pm_option[i].PM_name, 0, echo, 0 ) == 0) ) ERoptlog( pm_option[i].PM_name, param ); break; case TYPE_SETFLG: if ( STbcompare(param, 0, "off", 0, TRUE) != 0 && STbcompare(param, 0, "on", 0, TRUE) != 0 ) { SIprintf("IIRUNDBMS: %s value must be ON or OFF\n", pm_option[i].PM_name); SIflush(stdout); log_errmsg( "Must be ON or OFF", SS$_BADPARAM, 1 ); return (SS$_BADPARAM); } target = (unsigned int *)pm_option[i].target; if ( STbcompare(param, 0, pm_option[i].keyword, 0, TRUE) == 0) *target |= (int)pm_option[i].parameter; if ( msg_echo ) ERoptlog( pm_option[i].PM_name, param ); break; case TYPE_INT: target = (unsigned int *)pm_option[i].target; status = CVal( param, target ); if (status) { SIprintf("IIRUNDBMS: %s value must be an integer\n", pm_option[i].PM_name); SIflush(stdout); pmerr_func(status, 0, &dummy_arg); return (SS$_BADPARAM); } if ( msg_echo ) { STprintf( buf, "%d", *target ); ERoptlog( pm_option[i].PM_name, buf ); } break; case TYPE_UIC: { $DESCINIT( uicdsc, param ); status = iics_cvtuic( &uicdsc, (char *)pm_option[i].target ); if ( !(status & 1) ) { log_errmsg( "vms_uic invalid", status, 1 ); return (status); /* B56811 */ } if ( msg_echo ) { if ( *(unsigned int *)(pm_option[i].target) != 0 ) { STprintf( buf, "%s [%o,%o]", param, ((uic >> 16) & 0xffff), (uic & 0xffff) ); ERoptlog( pm_option[i].PM_name, buf ); } } break; } case TYPE_STR: if (STlength(param) > MAX_STRING_OPTION_LENGTH) { SIprintf("IIRUNDBMS: Max length for %s is %d\n", pm_option[i].PM_name, MAX_STRING_OPTION_LENGTH); SIflush(stdout); return (SS$_BADPARAM); } STcopy( param, (char *)pm_option[i].target ); if ( msg_echo ) ERoptlog( pm_option[i].PM_name, param ); break; case TYPE_PQL: /* ** build VMS process quota block */ quota[pqlcnt].name = (char)pm_option[i].parameter; status = CVal( param, "a[pqlcnt].value ); if (status) { SIprintf("IIRUNDBMS: %s value must be an integer\n", pm_option[i].PM_name); SIflush(stdout); pmerr_func(status, 0, &dummy_arg); return (SS$_BADPARAM); } pqlcnt++; if ( msg_echo ) ERoptlog( pm_option[i].PM_name, param ); break; case TYPE_PRIV: { char prvbuf[512]; char *p, *q; i4 j; /* ** Remove white space then ** convert the string to upper case, then ** remove leading and trailing parens */ if (STlength(param) >= sizeof(prvbuf)) { SIprintf("IIRUNDBMS: vms_privileges are too long\n"); SIprintf(" Actual length (%d) exceeds maximum (%d)\n", STlength(param), sizeof(prvbuf)); SIflush(stdout); return (SS$_BADPARAM); } STcopy( param, prvbuf); STtrmwhite( prvbuf ); CVupper( prvbuf ); /* ** Scan the comma seperated privilege list and set the ** privileges for each privileges keywork in the list. */ for ( p = prvbuf; p != 0 && *p != 0; p = q ) { if ( (q = STindex( p, ERx( "," ), 0 )) != NULL ) *q++ = '\0'; else if ( (q = STindex( p, ERx( ")" ), 0 )) != NULL ) *q++ = '\0'; if ( *p == '(' ) p++; for ( j = 0; prv_table[j].prv_name != NULL; j++ ) { if ( STscompare( p, 4, prv_table[j].prv_name, 4 ) == 0 ) { prvadr[0] |= prv_table[j].prv_code_low; prvadr[1] |= prv_table[j].prv_code_hi; if ( msg_echo ) ERoptlog( pm_option[i].PM_name, prv_table[j].prv_name ); break; } } if (prv_table[j].prv_name == NULL) { /* ** We failed to find privilege "p" in our table */ SIprintf("IIRUNDBMS: Syntax error in privilege list\n"); SIprintf(" Error near byte %d of string %s", p - prvbuf, param); SIflush(stdout); ERoptlog("Unrecognized privilege:", p); return (SS$_BADPARAM); } } break; } default: break; } }
/* ** Name: sxapo_init_cnf - Initialize SXAPO configuration from the PM file. ** ** Description: ** This routine initializes the SXAPO configuration from the ** PM configuration file. ** ** Inputs: ** None. ** ** Outputs: ** err_code Error code returned to caller. ** ** Returns: ** DB_STATUS ** ** History: ** 6-jan-94 (stephenb) ** Initial creation. */ static DB_STATUS sxapo_init_cnf( i4 *err_code) { DB_STATUS status = E_DB_OK; STATUS clstat; i4 local_err; char *pmfile; char *pmvalue; *err_code = E_SX0000_OK; for (;;) { /* ** Allow private override on PM file */ NMgtAt("II_SXF_PMFILE", &pmfile); if (pmfile && *pmfile) { LOCATION pmloc; TRdisplay("Loading SXF-PM file '%s'\n",pmfile); LOfroms(PATH & FILENAME, pmfile, &pmloc); if(PMload(&pmloc,NULL)!=OK) TRdisplay("Error loading PMfile '%s'\n",pmfile); } /* ** Get auditing status */ if (PMget(SX_C2_MODE,&pmvalue) == OK) { if (!STbcompare(pmvalue, 0, SX_C2_MODE_ON, 0, TRUE)) { /* ** Auditing on */ Sxapo_cb->sxapo_status=SXAPO_ACTIVE; } else if ((STbcompare(pmvalue, 0, SX_C2_MODE_OFF, 0, TRUE)!=0)) { /* ** Niether ON nor OFF, Invalid mode */ *err_code=E_SX1061_SXAP_BAD_MODE; break; } } else { /* ** No value, this is an error */ *err_code=E_SX1061_SXAP_BAD_MODE; break; } /* ** Get action on error */ if ((PMget("II.*.C2.ON_ERROR",&pmvalue) == OK)) { if (!STcasecmp(pmvalue, "STOPAUDIT" )) { Sxf_svcb->sxf_act_on_err=SXF_ERR_STOPAUDIT; } else if (!STcasecmp(pmvalue, "SHUTDOWN" )) { Sxf_svcb->sxf_act_on_err=SXF_ERR_SHUTDOWN; } else { /* ** Invalid value */ *err_code=E_SX1060_SXAP_BAD_ONERROR; break; } } else { /* ** No value, this is an error */ *err_code=E_SX1060_SXAP_BAD_ONERROR; break; } break; } /* handle errors */ if (*err_code != E_SX0000_OK) { _VOID_ ule_format(*err_code, NULL, ULE_LOG, NULL, NULL, 0L, NULL, &local_err, 0); *err_code = E_SX1020_SXAP_INIT_CNF; status = E_DB_ERROR; } return (status); }
/****************************************************************************** ** Name: CSoptions() - fetch a pile of options using PMget() ** ** Description: ** Calls PMget() for each option in the option table, converts the ** value appropriately, and distributes the value into the right ** spot in the CS_SYSTEM block. ** ** Note special cruddiness surrounding CSO_SERVER_CLASS: the CL ** fetches this only to set cs_isstar, used by CSinitiate() to ** calculate the file descriptor fluff factors: STAR uses more of 'em. ******************************************************************************/ STATUS CSoptions( CS_SYSTEM *cssb ) { i4 echo = 1; struct CSO_OPTIONS *csopt; i4 failures = 0; for( csopt = cso_opttab; csopt->cso_name; csopt++ ) { char *cs_svalue; i4 cs_value = 0; STATUS status = OK; /* * Get option's value using PMget() */ if( PMget( csopt->cso_name, &cs_svalue ) != OK ) continue; if( echo ) ERoptlog( csopt->cso_name, cs_svalue ); /* * Convert & check the option's value, according to argtype */ switch( csopt->cso_argtype ) { case 'g': /* String option */ break; case 'm': /* numeric option or the word "max" if( !STcompare( cs_svalue, "max" ) ) { cs_value = -1; break; } /* fall through */ case 'o': case 'n': /* set a numeric option */ if( CVal( cs_svalue, &cs_value ) != OK ) { status = E_CS0025_NUMERIC_ARG; } else if( csopt->cso_argtype == 'o' && cs_value < 0 ) { status = E_CS0026_POSITIVE_VALUE; } break; case 't': /* set a switch option: on = true */ if( STbcompare( cs_svalue, 0, "on", 0, TRUE ) ) continue; break; case 'z': /* clear a switch option */ if( !STbcompare( cs_svalue, 0, "on", 0, TRUE ) ) continue; break; } if( status ) { (*cssb->cs_elog)( status, (CL_ERR_DESC *)0, 1, STlength( csopt->cso_name ), csopt->cso_name ); failures++; break; } /* * Distribute option value, according to index */ switch( csopt->cso_index ) { case CSO_ECHO: /* echo: off */ echo = 0; break; case CSO_ACT_SESSION: cssb->cs_max_active = cs_value; break; case CSO_CON_SESSION: cssb->cs_max_sessions = cs_value; break; case CSO_MAXLDB_CON: // cssb->cs_max_ldb_connections = cs_value; break; case CSO_MAX_WS: # if defined( xCL_034_GETRLIMIT_EXISTS) && defined( RLIMIT_RSS ) { struct rlimit rlim; getrlimit( RLIMIT_RSS, &rlim ); rlim.rlim_cur = cs_value; if( cs_value < 0 || cs_value > rlim.rlim_max ) rlim.rlim_cur = rlim.rlim_max; setrlimit( RLIMIT_RSS, &rlim ); } #endif break; case CSO_PRIORITY: /* Process priority */ # ifdef xCL_033_SETPRIORITY_EXISTS // setpriority( PRIO_PROCESS, 0, cs_value ); # else // nice( cs_value ); # endif break; case CSO_QUANTUM: // cssb->cs_quantum = cs_value; break; case CSO_SESS_ACCTNG: cssb->cs_mask |= CS_ACCNTING_MASK; cssb->cs_mask |= CS_CPUSTAT_MASK; break; case CSO_CPUSTATS: cssb->cs_mask |= CS_CPUSTAT_MASK; break; case CSO_STK_SIZE: cssb->cs_stksize = cs_value; break; case CSO_SERVER_CLASS: // cssb->cs_isstar = !STcompare( cs_svalue, "STAR" ); /* cheesy */ break; case CSO_DEFINE: cssb->cs_define = TRUE; break; } } return (OK); }