DB_STATUS qel_c5_ldbid_long( QEF_RCB *v_qer_p, QEC_LINK *v_lnk_p ) { DB_STATUS status; QES_DDB_SES *dds_p = & v_qer_p->qef_cb->qef_c2_ddb_ses; DD_LDB_DESC *cdb_p = & dds_p->qes_d4_ddb_p-> dd_d3_cdb_info.dd_i1_ldb_desc, *ldb_p = v_lnk_p->qec_19_ldb_p; QEQ_1CAN_QRY *sel_p = v_lnk_p->qec_6_select_p; QEC_D5_LONG_LDBNAMES *long_p = v_lnk_p->qec_8_longnames_p; /* 1. set up for accessing IIDD_DDB_LDB_LONGNAMES */ sel_p->qeq_c3_ptr_u.d5_long_ldbnames_p = long_p; sel_p->qeq_c4_ldb_p = cdb_p; sel_p->qeq_c5_eod_b = FALSE; sel_p->qeq_c6_col_cnt = 0; qed_u0_trimtail( ldb_p->dd_l3_ldb_name, (u_i4) DD_256_MAXDBNAME, long_p->d5_1_ldb_name); /* 3. retrieve the LDB's 32-char alias if it exists */ sel_p->qeq_c1_can_id = SEL_014_DD_DDB_LONG_LDBNAMES; status = qel_s4_prepare(v_qer_p, v_lnk_p); if (status) return(status); if (! sel_p->qeq_c5_eod_b) { /* no data */ status = qel_s3_flush(v_qer_p, v_lnk_p); if (status) return(status); /* generate alias */ STcopy(IIQE_30_alias_prefix, v_lnk_p->qec_5_ldb_alias); /* prefix */ CVla(v_lnk_p->qec_2_tableinfo_p->d9_1_obj_id.db_tab_base, &v_lnk_p->qec_5_ldb_alias[QEK_5_SIZE_OF_PREFIX]); return(E_DB_OK); } /* 4. send SELECT query to retrieve ldb id if it exists */ status = qel_c4_ldbid_short(TRUE, v_qer_p, v_lnk_p); /* TRUE for using alias */ return(status); }
static void formatXID( IIAPI_XA_DIS_TRAN_ID *xid, char *str ) { u_i4 count, val; u_i1 *data; CVlx( xid->xa_tranID.xt_formatID, str ); str += STlength( str ); *(str++) = ':'; CVla( xid->xa_tranID.xt_gtridLength, str ); str += STlength( str ); *(str++) = ':'; CVla( xid->xa_tranID.xt_bqualLength, str ); str += STlength( str ); data = (u_i1 *)xid->xa_tranID.xt_data; count = (xid->xa_tranID.xt_gtridLength + xid->xa_tranID.xt_bqualLength + sizeof( i4 ) - 1) / sizeof( i4 ); while( count-- ) { val = (*data << 24) | (*(data+1) << 16) | (*(data+2) << 8) | *(data+3); data+= 4; *(str++) = ':'; CVlx( val, str ); str += STlength( str ); } STcat( str, ERx( ":XA" ) ); str += STlength( str ); *(str++) = ':'; CVna( xid->xa_branchSeqnum, str ); str += STlength( str ); *(str++) = ':'; CVna( xid->xa_branchFlag, str ); str += STlength( str ); STcat( str, ERx( ":EX" ) ); return; }
static STATUS my_dynamic_index(i4 msg, PTR cdata, i4 linstance, char *instance, PTR *instdata ) { STATUS stat = OK; i4 ival; char buf[ 20 ]; switch( msg ) { case MO_GET: *instdata = (PTR)instance; break; case MO_GETNEXT: if( *instance == EOS ) ival = 0; stat = CVal( instance, &ival ); /* value is the instance */ if( stat != OK ) break; if( ival > 9 ) /* validate this instance */ stat = MO_NO_INSTANCE; else if( ++ival > 9 ) /* validate next */ stat = MO_NO_NEXT; if( stat != OK ) break; CVla( ival, buf ); /* assumes caller doesn't blast instance before passing it to a get/set method. Otherwise hard to handle, because we don't want to allocate memory here to be freed in the get or set routine. */ *instdata = (PTR)instance; STncpy( instance, buf, linstance ); instance [ linstance ] = EOS; if( STlength( buf ) != STlen ( instance )) stat = MO_INSTANCE_TRUNCATED; break; default: stat = MO_BAD_MSG; } return( stat ); }
VOID qee_d1_qid( QEE_DSH *v_dsh_p) { QEE_DDB_CB *qee_p = v_dsh_p->dsh_ddb_cb; DB_CURSOR_ID *csr_p; SYSTIME tm_now; char hi_ascii[QEK_015_LEN], lo_ascii[QEK_015_LEN], pid_ascii[QEK_015_LEN], temp[QEK_050_LEN + DB_CURSOR_MAXNAME]; PID pid; /* an i4 */ PCpid(& pid); /* get process (server) id */ CVla(pid, pid_ascii); /* convert to ascii */ TMnow(& tm_now); csr_p = & qee_p->qee_d4_given_qid; csr_p->db_cursor_id[0] = tm_now.TM_secs; csr_p->db_cursor_id[1] = tm_now.TM_msecs; CVla(tm_now.TM_secs, hi_ascii); CVla(tm_now.TM_msecs, lo_ascii); STpolycat((i4) 4, /* 4 constituent pieces */ "dd", lo_ascii, hi_ascii, pid_ascii, temp); MEmove(STlength(temp), temp, ' ', DB_CURSOR_MAXNAME, csr_p->db_cur_name); csr_p = & qee_p->qee_d5_local_qid; csr_p->db_cursor_id[0] = 0; csr_p->db_cursor_id[1] = 0; MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name); return; }
static STATUS myintget( i4 offset, i4 objsize, PTR object, i4 luserbuf, char *userbuf ) { STATUS stat = OK; char buf[ 20 ]; CVla( private_num, buf ); STncpy( userbuf, buf, luserbuf ) ; userbuf[ luserbuf ] = EOS; if( STlength( buf ) != STlength( userbuf ) ) stat = MO_VALUE_TRUNCATED; return( stat ); }
/* ** Name: PCexec_suid - Execute a command as the ingres user. ** ** Description: ** This procedure works with the Ingres service to run the given ** command as the ingres user. It mimicks the "setuid" bit in UNIX. ** ** Inputs: ** cmdbuf - command to execute as the ingres user ** ** Outputs: ** none ** ** Returns: ** OK ** FAIL ** ** Side Effects: ** none ** ** History: ** 08-jan-1998 (somsa01) ** Created. ** 19-feb-1998 (somsa01) ** We need to pass to the service the current working directory ** as well. (Bug #89006) ** 25-feb-1998 (somsa01) ** We now have an input file for the process' stdin which ** runs through the OpenIngres service. ** 19-jun-1998 (somsa01) ** Use SYSTEM_PRODUCT_NAME for the name of the service. ** 10-jul-1998 (kitch01) ** Bug 91362. If user is 'system' run through OpenIngres service ** despite having access to server shared memory 'system' does not ** have required privilege to access semaphores/mutexes. ** 11-jun-1999 (somsa01) ** If the command is a startup command, then it is always run through ** the Ingres service. ** 03-nov-1999 (somsa01) ** A failure from ControlService() should be treated as a severe ** error which should not let us continue. ** 22-jan-2000 (somsa01) ** Return the exit code of the spawned process. Also, if the ** files exist, truncate them. The service name is now keyed off ** of II_INSTALLATION. ** 05-jun-2000 (somsa01) ** The Ingres installation may be started as the SYSTEM account, ** in which the 'ingres' user will not automatically have access ** to the shared memory segments. Therefore, even if the real ** user is 'ingres', check to see if he has access. ** 24-oct-2000 (somsa01) ** Removed the check on shared memory access. Access to the shared ** memory segment does not necessarily mean that the user running ** the process does not need to run the specified process as the ** Ingres owner. Also, generalized the check of the user with ** IDname_service(). ** 18-dec-2000 (somsa01) ** Modified the cases to run the command "as is" without the Ingres ** service. ** 20-mar-2002 (somsa01) ** If all is well, return the exit code of the child process that ** was executed. ** 29-mar-2002 (somsa01) ** Properly return the child process exit code. ** 11-apr-2003 (somsa01) ** While waiting for "pending" to not be set, give some CPU back ** to the OS. ** 29-Jul-2005 (drivi01) ** Allow user to run the command if he/she owns a shared ** segment and ingres is not running as a service. ** 06-Dec-2006 (drivi01) ** Adding support for Vista, Vista requires "Global\" prefix for ** shared objects as well. Replacing calls to GVosvers with ** GVshobj which returns the prefix to shared objects. ** Added PCadjust_SeDebugPrivilege to allow quering of ** System processes. ** 25-Jul-2007 (drivi01) ** On Vista, PCexec_suid is unable to use SE_DEBUG Privilege ** to query process status and retireve its exit code. ** The routine for monitoring a process and retrieving ** its exit code has been moved to Ingres Service. ** 05-Nov-2009 (wanfr01) b122847 ** Don't do a PCsleep unless you are waiting for more input */ STATUS PCexec_suid(char *cmdbuf) { EX_CONTEXT context; SERVICE_STATUS ssServiceStatus; LPSERVICE_STATUS lpssServiceStatus = &ssServiceStatus; struct SETUID setuid; DWORD ProcID; HANDLE SaveStdout; SECURITY_ATTRIBUTES sa; CHAR szRealUserID[25] = ""; CHAR *pszRealUserID = szRealUserID; CHAR szServiceUserID[25] = ""; CHAR *pszServiceUserID = szServiceUserID; DWORD BytesWritten, BytesRead = 0; CHAR *inst_id; CHAR SetuidShmName[64]; CHAR *temp_loc; CHAR InBuf[256], OutBuf[256]; static CHAR SetuidPipeName[32]; CL_ERR_DESC err_code; CHAR ServiceName[255]; DWORD ExitCode = 0; CHAR tchII_INSTALLATION[3]; BOOL SetuidDbCmd = FALSE, ServiceCommand = FALSE; int i, cmdlen; char *ObjectPrefix; u_i4 drType; SC_HANDLE schSCManager, OpIngSvcHandle; BOOL bServiceStarted = FALSE; if (EXdeclare(ex_handler, &context) != OK) { EXdelete(); PCexit(FAIL); } NMgtAt("II_INSTALLATION", &inst_id); STcopy(inst_id, tchII_INSTALLATION); /* ** See if this is a command that MUST be run through the Ingres ** service. */ cmdlen = (i4)STlength(cmdbuf); for (i = 0; ServiceCommands[i] ; i++) { if (STbcompare( cmdbuf, cmdlen, ServiceCommands[i], (i4)STlength(ServiceCommands[i]), FALSE ) == 0) { ServiceCommand = TRUE; break; } } /* ** If the user is the same as the user who started the Ingres ** service, just spawn the command. */ if (!ServiceCommand) { IDname(&pszRealUserID); if (!IDname_service(&pszServiceUserID) && STcompare(pszServiceUserID, pszRealUserID) == 0 && PCisAdmin()) { /* ** Attempt to just execute the command. */ return( PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT, (LOCATION *) NULL, &err_code) ); } else { /* ** If current user is not the same as service user and ingres is not ** running as a service, check if shared memory segment is owned ** by current user, if user has access to shared segment allow him ** to run the command. */ PTR shmem; SIZE_TYPE allocated_pages=0; STATUS status; if((status = MEget_pages(ME_MSHARED_MASK, 1, "lglkdata.mem", &shmem, &allocated_pages, &err_code)) == OK) { STprintf(ServiceName, "%s_Database_%s", SYSTEM_SERVICE_NAME, tchII_INSTALLATION); if ((schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) != NULL) { if ((OpIngSvcHandle = OpenService(schSCManager, ServiceName, SERVICE_QUERY_STATUS)) != NULL) { if (QueryServiceStatus(OpIngSvcHandle,lpssServiceStatus)) { if (ssServiceStatus.dwCurrentState != SERVICE_STOPPED) bServiceStarted = TRUE; } } } if (!bServiceStarted) return(PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT, (LOCATION *) NULL, &err_code) ); } } /* ** See if this command is an Ingres command which needs to interact ** with at least one database. */ for (i = 0; validSetuidDbCmds[i] ; i++) { if (STbcompare( cmdbuf, cmdlen, validSetuidDbCmds[i], (i4)STlength(validSetuidDbCmds[i]), FALSE ) == 0) { SetuidDbCmd = TRUE; break; } } /* ** If the user has access to the Ingres shared memory segment, ** just spawn the command provided that it is not in the ** validSetuidDbCmds list. */ if (!SetuidDbCmd) { PTR shmem; SIZE_TYPE allocated_pages=0; STATUS status; if (((status = MEget_pages(ME_MSHARED_MASK, 1, "lglkdata.mem", &shmem, &allocated_pages, &err_code)) == OK) || (status == ME_NO_SUCH_SEGMENT)) { if (status != ME_NO_SUCH_SEGMENT) MEfree_pages(shmem, allocated_pages, &err_code); return( PCcmdline( (LOCATION *) NULL, cmdbuf, PC_WAIT, (LOCATION *) NULL, &err_code) ); } } } /* ** We must run the command through the Ingres service. */ if ( STstrindex(cmdbuf, "-silent", 0, FALSE ) ) SilentMode = TRUE; iimksec(&sa); GVshobj(&ObjectPrefix); STprintf(SetuidShmName, "%s%sSetuidShm", ObjectPrefix, tchII_INSTALLATION); if ( (SetuidShmHandle = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, SetuidShmName)) == NULL ) { error_exit(GetLastError()); return(FAIL); } if ( (SetuidShmPtr = MapViewOfFile(SetuidShmHandle, FILE_MAP_WRITE | FILE_MAP_READ, 0, 0, sizeof(struct SETUID_SHM))) == NULL ) { error_exit(GetLastError()); return(FAIL); } /* Set up the information to send to the service. */ STcopy(cmdbuf, setuid.cmdline); GetCurrentDirectory(sizeof(setuid.WorkingDirectory), setuid.WorkingDirectory); NMgtAt("II_TEMPORARY", &temp_loc); drType = GetDriveType(NULL); if (drType == DRIVE_REMOTE) { STcopy(temp_loc, setuid.WorkingDirectory); } SaveStdout = GetStdHandle(STD_OUTPUT_HANDLE); CVla(GetCurrentProcessId(), setuid.ClientProcID); STprintf(SetuidPipeName, "\\\\.\\PIPE\\INGRES\\%s\\SETUID", inst_id); /* Set up the stdout file for the command. */ STprintf(OutfileName, "%s\\%sstdout.tmp", temp_loc, setuid.ClientProcID); if ( (OutFile = CreateFile(OutfileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) { error_exit(GetLastError()); return(FAIL); } /* Set up the stdin file for the command. */ STprintf(InfileName, "%s\\%sstdin.tmp", temp_loc, setuid.ClientProcID); if ( (InFile = CreateFile(InfileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH, NULL)) == INVALID_HANDLE_VALUE ) { error_exit(GetLastError()); return(FAIL); } /* Wait until the service is ready to process our request. */ while (SetuidShmPtr->pending == TRUE) PCsleep(100); SetuidShmPtr->pending = TRUE; /* Trigger the "setuid" event of the service. */ if ( (schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT)) == NULL) { error_exit(GetLastError()); return(FAIL); } STprintf(ServiceName, "%s_Database_%s", SYSTEM_SERVICE_NAME, tchII_INSTALLATION ); OpIngSvcHandle = OpenService(schSCManager, ServiceName, SERVICE_USER_DEFINED_CONTROL); if (OpIngSvcHandle == NULL) { STprintf(ServiceName, "%s_DBATools_%s", SYSTEM_SERVICE_NAME, tchII_INSTALLATION ); OpIngSvcHandle = OpenService(schSCManager, ServiceName, SERVICE_USER_DEFINED_CONTROL); } if ( OpIngSvcHandle == NULL) { error_exit(GetLastError()); return(FAIL); } if (!ControlService(OpIngSvcHandle, RUN_COMMAND_AS_INGRES, lpssServiceStatus)) { error_exit(GetLastError()); CloseServiceHandle(schSCManager); return(FAIL); } WaitNamedPipe(SetuidPipeName, NMPWAIT_WAIT_FOREVER); /* Send the information to the service. */ if ( (Setuid_Handle = CreateFile(SetuidPipeName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ) { error_exit(GetLastError()); return(FAIL); } if (!WriteFile(Setuid_Handle, &setuid, sizeof(struct SETUID), &BytesWritten, NULL)) { error_exit(GetLastError()); return(FAIL); } /* ** Retrieve information back from the service, and then ** disconnect from the pipe. */ if (!ReadFile(Setuid_Handle, &setuid, sizeof(struct SETUID), &BytesRead, NULL)) { error_exit(GetLastError()); return(FAIL); } ProcID = setuid.CreatedProcID; SetuidShmPtr->pending = FALSE; UnmapViewOfFile(SetuidShmPtr); SetuidShmPtr = NULL; CloseHandle(SetuidShmHandle); if ( (ProcID != -1) && (ProcID != -2) ) { /* ** Wait for the "spawned" process to exit, reading its output ** from the stdout file. */ for (;;) { if ( ((!ReadFile(OutFile, OutBuf, sizeof(OutBuf), &BytesRead, NULL) || (BytesRead == 0)) && setuid.ExitCode != STILL_ACTIVE )) break; if ( BytesRead && (!WriteFile(SaveStdout, OutBuf, BytesRead, &BytesWritten, NULL)) && setuid.ExitCode != STILL_ACTIVE) break; else if (BytesRead < sizeof(OutBuf)) PCsleep(200); /* ** Currently, the only DBA program which can require ** user input is verifydb. Therefore, when it spits out ** the appropriate messages asking for user input, get ** it from the end user and pass it along to the spawned ** process. */ if ( (STrstrindex(OutBuf, "S_DU04FF_CONTINUE_PROMPT", 0, FALSE) != NULL) || (STrstrindex(OutBuf, "S_DU0300_PROMPT", 0, FALSE) != NULL) ) { SIflush(stdout); MEfill(sizeof(OutBuf), ' ', &OutBuf); MEfill(sizeof(InBuf), ' ', &InBuf); SIgetrec(InBuf, 255, 0); WriteFile(InFile, InBuf, sizeof(OutBuf), &BytesWritten, NULL); } } ExitCode = setuid.ExitCode; CloseHandle(Setuid_Handle); CloseHandle(InFile); DeleteFile(InfileName); CloseHandle(OutFile); DeleteFile(OutfileName); CloseServiceHandle(OpIngSvcHandle); CloseServiceHandle(schSCManager); return(ExitCode); } else { error_exit(GetLastError()); return(FAIL); } }
DB_STATUS qee_d2_tmp( QEF_RCB *qef_rcb, QEE_DSH *dsh, ULM_RCB *ulm) { DB_STATUS status = E_DB_OK; QEF_QP_CB *qp_p = dsh->dsh_qp_ptr; QEQ_DDQ_CB *ddq_p = & qp_p->qp_ddq_cb; QEE_DDB_CB *qee_p = dsh->dsh_ddb_cb; DB_CURSOR_ID *csr_p; if (ddq_p->qeq_d3_elt_cnt > 0) { SYSTIME tm_now, tm_last; char hi_ascii[QEK_015_LEN], lo_ascii[QEK_015_LEN], /* pid_ascii[QEK_015_LEN], */ temp[QEK_050_LEN+DB_MAXNAME];/* must be > DB_MAXNAME */ DD_TAB_NAME *name_p; i4 *long_p; /* PID pid; ** an i4 ** */ i4 m, n; char *p, *q; u_i2 hi_len, /* lo_len, */ tmp_len; #define QEE_10SQL_NAME_LEN 10 /* allocate space for array of temporary-table names and ** generate their names */ /* 1. allocate array for DD_TAB_NAMEs */ ulm->ulm_psize = ddq_p->qeq_d3_elt_cnt * sizeof(DD_TAB_NAME); if (status = qec_malloc(ulm)) { qef_rcb->error.err_code = ulm->ulm_error.err_code; qed_u10_trap(); return(status); } qee_p->qee_d1_tmp_p = (DD_TAB_NAME *) ulm->ulm_pptr; /* ptr to array of DD_TAB_NAMEs */ /* 2. allocate array for i4 status */ ulm->ulm_psize = ddq_p->qeq_d3_elt_cnt * sizeof(i4); if (status = qec_malloc(ulm)) { qef_rcb->error.err_code = ulm->ulm_error.err_code; qed_u10_trap(); return(status); } qee_p->qee_d2_sts_p = (i4 *) ulm->ulm_pptr; /* ptr to array of i4s */ /* initialize both allocated arrays */ name_p = qee_p->qee_d1_tmp_p; long_p = qee_p->qee_d2_sts_p; tm_last.TM_secs = 0; tm_last.TM_msecs = 0; /* PCpid(& pid); ** get process (server) id ** CVla(pid, pid_ascii); ** convert to ascii ** */ for (n = 0; n < ddq_p->qeq_d3_elt_cnt; n++) { /* 3. generate temporary table name */ TMnow(& tm_now); if (tm_now.TM_secs == tm_last.TM_secs) { if (tm_now.TM_msecs <= tm_last.TM_msecs) tm_now.TM_msecs = tm_last.TM_msecs + 1; } CVla(tm_now.TM_secs, hi_ascii); CVla(tm_now.TM_msecs, lo_ascii); hi_len = STlength(hi_ascii); /* transpose the hi_ascii string to get lower digits */ p = hi_ascii; q = hi_ascii + hi_len - 1; /* backup past EOS */ for (m = 0; m < (i4) hi_len - 1; m++) /* do length - 1 characters */ { *p = *q; p++; q--; } STpolycat((i4) 3, /* 3 constituent pieces */ "z", lo_ascii, hi_ascii, temp); tmp_len = STlength(temp); /* use at most 10 characters */ if (tmp_len > QEE_10SQL_NAME_LEN) tmp_len = QEE_10SQL_NAME_LEN; MEmove(tmp_len, temp, ' ', sizeof(DD_TAB_NAME), (char *)name_p); STRUCT_ASSIGN_MACRO(tm_now, tm_last); /* save for comparison */ name_p++; /* pt to next slot */ /* 4. initialize status word for this table */ *long_p = QEE_00M_NIL; long_p++; /* pt to next status word */ } /* for */ } else { qee_p->qee_d1_tmp_p = (DD_TAB_NAME *) NULL; qee_p->qee_d2_sts_p = (i4 *) NULL; } /* 5. initialize */ qee_p->qee_d3_status = QEE_00Q_NIL; if (! (qp_p->qp_status & QEQP_RPT)) { /* initialize if not repeat query */ csr_p = & qee_p->qee_d4_given_qid; csr_p->db_cursor_id[0] = 0; csr_p->db_cursor_id[1] = 0; MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name); } csr_p = & qee_p->qee_d5_local_qid; csr_p->db_cursor_id[0] = 0; csr_p->db_cursor_id[1] = 0; MEfill(DB_CURSOR_MAXNAME, ' ', (PTR) csr_p->db_cur_name); return(status); }
DB_STATUS adu_copascii( ADF_CB *adf_scb, DB_DATA_VALUE *dv1, DB_DATA_VALUE *rdv) { register char *p; char temp[ADI_OUTMXFIELD]; i4 leftfill; i4 plen; i4 str_len; i2 out_width; p = temp; switch(dv1->db_datatype) { case DB_INT_TYPE: if (dv1->db_length == 8) { CVla8(*(i8 *) dv1->db_data, p); } else if (dv1->db_length == 4) { CVla(*(i4 *) dv1->db_data, p); } else if (dv1->db_length == 2) { CVla((i4) *(i2 *) dv1->db_data, p); } else { CVla(I1_CHECK_MACRO(*(i1 *) dv1->db_data), p); } break; case DB_DEC_TYPE: { i4 pr = DB_P_DECODE_MACRO(dv1->db_prec); i4 sc = DB_S_DECODE_MACRO(dv1->db_prec); i4 available_width = rdv->db_length; char decimal = (adf_scb->adf_decimal.db_decspec ? (char) adf_scb->adf_decimal.db_decimal : '.' ); if ( rdv->db_datatype == DB_VCH_TYPE || rdv->db_datatype == DB_TXT_TYPE || rdv->db_datatype == DB_LTXT_TYPE ) available_width -= DB_CNTSIZE; /* now convert to ascii: use formula from lenspec for length, get ** scale # of digits after decimal point, use left-justify */ if (CVpka((PTR)dv1->db_data, pr, sc, decimal, AD_PS_TO_PRN_MACRO(pr, sc), sc, CV_PKLEFTJUST, p, &str_len) == CV_OVERFLOW) { /* this should never happen */ return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0)); } if (str_len > available_width) return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0)); } break; case DB_FLT_TYPE: { char decimal = (adf_scb->adf_decimal.db_decspec ? (char) adf_scb->adf_decimal.db_decimal : '.'); i4 available_width = rdv->db_length; if ( rdv->db_datatype == DB_VCH_TYPE || rdv->db_datatype == DB_TXT_TYPE || rdv->db_datatype == DB_LTXT_TYPE ) available_width -= DB_CNTSIZE; if (dv1->db_length == 4) { f8 f8tmp = (f8) *(f4 *) dv1->db_data; /* BUG : b119968 ** ** CVfa is a utility routine for both f8 and f4 floats. ** In the f4 case, the value is converted to f8 prior ** to call (as here). ** ** This works well except for the boundary case, where ** the f4 is FLT_MAX. In this case, an effective ** rounding up of the f8 that occurs as we convert to ** a string (eventually through fcvt) "overflows" the ** original f4 value. ** ** We bump down the last sig bit of the f4, and then ** we have no problems. */ if ( f8tmp == FLT_MAX ) { f8tmp = FLT_MAX_ROUND; } else if ( f8tmp == -FLT_MAX ) { f8tmp = -FLT_MAX_ROUND; } CVfa(f8tmp, adf_scb->adf_outarg.ad_f4width, adf_scb->adf_outarg.ad_f4prec, adf_scb->adf_outarg.ad_f4style, decimal, p, &out_width); if (out_width > available_width) return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0)); } else { CVfa(*(f8 *)dv1->db_data, adf_scb->adf_outarg.ad_f8width, adf_scb->adf_outarg.ad_f8prec, adf_scb->adf_outarg.ad_f8style, decimal, p, &out_width); if (out_width > available_width) return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0)); } } break; default: return(adu_error(adf_scb, E_AD5002_BAD_NUMBER_TYPE, 0)); } while (*p == ' ') p++; /* ** TEXT, VARCHAR, and LONGTEXT are variable length copies, ** so no need to pad on the left. */ if ( rdv->db_datatype == DB_TXT_TYPE || rdv->db_datatype == DB_VCH_TYPE || rdv->db_datatype == DB_LTXT_TYPE ) { return(adu_movestring(adf_scb, (u_char *) p, (i4) STlength(p), dv1->db_datatype, rdv)); } /* ** At this point the result type can be C or CHAR */ plen = min(STlength(p), rdv->db_length); leftfill = rdv->db_length - plen; MEfill(leftfill, ' ', rdv->db_data); MEcopy((PTR)p, plen, (PTR)((char *)rdv->db_data + leftfill)); return(E_DB_OK); }
DB_STATUS adu_ascii( ADF_CB *adf_scb, register DB_DATA_VALUE *dv1, DB_DATA_VALUE *rdv) { DB_STATUS db_stat = E_DB_OK; register char *p; char temp[ADI_OUTMXFIELD]; /* could probably be smaller */ u_char *str_addr; i4 str_len; i2 reswidth; bool char_text = FALSE; i8 i8_tmp = 0; p = temp; switch(dv1->db_datatype) { case DB_INT_TYPE: if (dv1->db_length == 8) { CVla8(*(i8 *) dv1->db_data, p); } else if (dv1->db_length == 4) { CVla(*(i4 *) dv1->db_data, p); } else if (dv1->db_length == 2) { CVla((i4) (*(i2 *) dv1->db_data), p); } else { CVla(I1_CHECK_MACRO(*(i1 *) dv1->db_data), p); } break; case DB_BOO_TYPE: if (((DB_ANYTYPE *)dv1->db_data)->db_booltype == DB_FALSE) STcopy("FALSE", p); else STcopy("TRUE", p); break; case DB_VCH_TYPE: case DB_CHA_TYPE: case DB_CHR_TYPE: case DB_TXT_TYPE: case DB_LTXT_TYPE: case DB_BYTE_TYPE: case DB_VBYTE_TYPE: if ((db_stat = adu_3straddr(adf_scb, dv1, (char **) &str_addr))) return(db_stat); if ((db_stat = adu_size(adf_scb, dv1, &str_len))) return(db_stat); if ((db_stat = adu_movestring(adf_scb, str_addr, str_len, dv1->db_datatype, rdv))) return(db_stat); char_text = TRUE; break; case DB_DEC_TYPE: { i4 pr = DB_P_DECODE_MACRO(dv1->db_prec); i4 sc = DB_S_DECODE_MACRO(dv1->db_prec); char decimal = (adf_scb->adf_decimal.db_decspec ? (char) adf_scb->adf_decimal.db_decimal : '.' ); /* now convert to ascii: use formula from lenspec for length, get ** scale # of digits after decimal point, use left-justify option */ if (CVpka((PTR)dv1->db_data, pr, sc, decimal, AD_PS_TO_PRN_MACRO(pr, sc), sc, CV_PKLEFTJUST, p, &str_len) == CV_OVERFLOW) { /* this should never happen */ return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0)); } } break; case DB_FLT_TYPE: { char decimal = (adf_scb->adf_decimal.db_decspec ? (char) adf_scb->adf_decimal.db_decimal : '.'); if (dv1->db_length == 4) { CVfa((f8) *(f4 *) dv1->db_data, adf_scb->adf_outarg.ad_f4width, adf_scb->adf_outarg.ad_f4prec, adf_scb->adf_outarg.ad_f4style, decimal, p, &reswidth); } else { CVfa(*(f8 *)dv1->db_data, adf_scb->adf_outarg.ad_f8width, adf_scb->adf_outarg.ad_f8prec, adf_scb->adf_outarg.ad_f8style, decimal, p, &reswidth); } } break; case DB_DTE_TYPE: case DB_ADTE_TYPE: case DB_TMWO_TYPE: case DB_TMW_TYPE: case DB_TME_TYPE: case DB_TSWO_TYPE: case DB_TSW_TYPE: case DB_TSTMP_TYPE: case DB_INYM_TYPE: case DB_INDS_TYPE: return( adu_6datetostr( adf_scb, dv1, rdv)); case DB_MNY_TYPE: return( adu_9mnytostr( adf_scb, dv1, rdv)); case DB_LVCH_TYPE: case DB_LBYTE_TYPE: case DB_GEOM_TYPE: case DB_POINT_TYPE: case DB_MPOINT_TYPE: case DB_LINE_TYPE: case DB_MLINE_TYPE: case DB_POLY_TYPE: case DB_MPOLY_TYPE: case DB_GEOMC_TYPE: case DB_LNVCHR_TYPE: case DB_LCLOC_TYPE: case DB_LBLOC_TYPE: case DB_LNLOC_TYPE: return( adu_lvch_move( adf_scb, dv1, rdv)); case DB_BIT_TYPE: case DB_VBIT_TYPE: return( adu_bit2str( adf_scb, dv1, rdv)); case DB_LOGKEY_TYPE: case DB_TABKEY_TYPE: return( adu_3logkeytostr( adf_scb, dv1, rdv)); default: return(adu_error(adf_scb, E_AD2090_BAD_DT_FOR_STRFUNC, 0)); } if (!char_text) { if ((db_stat = adu_movestring(adf_scb, (u_char *) p, (i4) STlength(p), dv1->db_datatype, rdv)) != E_DB_OK ) return(db_stat); } return(E_DB_OK); }
/*{ ** Name: psy_print - Format query text to send to user ** ** Description: ** This function decodes query text that comes from the iiqrytext relation ** and formats it to send to the user. It is useful for the "help permit", ** "help integrity", and "help view" commands. ** ** Query text stored in the iiqrytext relation consists of human-readable ** text and special symbols. Some of these special symbols are numbers ** and strings sent from EQUEL or ESQL programs. Others stand for table ** names, range variables, and column numbers. This functio decodes all ** this stuff, and puts the result into a chain of PSY_QTEXT blocks to be ** sent back to the user. ** ** Inputs: ** mstream Memory stream to allocate blocks from ** map map of range var numbers to those ** in rngtab. ** block Current query text block ** text Pointer to the query text ** length Length of the query text ** rngtab The range table (used for decoding the ** special symbol standing for range ** variable numbers, and column numbers). ** The result range variable should stand ** for the table we're getting help on. ** err_blk Filled in if an error happens ** ** Outputs: ** err_blk Filled in if an error happened ** Returns: ** E_DB_OK Success ** E_DB_ERROR Non-catastrophic failure ** E_DB_FATAL Catastrophic failure ** Exceptions: ** none ** ** Side Effects: ** Sends query text to user ** ** History: ** 15-jul-86 (jeff) ** written ** 14-jul-93 (ed) ** replacing <dbms.h> by <gl.h> <sl.h> <iicommon.h> <dbdbms.h> */ DB_STATUS psy_print( PSF_MSTREAM *mstream, i4 map[], PSY_QTEXT **block, u_char *text, i4 length, PSS_USRRANGE *rngtab, DB_ERROR *err_blk) { char buf[1024 + DB_TAB_MAXNAME]; i4 i4align; i2 i2align; f8 f8align; register u_char *p; register i4 j; register i4 i; PSS_RNGTAB *lastvar = (PSS_RNGTAB *) NULL; DB_STATUS status; i4 slength; /* Put out range statements */ for (i = 0; i < PST_NUMVARS; i++) { /* Only look at range vars that are being used */ if (!rngtab->pss_rngtab[i].pss_used || rngtab->pss_rngtab[i].pss_rgno < 0) { continue; } status = psy_put(mstream, (char*) "range of ", (i4) sizeof("range of ") - 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* NULL terminate and trim blanks from range variable name */ MEcopy(rngtab->pss_rngtab[i].pss_rgname, DB_TAB_MAXNAME, buf); buf[DB_TAB_MAXNAME] = '\0'; slength = STtrmwhite(buf); status = psy_put(mstream, buf, slength, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); status = psy_put(mstream, " is ", (i4) sizeof(" is ") - 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* NULL terminate and trim blanks from table name */ MEcopy((char *) &rngtab->pss_rngtab[i].pss_tabname, DB_TAB_MAXNAME, buf); buf[DB_TAB_MAXNAME] = '\0'; slength = STtrmwhite(buf); status = psy_put(mstream, buf, slength, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* Newline after every range statement */ status = psy_put(mstream, (char*) "\n", (i4) 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); } for (p = text; p < (u_char*) text + length;) { switch (*p++) { case PSQ_HVSTR: /* String sent from user program */ slength = STlength((char*) p); /* Emit opening quote */ status = psy_put(mstream, (char *) "\"", 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); for (j = slength; j > 0; j--, p++) { if (*p == '"') { /* Escape any quote characters */ status = psy_put(mstream, "\\\"", 2, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); } else if (!CMprint(p)) { /* Non-printing characters show up as escape sequence */ STprintf(buf, "\\%o", *p); status = psy_put(mstream, buf, (i4) STlength(buf), block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); } else { status = psy_put(mstream, (char*) p, 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); } } break; case PSQ_HVF8: /* f8 sent from user program */ MEcopy((char *) p, sizeof(f8align), (char *) &f8align); STprintf(buf, "%f", f8align); status = psy_put(mstream, buf, (i4) STlength(buf), block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); p += sizeof(f8align); break; case PSQ_HVI4: /* i4 sent from user program */ MEcopy((char *) p, sizeof(i4align), (char *) &i4align); CVla(i4align, buf); status = psy_put(mstream, buf, (i4) STlength(buf), block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); p += sizeof(i4align); break; case PSQ_HVI2: /* i2 sent from user program */ MEcopy((char *) p, sizeof(i2align), (char *) &i2align); CVla((i4) i2align, buf); status = psy_put(mstream, buf, (i4) STlength(buf), block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); p += sizeof(i2align); break; case DB_INTRO_CHAR: /* Intro char for special sequence */ switch (*p++) { case DB_RNG_VAR: /* Put a blank before the table name */ status = psy_put(mstream, " ", 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* Get the range variable number */ MEcopy((char *) p, sizeof(i4align), (char *) &i4align); p += sizeof(i4align); i4align = map[i4align]; /* Look up range variable number */ for (j = 0; j < PST_NUMVARS; j++) { if (rngtab->pss_rngtab[j].pss_used && rngtab->pss_rngtab[j].pss_rgno == i4align) { break; } } /* If found, give variable name, otherwise question marks */ if (j < PST_NUMVARS) { /* trim trailing blanks and NULL terminate */ MEcopy(rngtab->pss_rngtab[j].pss_rgname, DB_TAB_MAXNAME, buf); buf[DB_TAB_MAXNAME] = '\0'; slength = STtrmwhite(buf); status = psy_put(mstream, buf, slength, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* Remember the range variable for when we get the colnum */ lastvar = &rngtab->pss_rngtab[j]; } else { lastvar = (PSS_RNGTAB*) 0; /* Put question marks if not found */ status = psy_put(mstream, "???", 3, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); } break; case DB_COL_NUM: /* Column number for a range var */ /* Get the column number */ MEcopy((char *) p, sizeof(i4align), (char *) &i4align); p += sizeof(i4align); /* If there was no range variable, put question marks */ if (lastvar != (PSS_RNGTAB *) NULL) { status = psy_put(mstream, lastvar->pss_attdesc[i4align]->att_nmstr, lastvar->pss_attdesc[i4align]->att_nmlen, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); } else { /* Don't know column name, just give question marks */ status = psy_put(mstream, "???", 3, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); } /* Put a blank after the column name */ status = psy_put(mstream, " ", 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); break; case DB_TBL_NM: /* The table name is in the result slot of the range table */ /* Put a blank before the table name */ status = psy_put(mstream, " ", 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* NULL terminate and trim blanks from the table name */ MEcopy((char *) &rngtab->pss_rsrng.pss_tabname, sizeof(DB_TAB_NAME), buf); buf[DB_TAB_MAXNAME] = '\0'; slength = STtrmwhite(buf); status = psy_put(mstream, buf, slength, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* Put a blank after the table name */ status = psy_put(mstream, " ", 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); break; case DB_RES_COL: /* Result column: column in result table */ /* Put a blank before the column name */ status = psy_put(mstream, " ", 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* Get the column number for the result column */ MEcopy((char *) p, sizeof(i4align), (char *) &i4align); p += sizeof(i4align); /* Get the column name from the result range variable */ lastvar = &rngtab->pss_rsrng; status = psy_put(mstream, lastvar->pss_attdesc[i4align]->att_nmstr, lastvar->pss_attdesc[i4align]->att_nmlen, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* Put a blank after the column name */ status = psy_put(mstream, " ", 1, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); break; default: /* Unknown special sequence: just put out as it came in */ status = psy_put(mstream, (char*) p - 1, 2, block, err_blk); if (DB_FAILURE_MACRO(status)) return (status); break; } break; default: /* No special case, just put the char */ status = psy_put(mstream, (char*) p - 1, 1, block, err_blk); break; } } /* Put a newline just after the statement */ status = psy_put(mstream, "\n", 1, block, err_blk); return (status); }
STATUS ERslookup( i4 msg_number, CL_ERR_DESC *clerror, i4 flags, char *sqlstate, char *msg_buf, i4 msg_buf_size, i4 language, i4 *msg_length, CL_ERR_DESC *err_code, i4 num_param, ER_ARGUMENT *param ) { i4 erindex; /* index of ERmulti table */ i4 status; i4 length = 0; ER_ARGUMENT *p; ER_ARGUMENT hidden[CLE_INFO_ITEMS]; /* to access info in clerror */ char tempbuf[ER_MAX_LEN+ER_MAX_NAME+2]; i4 templen; char *p_msg_buf; char *p_tempbuf; SYSTIME stime; char langbuf[ER_MAX_LANGSTR]; EX_CONTEXT context; ER_SEMFUNCS *sems; #define D_WIDTH 23 #define F_WIDTH 20 #define X_WIDTH 18 /* Validate the parameters. */ if (msg_buf == 0 || msg_buf_size == 0 || msg_length == 0) { return (ER_BADPARAM); } if (language != -1 && ERlangstr(language,langbuf) != OK) { return (ER_BADLANGUAGE); } if (!(flags & ER_NAMEONLY)) { EXdump(msg_number,0); } /* Insert timestamp if requested. */ if (flags & ER_TIMESTAMP) { if (msg_buf_size < 21) { return (ER_TOOSMALL); } TMnow(&stime); TMstr(&stime,msg_buf); length = (i4)STlength(msg_buf); msg_buf[length++] = ' '; } /* ** if (clerror && msg_number) ** look up msg_number, optional parameters in clerror->moreinfo ** else if (clerror) ** { ** if (clerror->intern) ** look up clerror.intern, optional params in clerror->moreinfo ** if (clerror->callid) ** look up system error message ** } */ if (clerror) { if (msg_number) /* Look up message after system error */ { /* ** Set up an ER_ARGUMENT that references system-dependent ** information in `clerror', and point `param' at it. */ i4 i; for (i = 0; i < CLE_INFO_ITEMS; ++i) { /* "...all of whose members begin at offset 0..." (K&R) */ hidden[i].er_value = (PTR)&clerror->moreinfo[i].data._i4; hidden[i].er_size = clerror->moreinfo[i].size; } param = &hidden[0]; num_param = CLE_INFO_ITEMS; } else /* retrieve system-dependent error messages */ { i4 len; ER_ARGUMENT argv[3]; if (clerror->intern) /* look up internal CL error */ { i4 i; for (i = 0; i < CLE_INFO_ITEMS; ++i) { argv[i].er_value = (PTR)&clerror->moreinfo[i].data._i4; argv[i].er_size = clerror->moreinfo[i].size; } /* ** Don't timestamp on recursive call, since it's been done ** already (if requested). */ if ((status = ERslookup((i4) clerror->intern, (CL_ERR_DESC*) NULL, flags & ~ER_TIMESTAMP | ER_TEXTONLY, NULL, &msg_buf[length], msg_buf_size-length, language, &len, err_code, CLE_INFO_ITEMS, argv)) != OK) { return (status); } length += len; if (clerror->callid) msg_buf[length++] = '\n'; } if (clerror->callid) /* look up system error message text */ { DESCRIPTOR msg_desc; msg_desc.desc_length = sizeof(tempbuf) - 1; msg_desc.desc_value = tempbuf; if ((status = cer_sysgetmsg(clerror, &len, &msg_desc, err_code)) != OK) { return(status); } argv[0].er_size = argv[1].er_size = argv[2].er_size = ER_PTR_ARGUMENT; argv[0].er_value = (PTR)&clerror->errnum; argv[1].er_value = (PTR)ERNAME((i4) clerror->callid); argv[2].er_value = (PTR)tempbuf; if ((status = ERslookup(ER_UNIXERROR, (CL_ERR_DESC*) NULL, flags & ~ER_TIMESTAMP | ER_TEXTONLY, NULL, &msg_buf[length], msg_buf_size - length, language, &len,err_code, 3, argv)) != OK) { return (status); } length += len; } msg_buf[*msg_length = length] = EOS; return (OK); } } /* ** Check if error message file is already opened or not yet. ** First see if the language is initialized. If not, initialize ** it and the message files. ** If it is already opened, cer_fndindex function returns the index of ** ERmulti table that internal language code is parameter 'language'. ** If not yet, it returns '-1'. */ if (cer_issem(&sems)) { if (((sems->sem_type & MU_SEM) ? (*sems->er_p_semaphore)(&sems->er_mu_sem) : (*sems->er_p_semaphore)(1, &sems->er_sem)) != OK) { sems = NULL; } } if ((erindex = cer_fndindex(language)) == -1) { if ((status = cer_nxtindex(language,&erindex)) != OK) { /* Error in initializing the language */ if (sems) { if (sems->sem_type & MU_SEM) _VOID_ (*sems->er_v_semaphore)(&sems->er_mu_sem); else _VOID_ (*sems->er_v_semaphore)(&sems->er_sem); } return (status); } } /* If the error message file is not opened, open the message file. */ if (!cer_isopen(erindex,ER_SLOWSIDE)) { if ((status = cer_sinit(language,msg_number,erindex,err_code)) != OK) { if (sems) { if (sems->sem_type & MU_SEM) _VOID_ (*sems->er_v_semaphore)(&sems->er_mu_sem); else _VOID_ (*sems->er_v_semaphore)(&sems->er_sem); } return (status); } } /* If not open then just return. */ if (!cer_isopen(erindex,ER_SLOWSIDE)) { if (sems) { if (sems->sem_type & MU_SEM) _VOID_ (*sems->er_v_semaphore)(&sems->er_mu_sem); else _VOID_ (*sems->er_v_semaphore)(&sems->er_sem); } /* ** As internal file id is '0', openning file will fail. ** In her,return status 'ER_BADOPEN' to show open fail. */ return (ER_BADOPEN); } /* ** Search message string from file and set to buffer. ** Error status on system call set to 'err_code'. */ status = cer_sstr(msg_number, sqlstate, tempbuf, msg_buf_size - length, erindex, err_code, flags & ER_TEXTONLY? ER_GET : ER_LOOKUP); if (sems) { if (sems->sem_type & MU_SEM) _VOID_ (*sems->er_v_semaphore)(&sems->er_mu_sem); else _VOID_ (*sems->er_v_semaphore)(&sems->er_sem); } if (status != OK) { return (status); } /* ** Format the text with parameters into the callers buffer. ** The message is truncated if it will not fit. */ /* Insert part of name from temporary buffer to buffer */ status = OK; templen = (i4)STlength(tempbuf); p_msg_buf = &msg_buf[length]; p_tempbuf = tempbuf; if (!(flags & ER_TEXTONLY)) { while(*p_tempbuf != '\t') { CMcpyinc(p_tempbuf,p_msg_buf); } CMcpyinc(p_tempbuf,p_msg_buf); } /* ============================================ */ /* Copy text to message substituting arguments. */ /* -------------------------------------------- */ /* (But first, declare an exception handler to */ /* catch bad params that may access violate.) */ /* ============================================ */ if (EXdeclare(er_exhandler, &context)) { u_i4 res_len; u_i4 bytes_left_in_buf; bytes_left_in_buf = (u_i4)(msg_buf_size - (p_msg_buf - msg_buf)); res_len = STlen( STncpy(p_msg_buf, ERx("*** ERslookup() ERROR: Missing or bad parameter for this message. ***"), bytes_left_in_buf )); p_msg_buf[ bytes_left_in_buf - 1 ] = EOS; p_msg_buf += res_len; *msg_length = (i4)(p_msg_buf - msg_buf); EXdelete(); return (OK); } for( ;p_tempbuf - tempbuf < templen; CMnext(p_tempbuf)) { long number; u_long unumber; double fnumber; i4 i; i4 pnum; if ( (*p_tempbuf != '%') || (flags & ER_NOPARAM) ) { if ((p_msg_buf - msg_buf) >= msg_buf_size) break; CMcpychar(p_tempbuf,p_msg_buf); CMnext(p_msg_buf); continue; } if (p_tempbuf - tempbuf + 2 >= templen) continue; CMnext(p_tempbuf); if (*p_tempbuf == '!') { if ((p_msg_buf - msg_buf) + 3 >= msg_buf_size) continue; CMcpychar(ERx("\r"),p_msg_buf); CMnext(p_msg_buf); CMcpychar(ERx("\n"),p_msg_buf); CMnext(p_msg_buf); CMcpychar(ERx("\t"),p_msg_buf); CMnext(p_msg_buf); continue; } /* ** Only works for up to 10 parameters, and makes character set ** assumptions - should be fixed. */ if ( *p_tempbuf < '0' || *p_tempbuf > '9' ) { /* treat any other character as a literal */ if ((p_msg_buf - msg_buf) >= msg_buf_size) break; if ( *p_tempbuf != '%' ) { CMcpychar("%",p_msg_buf); CMnext(p_msg_buf); } CMcpychar(p_tempbuf,p_msg_buf); CMnext(p_msg_buf); continue; } pnum = *p_tempbuf - '0'; if (pnum >= num_param) { EXdelete(); return(ER_BADPARAM); } p = ¶m[pnum]; CMnext(p_tempbuf); switch (*p_tempbuf) { case 'd': /* Convert an integer into the buffer with width D_WIDTH */ if (p->er_size == ER_PTR_ARGUMENT) /* this is ptr to i4 */ number = *(i4 *)p->er_value; else if (p->er_size == 0) /* this is a i4 */ number = (i4)(SCALARP)p->er_value; else if (p->er_size == 1) number = *(i1 *)p->er_value; else if (p->er_size == 2) number = *(i2 *)p->er_value; else if (p->er_size == 4) number = *(i4 *)p->er_value; else if (p->er_size == 8) number = *(i8 *)p->er_value; else continue; if (p_msg_buf - msg_buf + D_WIDTH >= msg_buf_size) continue; if (p->er_size == 8) { CVla8(number, p_msg_buf); } else { CVla((i4)number, p_msg_buf); } while (*p_msg_buf) CMnext(p_msg_buf); continue; case 'u': /* Convert an integer into the buffer with width D_WIDTH */ if (p->er_size == ER_PTR_ARGUMENT) /* this is ptr to u_i4 */ number = *(u_i4 *)p->er_value; else if (p->er_size == 0) /* this is a u_i4 */ number = (u_i4)(SCALARP)p->er_value; else if (p->er_size == 1) number = *(u_i1 *)p->er_value; else if (p->er_size == 2) number = *(u_i2 *)p->er_value; else if (p->er_size == 4) number = *(u_i4 *)p->er_value; else if (p->er_size == 8) number = *(u_i8 *)p->er_value; else continue; if (p_msg_buf - msg_buf + D_WIDTH >= msg_buf_size) continue; if (p->er_size == 8) { CVula8(number, p_msg_buf); } else { CVula((u_i4)number, p_msg_buf); } while (*p_msg_buf) CMnext(p_msg_buf); continue; case 'f': { i2 res_width; /* Convert a float into the buffer with width F_WIDTH */ if (p->er_size == ER_PTR_ARGUMENT) /* Pointer to a double */ fnumber = *(double *)p->er_value; else if (p->er_size == 4) fnumber = *(f4 *)p->er_value; else if (p->er_size == 8) fnumber = *(f8 *)p->er_value; else continue; if (p_msg_buf - msg_buf + F_WIDTH >= msg_buf_size) continue; /* Always convert to 'e' format. */ CVfa(fnumber, (i4) 20, (i4) 5, 'e', '.', p_msg_buf, &res_width); p_msg_buf += F_WIDTH; continue; } case 'c': /* Convert a character array into buffer. */ if (p->er_value == 0) p->er_value = (PTR)ERx("<missing>"); if ((p->er_size == 0) || (p->er_size == ER_PTR_ARGUMENT)) { for (i = 0; ((char *)p->er_value)[i]; i++) ; p->er_size = i; } if (p_msg_buf - msg_buf + p->er_size >= msg_buf_size) continue; if (p->er_size > msg_buf_size - (p_msg_buf - msg_buf)) p->er_size = (i4)(msg_buf_size - (p_msg_buf - msg_buf)); /* p->er_size=STtrmwhite(p_msg_buf);*/ MEcopy(p->er_value, p->er_size, p_msg_buf); p->er_size = (i4)STtrmnwhite(p_msg_buf, p->er_size); p_msg_buf += p->er_size; continue; case 'x': /* Convert an integer into the buffer with width D_WIDTH */ if (p->er_size == ER_PTR_ARGUMENT) unumber = *(u_i4 *)p->er_value; else if (p->er_size == 0) unumber = (u_i4)(SCALARP)p->er_value; else if (p->er_size == 1) unumber = *(u_i1 *)p->er_value; else if (p->er_size == 2) unumber = *(u_i2 *)p->er_value; else if (p->er_size == 4) unumber = *(u_i4 *)p->er_value; else if (p->er_size == 8) unumber = *(u_i8 *)p->er_value; if (p_msg_buf - msg_buf + X_WIDTH >= msg_buf_size) continue; for (i = 8; --i >= 0; ) { /* {@fix_me@} ** This is *NOT* machine independent. This relys on an ** ASCII-like character set, where the digits '0'-'9' are ** contiguous and sequential, and the characters 'A'-'F' ** are contiguous and sequential. Both ASCII and EBCDIC ** happen to be this way. */ if ((*(p_msg_buf + i) = (unumber & 0x0f) + '0') > '9') *(p_msg_buf + i) += 'A' - '9' - 1; unumber >>= 4; } p_msg_buf += 8; continue; default: continue; } } *msg_length = (i4)(p_msg_buf - msg_buf); *p_msg_buf = EOS; EXdelete(); return (OK); }
DB_STATUS psy_kalarm( PSY_CB *psy_cb, PSS_SESBLK *sess_cb) { RDF_CB rdf_cb; RDR_RB *rdf_rb = &rdf_cb.rdf_rb; RDF_CB rdf_inv_cb; DB_STATUS status; DB_SECALARM *atuple= &psy_cb->psy_tuple.psy_alarm; i4 i; PSY_OBJ *psy_obj; bool loop=FALSE; /* Fill in the RDF request blocks */ pst_rdfcb_init(&rdf_cb, sess_cb); rdf_rb->rdr_types_mask = RDR_SECALM; /* Alarm deletion */ rdf_rb->rdr_update_op = RDR_DELETE; rdf_rb->rdr_qrytuple = (PTR)atuple;/* Alarm tuple */ pst_rdfcb_init(&rdf_inv_cb, sess_cb); rdf_inv_cb.rdf_rb.rdr_types_mask |= RDR_SECALM; do { /* ** Loop through each alarm in turn deleting them. ** User may have specified alarms by name or by number, or by all */ if (psy_cb->psy_numnms == 0 && (PSY_OBJ*)psy_cb->psy_objq.q_next == (PSY_OBJ*)&psy_cb->psy_objq) { /* ** Drop all alarms on the indicated object */ rdf_rb->rdr_types_mask |= RDR_DROP_ALL; STmove(ERx("all alarms"),' ', sizeof(atuple->dba_alarmname), (char*)&atuple->dba_alarmname); status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb); /* Destroy alarm */ if (status != E_DB_OK) { _VOID_ psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error, &psy_cb->psy_error); } } if(psy_cb->psy_numnms) { /* ** Dropping alarms by number, so walk through all numbers dropping. */ for (i=0;i <psy_cb->psy_numnms; i++) { char tmpstr[64]; CVla((i4)psy_cb->psy_numbs[i],tmpstr); STmove(tmpstr,' ', sizeof(atuple->dba_alarmname), (char*)&atuple->dba_alarmname); atuple->dba_alarmno=psy_cb->psy_numbs[i]; status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb); if (status != E_DB_OK) { _VOID_ psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error, &psy_cb->psy_error); break; } } } if((PSY_OBJ*)psy_cb->psy_objq.q_next!= (PSY_OBJ*)&psy_cb->psy_objq) { /* ** Dropping alarms by name, so walk through all names dropping */ for (psy_obj = (PSY_OBJ *) psy_cb->psy_objq.q_next; psy_obj != (PSY_OBJ *) &psy_cb->psy_objq; psy_obj = (PSY_OBJ *) psy_obj->queue.q_next ) { MEcopy((PTR)&psy_obj->psy_objnm, sizeof(atuple->dba_alarmname), (PTR)&atuple->dba_alarmname); atuple->dba_alarmno=0; status = rdf_call(RDF_UPDATE, (PTR) &rdf_cb);/* Destroy alarm */ if (status != E_DB_OK) { _VOID_ psf_rdf_error(RDF_UPDATE, &rdf_cb.rdf_error, &psy_cb->psy_error); break; } } } } while(loop); if(status==E_DB_OK && atuple->dba_objtype==DBOB_TABLE) { /* ** Invalidate table infoblk from RDF cache. */ STRUCT_ASSIGN_MACRO(atuple->dba_objid, rdf_inv_cb.rdf_rb.rdr_tabid); status = rdf_call(RDF_INVALIDATE, (PTR) &rdf_inv_cb); /* drop infoblk */ if (DB_FAILURE_MACRO(status)) { (VOID) psf_rdf_error(RDF_INVALIDATE, &rdf_inv_cb.rdf_error, &psy_cb->psy_error); return(status); } } return (status); } /* psy_kalarm */
/* ** Name: psl_lm4_setlockparm_num() - perform semantic action for SETLOCKPARM ** production when the characteristic value ** has been specified as a number or a string ** constant containing a number ** ** Input: ** char_type characteristic type ** char_val value as specified by the user ** sess_cb PSF session CB ** pss_distrib DB_3_DDB_SESS if distributed thread ** pss_stmt_flags PSS_SET_LOCKMODE_SESS if SET LOCKMODE ** SESSION (distributed thread only) ** pss_object points to DMC_CB (or QEF_RCB) structure ** dmc_char_array characteristics array ** dmc_sl_scope scope of SET LOCKMODE ** pss_auxrng ** pss_rerng if setting lockmode on a table, table's ** description can be found here ** ** Output: ** err_blk filled in if an error occurred ** ** Returns: ** E_DB_{OK, ERROR, SEVERE} ** ** Side effects: ** None ** ** History: ** 07-mar-91 (andre) ** plagiarized from SETLOCKPARM production ** 21-apr-92 (barbara) ** Added support for Sybil. For distributed thread, on ** SET LOCKMODE SESSION .. TIMEOUT we set timeout value ** specifically for QEF. ** 19-oct-92 (barbara) ** Test for non_distrib before testing dmc_cb fields (because ** Star doesn't have valid dmc_cb). */ DB_STATUS psl_lm4_setlockparm_num( i4 char_type, i4 char_val, PSS_SESBLK *sess_cb, DB_ERROR *err_blk) { i4 err_code, err_no = 0L; DMC_CHAR_ENTRY *chr; DMC_CB *dmc_cb; bool not_distr = ~sess_cb->pss_distrib & DB_3_DDB_SESS; if (not_distr) { dmc_cb = (DMC_CB *) sess_cb->pss_object; if (dmc_cb->dmc_char_array.data_in_size / sizeof (DMC_CHAR_ENTRY) == MAX_LOCKMODE_CHARS) { (VOID) psf_error(5931L, 0L, PSF_USERERR, &err_code, err_blk, 0); return (E_DB_ERROR); /* non-zero return means error */ } chr = (DMC_CHAR_ENTRY *) ((char *) dmc_cb->dmc_char_array.data_address + dmc_cb->dmc_char_array.data_in_size); } switch (char_type) { case LOCKLEVEL: /* Can't set locklevel to a number */ err_no = 5924L; break; case READLOCK: /* Can't set readlocks to a number */ err_no = 5925L; break; case MAXLOCKS: if (not_distr) { chr->char_id = DMC_C_LMAXLOCKS; } break; case TIMEOUT: { extern PSF_SERVBLK *Psf_srvblk; /* ** if server was started with OPF flag which may result in ** deadlock when accesing SCONSUR catalogs, iihistogram, and ** iistatistics, we have to prevent user from specifying ** TIMEOUT=0 for any of these catalogs */ if (not_distr && Psf_srvblk->psf_flags & PSF_NO_ZERO_TIMEOUT && dmc_cb->dmc_sl_scope == DMC_SL_TABLE) { DB_TAB_ID *tabid = &dmc_cb->dmc_table_id; PSS_RNGTAB *tbl = &sess_cb->pss_auxrng.pss_rsrng; i4 mask = tbl->pss_tabdesc->tbl_status_mask; if (mask & DMT_CATALOG && char_val == 0L && (mask & DMT_CONCURRENCY || tabid->db_tab_base == DM_B_STATISTICS_TAB_ID && tabid->db_tab_index == DM_I_STATISTICS_TAB_ID || tabid->db_tab_base == DM_B_HISTOGRAM_TAB_ID && tabid->db_tab_index == DM_I_HISTOGRAM_TAB_ID ) ) { (VOID) psf_error(E_PS0352_ILLEGAL_0_TIMEOUT, 0L, PSF_USERERR, &err_code, err_blk, 1, psf_trmwhite(sizeof(tbl->pss_tabname), (char *) &tbl->pss_tabname), &tbl->pss_tabname); return (E_DB_ERROR); } } if (not_distr) { chr->char_id = DMC_C_LTIMEOUT; } else if (sess_cb->pss_stmt_flags & PSS_SET_LOCKMODE_SESS) { /* ** The distributed server is interested in the value from ** the SETLOCKKEY production when the SETLOCKSCOPE value ** was session; otherwise the set statement is just ** pased on to the LDBs. */ ((QEF_RCB*)sess_cb->pss_object)->qef_r3_ddb_req. qer_d14_ses_timeout = char_val; } break; } default: /* Unknown "set lockmode" parameter */ (VOID) psf_error(E_PS0351_UNKNOWN_LOCKPARM, 0L, PSF_INTERR, &err_code, err_blk, 1, (i4) sizeof(char_type), &char_type); return (E_DB_SEVERE); /* non-zero return means error */ } if (err_no != 0L) { char num_buf[30]; CVla((i4) char_val, num_buf); (VOID) psf_error(err_no, 0L, PSF_USERERR, &err_code, err_blk, 1, (i4) STlength(num_buf), num_buf); return (E_DB_ERROR); /* non-zero return means error */ } else if (not_distr) { chr->char_value = char_val; dmc_cb->dmc_char_array.data_in_size += sizeof (DMC_CHAR_ENTRY); } return(E_DB_OK); }