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 ); }
int uld_struct_xlate(char *strname) { const INTXLATE *xlatePtr; /* Translation table pointer */ xlatePtr = &Uld_struct_xlatetab[0]; while (xlatePtr->string != NULL) { if (STcasecmp(strname, xlatePtr->string) == 0) return (xlatePtr->code); ++ xlatePtr; } return (0); } /* uld_struct_xlate */
bool cer_istest(void) { char *nambuf; if (test_state == NOTSET) { /* Check the II_MSG_TEST */ NMgtAt("II_MSG_TEST", &nambuf); if (nambuf && *nambuf && ( STcasecmp(nambuf, "y" ) == 0 || STcasecmp(nambuf, "yes" ) == 0 || STcasecmp(nambuf, "t" ) == 0 || STcasecmp(nambuf, "true" ) == 0 ) ) { /* Value is Set */ test_state = SETON; } else { test_state = SETOFF; } } return ((test_state == SETON) ? TRUE : FALSE); }
/* ** Name: check_user ** ** Description: ** Test the characters in the username as returned from ** the operating system. ** ** Inputs: ** None. ** ** Output: ** error_msg pointer to the area where an error message should be ** copied ** ** Returns: ** None. ** ** History: ** 14-Feb-2005 (fanra01) ** Created. */ static i4 check_user() { i4 result; char username[UNLEN + 1] = { 0 }; i4 nsize = MAX_COMPNAME; #if defined(UNIX) struct passwd *p_pswd, pwd; char pwuid_buf[BUFSIZ]; int size = BUFSIZ; #endif /* ** Get current user name */ nsize = UNLEN; #if defined(UNIX) MEfill ( sizeof(pwuid_buf), '\0', pwuid_buf ); if( ( p_pswd = iiCLgetpwuid(getuid(), &pwd, pwuid_buf, size) ) != NULL) { STcopy( p_pswd->pw_name, username ); #else /* UNIX */ if (GetUserName( username, &nsize )) { #endif /* UNIX */ /* ** Check if the username contains unsupported characters */ if (!CMvalidusername( username )) { result = II_INVALID_USER; return(result); } } else { result = II_GET_USER_FAIL; return(result); } result = II_SUCCESSFUL; return(result); } /* ** Name: check_os_arch - Verify OS and architecture ** ** Description: ** Function verifies the OS version and the operating architecture and ** determines whether the platform should support an installation of ** Ingres. ** ** The following checks are applied: ** a. Verify the minimum OS version ** b. Verfiy execution mode. ** c. Verify architecture. ** ** Inputs: ** None. ** ** Outputs: ** None. ** ** Returns: ** 0 Platform verified successfully ** non-zero Error verifying platform ** ** History: ** 14-Dec-2004 (fanra01) ** Created. ** */ # ifdef NT_GENERIC /* ** Name: OS_ARCH ** ** Description: ** Structure to describe Ingres architecture coupled with actual hardware ** architecture. ** ** inghw Ingres hardware code will run on the processor architecture. ** procarch Processor architecture. ** ** History: ** 15-Dec-2004 (fanra01) ** Created. */ typedef struct _os_arch { i4 inghw; i4 procarch; }OS_ARCH; static OS_ARCH platform[] = { { II_IA32, PROCESSOR_ARCHITECTURE_INTEL }, /* 32-bit Ingres on IA32 */ { II_IA32, PROCESSOR_ARCHITECTURE_AMD64 }, /* 32-bit Ingres on AMD64 */ { II_IA64, PROCESSOR_ARCHITECTURE_IA64 }, /* 64-bit Ingres on IA64 */ { II_AMD64, PROCESSOR_ARCHITECTURE_AMD64 }, /* 64-bit Ingres on AMD64 */ { 0x000000, 0 } }; static i4 check_os_arch( i4 architecture ) { typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS)(HANDLE hProcess,PBOOL Wow64Process); typedef VOID (WINAPI *LPFN_GETNATIVESYSTEMINFO)(LPSYSTEM_INFO lpSystemInfo); BOOL bIsWow64 = FALSE; BOOL bVersVerified = FALSE; LPFN_ISWOW64PROCESS fnIsWow64Process; LPFN_GETNATIVESYSTEMINFO fnGetNativeSystemInfo; DWORDLONG dwlConditionMask = 0; i4 result = 0; i4 i; SYSTEM_INFO sysinfo; OSVERSIONINFOEX osvi; MEfill( sizeof(SYSTEM_INFO), 0, &sysinfo ); MEfill( sizeof(OSVERSIONINFOEX), 0, &osvi ); /* ** Test the processing mode. bIsWow64 is TRUE if this is 32-bit code ** running in a 32-bit execution layer on a 64-bit processor. */ if ((fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress( GetModuleHandle("kernel32"), "IsWow64Process")) != NULL) { if((fnGetNativeSystemInfo = (LPFN_GETNATIVESYSTEMINFO)GetProcAddress( GetModuleHandle("kernel32"), "GetNativeSystemInfo")) == NULL) { result = GetLastError(); } if (result == 0) { if (!fnIsWow64Process(GetCurrentProcess(),&bIsWow64)) { result = GetLastError(); } } } if (result == 0) { /* ** Verify the minimum version requirement. ** This has been set at Windows NT 4 SP3. */ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); osvi.dwMajorVersion = 4; osvi.dwMinorVersion = 0; osvi.wServicePackMajor = 3; VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL ); VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL ); VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL ); bVersVerified = VerifyVersionInfo( &osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask); if (bVersVerified == FALSE) { result = GetLastError(); } else { /* ** Get the system information that includes the processor ** architecture. */ if ((bIsWow64 == TRUE) && (fnGetNativeSystemInfo != NULL)) { /* ** Running 32-bit execution layer on a 64-bit platform ** Use function that gets true architecture. */ fnGetNativeSystemInfo( &sysinfo ); } else { GetSystemInfo( &sysinfo ); } if (result == 0) { result = FAIL; for( i=0; platform[i].inghw != 0; i+=1 ) { if ((architecture == platform[i].inghw) && (sysinfo.wProcessorArchitecture == platform[i].procarch)) { /* ** Return true if and only if the Ingres hardware ** platform is specifically associated with the ** processor architecture. */ result = OK; break; } } } } } return(result); } # endif /* NT_GENERIC */ # if defined(UNIX) /* ** Name: check_os_arch - Verify OS and architecture on UNIX/LINUX ** ** Description: ** Function verifies the hardware architecture and OS system, ** determines whether the platform should support an installation of ** Ingres. ** ** ** Inputs: Ingres architecture ( defined as GV_HW in gv.h ) ** ** ** Returns: ** 0 Platform verified successfully ** non-zero Error verifying platform ** ** History: ** 15-Oct-2006 (hweho01) ** Added for Unix/Linux platforms. ** */ /* ** Name: OS_ARCH ** ** Description: ** Structure to describe Ingres architecture coupled with actual OS ** system name. ** ** inghw Ingres hardware code will run on the OS system. ** os_name system name. ** */ typedef struct _os_arch { i4 inghw; char os_name[20]; }OS_ARCH; static OS_ARCH platform[] = { { II_IA32, "LINUX" }, /* 32-bit Ingres on IA32 */ { II_IA32, "LINUX" }, /* 32-bit Ingres on AMD64 */ { II_IA64, "LINUX" }, /* 64-bit Ingres on IA64 */ { II_AMD64, "LINUX" }, /* 64-bit Ingres on AMD64 */ { II_SPARC, "SUNOS" }, /* 32/64 Ingres on Sun Solaris */ { II_PARISC, "HP-UX" }, /* 32/64 Ingres on HP UNIX */ { II_POWERPC, "AIX" }, /* 32/64 Ingres on IBM POWERPC */ { 0x000000, NULL } }; static i4 check_os_arch( i4 architecture ) { struct utsname sysinfo; i4 ret, i ; i4 result = 0; /* check the running OS info */ ret = uname( &sysinfo ); result = FAIL; for( i=0; platform[i].inghw != 0; i+=1 ) { if ((architecture == platform[i].inghw) && (STcasecmp( sysinfo.sysname, platform[i].os_name) == 0)) { result = OK; break; } } return(result); } # endif /* UNIX */ /* ** Name: check_platform - Verify software platform ** ** Description: ** Function determines the operating platform and verifies that the ** minimum requirements are fulfilled. ** ** Inputs: ** None. ** ** Outputs: ** None. ** ** Returns: ** 0 architecture verification succeeded ** non-zero architecture failed verification ** ** History: ** 13-Dec-2004 (fanra01) ** Created. */ static i4 check_platform( i4 architecture ) { i4 result = 0; ING_VERSION ingver; char* plat_override = NULL; NMgtAt(ERx("II_RELAX_PLATFORM"), &plat_override); if (plat_override && *plat_override) { return(result); } /* ** No architecture has been specified, use the internal compiled one. */ if (architecture == II_DEFARCH) { MEfill( sizeof(ING_VERSION), 0, &ingver ); /* ** Retrieve the hardware architecture used to build this version */ if ((result = GVver( GV_M_HW, &ingver )) == OK) { /* ** Reassign the architecture to the retrieved one. */ architecture = ingver.hardware; } } if (result == OK) { result = check_os_arch( architecture ); } return(result); }
/* ** 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); }
/* ** NOTE: in SQL grammar target_list of a subselect is processed BEFORE the ** from_list; consequently, data types of target list elements are not ** known when we build RESDOM nodes for the target list elements of form ** [<corr_name>.]<col_name>. In psl_p_tlist(), we revisit the prototype ** tree and fill in the newly available information (type, length, ** precision, etc.) ** ** When making changes to pst_adresdom(), please take time to understand ** the effect these changes may have on the processing of prototype trees. */ DB_STATUS pst_adresdom( char *attname, PST_QNODE *left, PST_QNODE *right, PSS_SESBLK *cb, PSQ_CB *psq_cb, PST_QNODE **newnode) { DB_STATUS status; DMT_ATT_ENTRY *coldesc; DMT_ATT_ENTRY column; PSS_RNGTAB *resrange; char colname[sizeof(DB_ATT_NAME) + 1]; /* null term. */ PST_RSDM_NODE resdom; i4 err_code; PSC_RESCOL *rescol; ADF_CB *adf_scb; i2 null_adjust = 0; i4 temp_collID; /* Convert column name to a null-terminated string. */ (VOID) MEcopy((PTR) attname, sizeof(DB_ATT_NAME), (PTR) colname); colname[sizeof(DB_ATT_NAME)] = '\0'; (VOID) STtrmwhite(colname); /* For these operations, the result domain comes from the result table */ if (psq_cb->psq_mode == PSQ_APPEND || psq_cb->psq_mode == PSQ_PROT) { /* Get the result range variable */ if (psq_cb->psq_qlang == DB_SQL) { resrange = &cb->pss_auxrng.pss_rsrng; } else { resrange = &cb->pss_usrrange.pss_rsrng; } /* "tid" result column not allowed with these operations */ if (!STcasecmp(((*cb->pss_dbxlate & CUI_ID_REG_U) ? "TID" : "tid"), colname )) { psf_error(2100L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 4, (i4) sizeof(cb->pss_lineno), &cb->pss_lineno, psf_trmwhite(sizeof(DB_TAB_NAME), (char *) &resrange->pss_tabname), &resrange->pss_tabname, psf_trmwhite(sizeof(DB_OWN_NAME), (char *) &resrange->pss_ownname), &resrange->pss_ownname, psf_trmwhite(sizeof(DB_ATT_NAME), attname), attname); return (E_DB_ERROR); } /* Get the column description */ coldesc = pst_coldesc(resrange, (DB_ATT_NAME *) attname); if (coldesc == (DMT_ATT_ENTRY *) NULL) { psf_error(2100L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 4, (i4) sizeof(cb->pss_lineno), &cb->pss_lineno, psf_trmwhite(sizeof(DB_TAB_NAME), (char *) &resrange->pss_tabname), &resrange->pss_tabname, psf_trmwhite(sizeof(DB_OWN_NAME), (char *) &resrange->pss_ownname), &resrange->pss_ownname, psf_trmwhite(sizeof(DB_ATT_NAME), attname), attname); return (E_DB_ERROR); } if (coldesc->att_flags & DMU_F_SYS_MAINTAINED) { psf_error(E_US1900_6400_UPD_LOGKEY, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 4, (i4) sizeof(cb->pss_lineno), &cb->pss_lineno, psf_trmwhite(sizeof(DB_TAB_NAME), (char *) &resrange->pss_tabname), &resrange->pss_tabname, psf_trmwhite(sizeof(DB_OWN_NAME), (char *) &resrange->pss_ownname), &resrange->pss_ownname, psf_trmwhite(sizeof(DB_ATT_NAME), attname), attname); return (E_DB_ERROR); } } else if (psq_cb->psq_mode == PSQ_REPLACE) { /* ** For the "replace" command, use the result range variable that's ** in the normal user range table, not the special slot that's ** reserved for the result table in the append command. */ /* Get the result range variable */ resrange = cb->pss_resrng; /* "tid" result column not allowed with these operations */ if (!STcasecmp(((*cb->pss_dbxlate & CUI_ID_REG_U) ? "TID" : "tid"), colname)) { psf_error(2100L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 4, (i4) sizeof(cb->pss_lineno), &cb->pss_lineno, psf_trmwhite(sizeof(DB_TAB_NAME), (char *) &resrange->pss_tabname), &resrange->pss_tabname, psf_trmwhite(sizeof(DB_OWN_NAME), (char *) &resrange->pss_ownname), &resrange->pss_ownname, psf_trmwhite(sizeof(DB_ATT_NAME), attname), attname); return (E_DB_ERROR); } /* Get the column description */ coldesc = pst_coldesc(resrange, (DB_ATT_NAME *) attname); if (coldesc == (DMT_ATT_ENTRY *) NULL) { psf_error(2100L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 4, (i4) sizeof(cb->pss_lineno), &cb->pss_lineno, psf_trmwhite(sizeof(DB_TAB_NAME), (char *) &resrange->pss_tabname), &resrange->pss_tabname, psf_trmwhite(sizeof(DB_OWN_NAME), (char *) &resrange->pss_ownname), &resrange->pss_ownname, psf_trmwhite(sizeof(DB_ATT_NAME), attname), attname); return (E_DB_ERROR); } if (coldesc->att_flags & DMU_F_SYS_MAINTAINED) { psf_error(E_US1900_6400_UPD_LOGKEY, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 4, (i4) sizeof(cb->pss_lineno), &cb->pss_lineno, psf_trmwhite(sizeof(DB_TAB_NAME), (char *) &resrange->pss_tabname), &resrange->pss_tabname, psf_trmwhite(sizeof(DB_OWN_NAME), (char *) &resrange->pss_ownname), &resrange->pss_ownname, psf_trmwhite(sizeof(DB_ATT_NAME), attname), attname); return (E_DB_ERROR); } } else if (psq_cb->psq_mode == PSQ_REPCURS) { /* ** For the "replace cursor" command, the info comes from the cursor ** control block. Cursor column list and update map should always ** specify same column set, so the second if statemnt (BTtest) could, ** perhaps, be removed. */ rescol = psq_ccol(cb->pss_crsr, (DB_ATT_NAME *) attname); if (rescol == (PSC_RESCOL *) NULL) { psf_error(2207L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 3, sizeof(cb->pss_lineno), &cb->pss_lineno, psf_trmwhite(DB_CURSOR_MAXNAME, cb->pss_crsr->psc_blkid.db_cur_name), cb->pss_crsr->psc_blkid.db_cur_name, psf_trmwhite(sizeof(DB_ATT_NAME), attname), attname); return (E_DB_ERROR); } /* Make sure the column was declared "for update" */ if (!BTtest((i4) rescol->psc_attid.db_att_id, (char *) &cb->pss_crsr->psc_updmap)) { psf_error(2207L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 3, sizeof(cb->pss_lineno), &cb->pss_lineno, psf_trmwhite(DB_CURSOR_MAXNAME, cb->pss_crsr->psc_blkid.db_cur_name), cb->pss_crsr->psc_blkid.db_cur_name, psf_trmwhite(sizeof(DB_ATT_NAME), attname), attname); return (E_DB_ERROR); } /* Set up column descriptor */ coldesc = &column; MEcopy((char *) attname, sizeof(DB_ATT_NAME), (char *) &coldesc->att_name); #ifdef NO /* ** Count columns. Give error if too many. One extra for tid. */ cb->pss_rsdmno++; if (cb->pss_rsdmno > (DB_MAX_COLS + 1)) { psf_error(2130L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 1, (i4) sizeof(cb->pss_lineno), &cb->pss_lineno); return (E_DB_ERROR); } coldesc->att_number = cb->pss_rsdmno; #endif coldesc->att_number = rescol->psc_attid.db_att_id; coldesc->att_type = rescol->psc_type; coldesc->att_width = rescol->psc_len; coldesc->att_prec = rescol->psc_prec; coldesc->att_collID = -1; coldesc->att_geomtype = -1; coldesc->att_srid = -1; coldesc->att_encflags = 0; coldesc->att_encwid = 0; } else { /* ** In all other cases, just take the datatype info ** from the right child. */ coldesc = &column; MEcopy((char *) attname, sizeof(DB_ATT_NAME), (char *) &coldesc->att_name); /* ** Count columns. Give error if too many. One extra for tid. */ cb->pss_rsdmno++; if (cb->pss_rsdmno > (DB_MAX_COLS + 1)) { psf_error(2130L, 0L, PSF_USERERR, &err_code, &psq_cb->psq_error, 1, (i4) sizeof(cb->pss_lineno), &cb->pss_lineno); return (E_DB_ERROR); } coldesc->att_number = cb->pss_rsdmno; status = pst_rsdm_dt_resolve(right, coldesc, cb, psq_cb); if (DB_FAILURE_MACRO(status)) return(status); } /* Copy attribute information into PST_RSDM_NODE */ resdom.pst_rsno = coldesc->att_number; /* The two fields below are initialized for a common case. ** They are context sensitive and in many cases may have to be ** modified by the caller of this routine. */ resdom.pst_ntargno = resdom.pst_rsno; resdom.pst_ttargtype = PST_USER; resdom.pst_dmuflags = 0; /* Don't bother with the conversion id for now */ /* Not for update until we know otherwise */ resdom.pst_rsupdt = FALSE; resdom.pst_rsflags = PST_RS_PRINT; MEcopy((char *) &coldesc->att_name, sizeof(DB_ATT_NAME), (char *) resdom.pst_rsname); temp_collID = coldesc->att_collID; /* If client can not handle i8 INTs downgrade to i4 */ adf_scb = (ADF_CB *) cb->pss_adfcb; if ( !(adf_scb->adf_proto_level & AD_I8_PROTO) && (abs(coldesc->att_type) == DB_INT_TYPE) ) { if(coldesc->att_type < 0) { null_adjust = 1; } if((coldesc->att_width - null_adjust) == sizeof(i8)) { coldesc->att_width -= sizeof(i4); } } /* Now allocate the node */ status = pst_node(cb, &cb->pss_ostream, left, right, PST_RESDOM, (char *) &resdom, sizeof(PST_RSDM_NODE), (DB_DT_ID) coldesc->att_type, (i2) coldesc->att_prec, (i4) coldesc->att_width, (DB_ANYTYPE *) NULL, newnode, &psq_cb->psq_error, (i4) 0); if (status != E_DB_OK) { return (status); } (*newnode)->pst_sym.pst_dataval.db_collID = temp_collID; /* Remember the last result domain produced */ cb->pss_tlist = *newnode; return (E_DB_OK); }
/* Name: adu_getconverter - Obtains the name of converter mapping file ** to use for unicode coercion. ** Description: ** ** To obtain the mapping file to be used for carrying out unicode-local ** character conversion. The following mechanism is followed: ** ** 1. Check symbol table for user defined converter setting ** II_UNICODE_CONVERTER. If set then return this setting ** 2. If the variable is not set then ** 2.a Get the platform character set ** 2.b Read the aliasmaptbl file. ** 2.c Search the alias file for platform charset. ** 3. If still not found then find the II_CHARSETxx value ** for ingres installation and search the alias file for ** this value. ** 4. If none of these attempts succeed then return default ** with a warning to the errorlog if this happens ** ** Input: ** converter - Place holder for the output string, ** It is assumed that the area is at least MAX_LOC ** chars in size. ** Output: ** converter - Pointer to string where the output ** converter name is stored. ** History: ** ** 22-jan-2004 (gupsh01) ** Added. ** 14-Jun-2004 (schka24) ** Safe charset name handling. */ STATUS adu_getconverter( char *converter) { STATUS stat; char *tptr; char *env = 0; char chset[CM_MAXATTRNAME+1]; char pcs[CM_MAXLOCALE+1]; /* platform character set */ char norm_pcs[CM_MAXLOCALE+1]; CL_ERR_DESC syserr; char *alias_buffer = NULL; char *bufptr = NULL; char *buf = NULL; ADU_ALIAS_MAPPING *aliasmapping; ADU_ALIAS_DATA *aliasdata; char *datasize; SIZE_TYPE filesize = 0; SIZE_TYPE sizemap = 0; SIZE_TYPE sizedata = 0; i4 bytes_read; char *abufptr; i4 i = 0; i4 index = 0; /* STEP 1 */ NMgtAt(ERx("II_UNICODE_CONVERTER"), &env); if (env && *env) { STlcopy(env, converter, MAX_LOC-1); return OK; } /* STEP 2 */ stat = CM_getcharset(pcs); if (CMopen_col("aliasmaptbl", &syserr, CM_UCHARMAPS_LOC) != OK) { /* return an ERROR if we are unable to open the file */ return FAIL; } /* initialize buf to help read from the aliasmaptbl file */ buf = MEreqmem(0, COL_BLOCK, TRUE, &stat); if (buf == NULL || stat != OK) { CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } /* First file buffer has size information. */ stat = CMread_col(buf, &syserr); if (stat != OK) { MEfree((char *)buf); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } tptr = buf; bytes_read = COL_BLOCK; /* filesize is the first entry of the map file */ filesize = *(SIZE_TYPE *) buf; tptr += sizeof(SIZE_TYPE); tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* allocate working space for the data */ alias_buffer = (char *)MEreqmem(0, filesize, TRUE, &stat); if (alias_buffer == NULL || stat != OK) { CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } abufptr = alias_buffer; MEcopy (buf, COL_BLOCK, abufptr); abufptr += COL_BLOCK; /* Read the file till it is read completely */ for ( ;bytes_read < filesize;) { stat = CMread_col(buf, &syserr); if (stat != OK) { MEfree((char *)buf); MEfree((char *)alias_buffer); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } bytes_read += COL_BLOCK; MEcopy (buf, COL_BLOCK, abufptr); abufptr += COL_BLOCK; } if (bytes_read < filesize) { /* we had to exit for some unknown reason */ MEfree((char *)buf); MEfree((char *)alias_buffer); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } tptr = alias_buffer; tptr += sizeof(SIZE_TYPE); tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* Read the size of the MappingArray nodes */ sizemap = *(SIZE_TYPE *) tptr; tptr += sizeof(SIZE_TYPE); tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* initialize buffer for ADU_ALIAS_MAPPING buffer */ aliasmapping = (ADU_ALIAS_MAPPING *) MEreqmem(0, sizemap, TRUE, &stat); if (aliasmapping == NULL) { MEfree((char *)buf); MEfree((char *)alias_buffer); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } /* Copy data for ADU_ALIAS_MAPPING array */ MEcopy(tptr, sizemap, aliasmapping); tptr += sizemap; tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* Get size for the aliasdata */ sizedata = *(SIZE_TYPE *) tptr; tptr += sizeof(SIZE_TYPE); tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* Initialize buffer for ADU_ALIAS_MAPPING buffer */ aliasdata = (ADU_ALIAS_DATA *) MEreqmem(0, sizedata, TRUE, &stat); if (aliasdata == NULL) { MEfree((char *)buf); MEfree((char *)alias_buffer); MEfree((char *)aliasmapping); CMclose_col(&syserr, CM_UCHARMAPS_LOC); return (FAIL); } /* Copy the ADU_ALIAS_DATA array */ MEcopy(tptr, sizedata, aliasdata); tptr += sizedata; tptr = ME_ALIGN_MACRO(tptr, sizeof(PTR)); /* Close the "aliasmaptbl" file */ CMclose_col(&syserr, CM_UCHARMAPS_LOC); /* Normalize pcs */ adu_csnormalize (pcs, STlength(pcs), norm_pcs); /* Retrieve the pcs value */ for (i=0; i < sizedata/sizeof(ADU_ALIAS_DATA); i++) { if ((STcompare (aliasdata[i].aliasNameNorm, norm_pcs)) == 0) { index = aliasdata[i].aliasMapId; /* found */ STcopy (aliasmapping[index].mapping_id, converter); /* cleanup */ MEfree((char *)buf); MEfree((char *)alias_buffer); MEfree((char *)aliasmapping); MEfree((char *)aliasdata); return (OK); } } /* STEP 3 */ /* Obtain Ingres characterset */ STcopy("default", converter); CMget_charset_name(&chset[0]); if (STcasecmp(chset, "UTF8") != 0) { /* search maptable for env */ for (i=0; i < sizedata/sizeof(ADU_ALIAS_DATA); i++) { if ((STcompare (aliasdata[i].aliasNameNorm, norm_pcs)) == 0) { index = aliasdata[i].aliasMapId; /* found */ STcopy (aliasmapping[index].mapping_id, converter); break; } } } /* cleanup */ MEfree((char *)buf); MEfree((char *)alias_buffer); MEfree((char *)aliasmapping); MEfree((char *)aliasdata); /* FIXME warning or error if still "default" ? */ return (OK); }
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 ); }
STATUS gcn_recrypt( bool clustered, u_i1 *local_mask, char *gcn_val, bool *v1DecryptErr, bool *writeOutput) { i2 pc; char *pv[ 3 ]; STATUS status = OK; char *p; char pwd[GC_L_PASSWORD]; i2 j; bool printable; *v1DecryptErr = FALSE; pc = gcu_words( gcn_val, NULL, pv, ',', 3 ); if (pc < 2 ) pv[1] = ""; if (pc < 3 ) pv[2] = ""; if (!STcasecmp(pv[2],"V0") || (pc < 3)) status = gcn_decrypt( pv[0], pv[1], pwd ); else status = gcn_decode( pv[0],(u_i1*)local_mask, pv[1], pwd ); if (status != OK) { if (!STcasecmp(pv[2],"V1")) *v1DecryptErr = TRUE; goto end_routine; } if (!STlength(pwd)) { if (!STcasecmp(pv[2],"V1")) *v1DecryptErr = TRUE; status = FAIL; goto end_routine; } p = &pwd[0]; printable = TRUE; for (j = 0; j < STlength(pwd); j++) { if (!CMprint(p)) { printable = FALSE; break; } CMnext(p); } if (!printable) { if (!STcasecmp(pv[2],"V1")) *v1DecryptErr = TRUE; status = FAIL; goto end_routine; } if (clustered) { if (!STncasecmp("V1", pv[2], STlength(pv[2]))) *writeOutput = TRUE; status = gcu_encode( pv[0], pwd, pv[1] ); STpolycat( 5, pv[0], ",", pv[1], ",", "V0", gcn_val ); } else { status = gcn_encode( pv[0],(u_i1*)local_mask, pwd, pv[1] ); STpolycat( 5, pv[0], ",", pv[1], ",", "V1", gcn_val ); } end_routine: return status; }
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 */