The following is a sample of a CLI program.
/**********************************************************************/ /* This is a sample PM/API application. */ /* 1) Prompts for a logon string */ /* 2) Connects to a Teradata RDBMS and establishes a MONITOR session */ /* 3) Prompts for input parameter for MONITOR SESSION; PM/API command */ /* 4) Submits MONITOR SESSION; */ /* 5) Retrieves the response, formats and prints the response parcels */ /* 6) Above 3 - 5 are repeated until Q is entered in #3. */ /* 7) Disconnects. */ /**********************************************************************/ #include <stdio.h> #include <string.h> #include <stdlib.h> #include "samplepmpc.h" // Global variables struct DBCAREA dbc; /* see dbcarea.h for definition of structure */ char cnta[4]; int IndicatorMode; unsigned short TargetVersion = 6; char RespMode = 'R'; static int IndicFieldCount = 0; static char CurrRequestText[32]; #define MON_SESS_REQ 1 // List of field names for Monitor Session Record 2 char *MonSesRec2fieldnamelist[]= { "HostId", "LogonProcId", "RunProcId", "SessionNo", "UserName", "UserAccount", "UserId", "LSN", "LogonTime", "LogonDate", "PartName", "Priority", "IFPState", "IFPCPUSec", "XactCount", "ReqCount", "ReqCacheHits", "AMPState", "AMPCPUSec", "AMPIO", "DeltaAMPSpool", "Blk1HostId", "Blk1SessNo", ""Blk1UserId", "Blk1LMode", "Blk1OType", "Blk1ObjDBId", "Blk1ObjTId", "Blk1Status", "Blk2HostId", "Blk2SessNo", "Blk2UserId", "Blk2LMode", "Blk2OType", "Blk2ObjDBId", "Blk2ObjTId", "Blk2Status", "Blk3HostId", "Blk3SessNo", "Blk3UserId", "Blk3LMode", "Blk3OType", "Blk3ObjDBId", "Blk3ObjTId", "Blk3Status", "MoreBlockers", "LogonSource", "TempSpaceUsage", "HotAmp1CPU", "HotAmp2CPU", "HotAmp3CPU", "HotAmp1IO ", "HotAmp2IO ", "HotAmp3IO ", "HotAmp1CPUId", "HotAmp2CPUId", "HotAmp3CPUId", "HotAmp1IOId", "HotAmp2IOId", "HotAmp3IOId", "LowAmp1CPU", "LowAmp2CPU", "LowAmp3CPU", "LowAmp1IO ", "LowAmp2IO ", "LowAmp3IO ", "LowAmp1CPUId", "LowAmp2CPUId", "LowAmp3CPUId", "LowAmp1IOId", "LowAmp2IOId", "LowAmp3IOId", "AmpCount", "AvgAmpCPUSec", "AvgAmpIOCnt", "ReqStartTime", "ReqStartDate", "ReqCPU", "ReqIO", "RequestNo", "WlcId", "DontReclassifyFlag", }; /* This routine displays the presence bits along with the field name. */ static void PrintPresenceBits(char *ptr,int fieldcount,char **fieldnamelist) { char *tempptr=ptr; char temp = *ptr; int i=0; int bitOn; char buf[200]; int endlist=0; printf("\nPresence Bits:\n"); while (i < fieldcount) { bitOn = (temp & (char)0x80); if (!endlist) { if (!fieldnamelist || (fieldnamelist && strlen(fieldnamelist[i]) == 0)) endlist = 1; }; if (endlist) { sprintf(buf,"Field%03d",i+1); } else strcpy(buf,fieldnamelist[i]); if (bitOn) printf("[%02d] %30s \tis \tNULL\n",i,buf); else printf("[%02d] %30s \tis \tNOT NULL\n",i,buf); i++; if ((i % 8) == 0) { tempptr++; temp = *tempptr; } else temp = temp << 1; } printf("\n"); } /***************************************************************/ /* WRITE_ERROR -- Prints error message that is located in */ /* the response buffer--Error or Failure Parcel */ /***************************************************************/ static void Write_error(char *parcel) { int i; Error_Fail_t *Error_Fail; Error_Fail = ((struct ERROR_FAIL_Type *) (parcel)); printf("DBS Error code: %d : ",Error_Fail->Code); for(i=0;i < (int)Error_Fail->Length;i++) printf("%c",Error_Fail->Msg[i]); printf("\n"); } /**end write_error**/ /* MONITOR SESSION formatting routines */ static void PrtSes1(char *dataptr) { short *SampleRate; SampleRate = (short *) (dataptr); printf("Sample rate: %d seconds\n\n", *SampleRate); } static void PrtSes2(char *dataptr, int version) { MonSesRec2_t *MonSesRec2; MonSesRecV3_t *MonSesRecV3; MonSesRecV4_t *MonSesRecV4; MonSesRecV5_t *MonSesRecV5; MonSesRec2 = (MonSesRec2_t *) (dataptr); if (version >= MONVERSION3) { MonSesRecV3 = (MonSesRecV3_t *)(((char *) (&MonSesRec2->LogonSource)) + MonSesRec2->LogonSourceLen); } if (version >=MONVERSION4) { MonSesRecV4 = (MonSesRecV4_t *) (MonSesRecV3 +1); } if (version >=MONVERSION5) { MonSesRecV5 = (MonSesRecV5_t *) (MonSesRecV4 +1); } printf("HostId: %8d ", MonSesRec2->HostId); printf("SessionNo: %d\n", MonSesRec2->SessionNo); printf("LogonPENo: %5d ", MonSesRec2->LogonProcId); printf("RunVprocNo: %5d\n", MonSesRec2->RunProcId); printf("PartName: %.16s", MonSesRec2->PartName); printf("PEState: %.18s\n\n", MonSesRec2->PEState); printf("LogonDate: %04d/%02d/%02d ", (int) MonSesRec2->LogonDate / 10000 + 1900, (int) MonSesRec2->LogonDate / 100 % 100, (int) MonSesRec2->LogonDate % 100); printf("LogonTime: %02d:%02d:%05.2f\n", (int) MonSesRec2->LogonTime / 10000, (int) MonSesRec2->LogonTime / 100 % 100, (int) MonSesRec2->LogonTime % 100 + MonSesRec2->LogonTime - (int) MonSesRec2->LogonTime); printf("UserID: %d ", MonSesRec2->UserID); printf("LSN: %d\n", MonSesRec2->LSN); printf("UserName: %.30s\n", MonSesRec2->UserName); printf("UserAccount: %.30s\n\n", MonSesRec2->UserAccount); printf("PECPUSec: %10.2f ", MonSesRec2->PECPUSec); printf("XactCount: %13.2f\n", MonSesRec2->XactCount); printf("ReqCount: %10.1f ", MonSesRec2->ReqCount); printf("ReqCacheHits: %10.1f\n\n", MonSesRec2->ReqCacheHits); printf("AMPState: %.18s\n", MonSesRec2->AMPState); printf("AMPCPUSec: %9.2f ", MonSesRec2->AMPCPUSec); printf("AMPIO: %7.2f\n", MonSesRec2->AMPIO); printf("Request_AMPSpool: %4.1f\n\n", MonSesRec2->Delta_AMPSpool); printf("Blk_1_HostId: %6d ", MonSesRec2->Blk_1_HostId); printf("Blk_2_HostId: %6d ", MonSesRec2->Blk_2_HostId); printf("Blk_3_HostId: %6d\n", MonSesRec2->Blk_3_HostId); printf("Blk_1_SessNo: %6d ", MonSesRec2->Blk_1_SessNo); printf("Blk_2_SessNo: %6d ", MonSesRec2->Blk_2_SessNo); printf("Blk_3_SessNo: %6d\n", MonSesRec2->Blk_3_SessNo); printf("Blk_1_UserID: %6d ", MonSesRec2->Blk_1_UserID); printf("Blk_2_UserID: %6d ", MonSesRec2->Blk_2_UserID); printf("Blk_3_UserID: %6d\n", MonSesRec2->Blk_3_UserID); printf("Blk_1_LMode: %c ", MonSesRec2->Blk_1_LMode); printf("Blk_2_LMode: %c ", MonSesRec2->Blk_2_LMode); printf("Blk_3_LMode: %c\n", MonSesRec2->Blk_3_LMode); printf("Blk_1_OType: %c ", MonSesRec2->Blk_1_OType); printf("Blk_2_OType: %c ", MonSesRec2->Blk_2_OType); printf("Blk_3_OType: %c\n", MonSesRec2->Blk_3_OType); printf("Blk_1_ObjDBId: %5d ", MonSesRec2->Blk_1_ObjDBId); printf("Blk_2_ObjDBId: %5d ", MonSesRec2->Blk_2_ObjDBId); printf("Blk_3_ObjDBId: %5d\n", MonSesRec2->Blk_3_ObjDBId); printf("Blk_1_ObjTId: %6d ", MonSesRec2->Blk_1_ObjTId); printf("Blk_2_ObjTId: %6d ", MonSesRec2->Blk_2_ObjTId); printf("Blk_3_ObjTId: %6d\n", MonSesRec2->Blk_3_ObjTId); printf("Blk_1_Status: %c ", MonSesRec2->Blk_1_Status); printf("Blk_2_Status: %c ", MonSesRec2->Blk_2_Status); printf("Blk_3_Status: %c\n", MonSesRec2->Blk_3_Status); printf("MoreBlockers: %c\n\n", MonSesRec2->MoreBlockers); MonSesRec2->LogonSource[MonSesRec2->LogonSourceLen] = '\0'; printf("LogonSource: %.128s\n\n", MonSesRec2->LogonSource); /* MonVerId 3 fields */ if (version < MONVERSION3) return; printf("HotAmp1CPU: %9.2f ", MonSesRecV3->HotAmp1CPU); printf("HotAmp2CPU: %9.2f ", MonSesRecV3->HotAmp2CPU); printf("HotAmp3CPU: %9.2f\n", MonSesRecV3->HotAmp3CPU); printf("HotAmp1CPUId: %7d ", MonSesRecV3->HotAmp1CPUId); printf("HotAmp2CPUId: %7d ", MonSesRecV3->HotAmp2CPUId); printf("HotAmp3CPUId: %7d\n\n", MonSesRecV3->HotAmp3CPUId); printf("HotAmp1IO: %10.2f ", MonSesRecV3->HotAmp1IO); printf("HotAmp2IO: %10.2f ", MonSesRecV3->HotAmp2IO); printf("HotAmp3IO: %10.2f\n", MonSesRecV3->HotAmp3IO); printf("HotAmp1IOId: %8d ", MonSesRecV3->HotAmp1IOId); printf("HotAmp2IOId: %8d ", MonSesRecV3->HotAmp2IOId); printf("HotAmp3IOId: %8d\n\n", MonSesRecV3->HotAmp3IOId); printf("LowAmp1CPU: %9.2f ", MonSesRecV3->LowAmp1CPU); printf("LowAmp2CPU: %9.2f ", MonSesRecV3->LowAmp2CPU); printf("LowAmp3CPU: %9.2f\n", MonSesRecV3->LowAmp3CPU); printf("LowAmp1CPUId: %7d ", MonSesRecV3->LowAmp1CPUId); printf("LowAmp2CPUId: %7d ", MonSesRecV3->LowAmp2CPUId); printf("LowAmp3CPUId: %7d\n\n", MonSesRecV3->LowAmp3CPUId); printf("LowAmp1IO: %10.2f ", MonSesRecV3->LowAmp1IO); printf("LowAmp2IO: %10.2f ", MonSesRecV3->LowAmp2IO); printf("LowAmp3IO: %10.2f\n", MonSesRecV3->LowAmp3IO); printf("LowAmp1IOId: %8d ", MonSesRecV3->LowAmp1IOId); printf("LowAmp2IOId: %8d ", MonSesRecV3->LowAmp2IOId); printf("LowAmp3IOId: %8d\n\n", MonSesRecV3->LowAmp3IOId); printf("AvgAmpCPUSec:%8.2f ", MonSesRecV3->AvgAmpCPUSec); printf("AvgAmpIOCnt: %8.2f\n", MonSesRecV3->AvgAmpIOCnt); printf("AmpCount: %11d\n\n", MonSesRecV3->AmpCount); printf("TempSpaceUsg: %7.2f\n\n", MonSesRecV3->TempSpaceUsage); if (version <MONVERSION4) return; /* MonVerId 4 fields */ printf("ReqStartTime: %04d/%02d/%02d ", (int) MonSesRecV4->ReqStartDate / 10000 + 1900, (int) MonSesRecV4->ReqStartDate / 100 % 100, (int) MonSesRecV4->ReqStartDate % 100); printf("%02d:%02d:%05.2f", (int) MonSesRecV4->ReqStartTime / 10000, (int) MonSesRecV4->ReqStartTime / 100 % 100, (int) MonSesRecV4->ReqStartTime % 100 + MonSesRecV4->ReqStartTime - (int) MonSesRecV4->ReqStartTime); printf(" ReqCPU: %10.2f", MonSesRecV4->ReqCPU); printf(" ReqIO: %10.2f\n", MonSesRecV4->ReqIO); if (version <MONVERSION5) return; /* MonVerId 5 fields */ printf("ReqNo:%d WlcId: %d DontReclassifyFlag: %d\n", MonSesRecV5->ReqNo, MonSesRecV5->WlcId,MonSesRecV5->DontReclassifyFlag); } static void CheckSuccess(int ActivityType, int ActivityCount, int StatementNo) { switch (ActivityType) { case PCLSTMTNULL: printf("Null statement successful. \n\n"); break; } return; } static void CheckData(int ActivtyType, int StatementNo) { DataInfo_t * DataInfo; int i; DataInfo = (DataInfo_t *) (dbc.fet_data_ptr); printf("\nCheckData called for Indicator mode data info parcel.\n"); printf("Field Count: %d \n", DataInfo->field_count); IndicFieldCount = DataInfo->field_count; if (DataInfo->field_count > MAXFIELDS) DataInfo->field_count = MAXFIELDS; for (i = 0; i < DataInfo->field_count; i++) { printf("Field %d: Type = %d Size = %d\n", i + 1, DataInfo->FieldData[i].FType, DataInfo->FieldData[i].FSize); } return; } static void CheckRecord(int ActivtyType, int StatementNo, int ActivityCount) { switch (ActivtyType) { case PCLMONSESS: if (StatementNo == 1) PrtSes1(dbc.fet_data_ptr); else if (StatementNo == 2) { int IndLen=0; if (IndicatorMode) { switch (TargetVersion) { case MONVERSION3: case MONVERSION4: IndLen = 10; break; case MONVERSION5: case MONVERSION6: default: IndLen = 11; break; } PrintPresenceBits(dbc.fet_data_ptr,IndicFieldCount,MonSesRec2fieldnamelist); dbc.fet_data_ptr = (char *)dbc.fet_data_ptr + IndLen; } PrtSes2(dbc.fet_data_ptr,TargetVersion); printf("\n"); printf("----------------------------------------------------\n\n"); } break; default: printf("\nFound a funny parcel number: %d\n",ActivtyType); break; } } /***************************************************************/ /* SET_OPTIONS -- sets cli options (record,field,indicator */ /* mode; etc..) */ /* Sets size of buffers (request and response) */ /***************************************************************/ set_options() { dbc.change_opts = 'Y'; dbc.resp_mode = 'R'; dbc.use_presence_bits = 'Y'; dbc.keep_resp = 'N'; dbc.wait_across_crash = 'N'; dbc.tell_about_crash = 'Y'; dbc.loc_mode = 'Y'; dbc.var_len_req = 'N'; dbc.var_len_fetch = 'N'; dbc.save_resp_buf = 'N'; dbc.two_resp_bufs = 'N'; dbc.ret_time = 'N'; dbc.parcel_mode = 'Y'; dbc.wait_for_resp = 'Y'; dbc.req_proc_opt = 'E'; dbc.req_buf_len = 256; dbc.resp_buf_len = 32000; return(0); } /**end set_options**/ /***************************************************************/ /* EXITOUT -- If connected logs off session. Cleans up */ /* any used memory. */ /***************************************************************/ void exitout(int status) { Int32 result; if (status == CONNECTED) { printf ("Logging off.\n"); dbc.func = DBFDSC; DBCHCL (&result,cnta,&dbc); if (result != EM_OK) printf("disconnect failed -- %s\n", dbc.msg_text); } DBCHCLN(&result,cnta); if (result != EM_OK) printf("cleanup failed -- %s\n", dbc.msg_text); exit(0); } /**end exitout**/ /***************************************************************/ /* INITIALIZE_DBCAREA -- Sets default options (clispb.dat) in */ /* dbcarea by calling DBCHINI() */ /***************************************************************/ initialize_dbcarea() { Int32 result; dbc.total_len = sizeof(struct DBCAREA); DBCHINI(&result,cnta,&dbc); if (result != EM_OK) { /* if we can't initialize, we can't go on, so exit */ printf("init failed -- %s\n", dbc.msg_text); exitout(NOT_CONNECTED); } return(0); } /**end initialize_dbcarea**/ /***************************************************************/ /* LOGON_TO_DBC -- Connects session and logs on to DBC */ /* Fetches result of connection to check if */ /* successful */ /***************************************************************/ logon_to_dbc(char * logonstr) { struct CliCONNECTType connectstr; Int32 result, i; char TempString[30]; for (i = 0; i < 30; i++) TempString[i] = ' '; for (i = 0; i < 30; i++) { if (logonstr[i] == '/') { TempString[i] = '\0'; break; } TempString[i] = logonstr[i]; } printf("Logging on to %s ...\n", TempString); dbc.logon_ptr = logonstr; dbc.logon_len = strlen(logonstr); dbc.func = DBFCON; dbc.run_ptr = (char *) &connectstr; strncpy(connectstr.PartitionName, "MONITOR ", 16); connectstr.Function = 0; dbc.run_len = sizeof(struct CliCONNECTType); DBCHCL(&result,cnta,&dbc); if (result != EM_OK) /*if connect fails exit*/ { printf("connect failed -- %s\n",dbc.msg_text); exitout(NOT_CONNECTED); } printf("Logon successful.\n"); return(0); } /**end logon_to_dbc**/ /***************************************************************/ /* CLOSE_REQUEST -- Terminates and cleans up specified request */ /***************************************************************/ close_request(Int32 req_id, Int32 sess_id) { Int32 result; dbc.i_sess_id = sess_id; dbc.i_req_id = req_id; dbc.func=DBFERQ; DBCHCL(&result,cnta,&dbc); if (result !=EM_OK) { printf("end request failed -- %s\n", dbc.msg_text); exitout(CONNECTED); } return(0); } /**end close_request**/ /***************************************************************/ /* OPEN_REQUEST -- Sends request to DBC */ /***************************************************************/ open_request (int InReqType, void *UsingPtr) { Int32 result; char CurrRequestText[32]; /* set up for a new request */ dbc.func = DBFIRQ; dbc.using_data_ptr = (char *) UsingPtr; switch (InReqType) { case MON_SESS_REQ: strcpy(CurrRequestText,"MONITOR SESSION;"); dbc.using_data_len = sizeof(monsess_t); break; default: printf("Internal error\n"); exitout(CONNECTED); } dbc.req_ptr = &CurrRequestText[0]; dbc.req_len = strlen (CurrRequestText); printf ("\nSubmitting request %s ...\n", dbc.req_ptr); /* Submit request */ DBCHCL (&result,cnta,&dbc); if (result != EM_OK) { printf ("result = %d \n", result); printf ("initiate request failed -- %s \n", dbc.msg_text); exitout(CONNECTED); } return(EM_OK); } /**end open_request**/ int fetch_request(Int32 request, Int32 session) { int status; int StatementNo = 0; int ActivityType = 0; int ActivityCount = 0; Int32 result; int ReturnCode; dbc.i_sess_id = session; dbc.i_req_id = request; dbc.func = DBFFET; status = OK; ReturnCode = OK; /* fetch one parcel at a time until all parcels are used up */ /* or an error occurs */ while (status == OK) { DBCHCL(&result,cnta,&dbc); if (result == REQEXHAUST) status = STOP; else if (result != EM_OK) status = NOT_OK; else { switch ((Int16) (dbc.fet_parcel_flavor)) { case PCLSUCCESS : /*Success Parcel */ { struct PclSUCCESSType succ; memcpy(&succ,dbc.fet_data_ptr-4,4); memcpy(&succ,dbc.fet_data_ptr-4,succ.Length+4); StatementNo = succ.StatementNo; ActivityCount = *(int *)(&succ.ActivityCount[0]); ActivityType = succ.ActivityType; if ( succ.WarningLength > 0 ) printf("%s \n", succ.WarningMsg); CheckSuccess(ActivityType, ActivityCount, StatementNo); } break; case PclDATAINFO : CheckData(ActivityType, StatementNo); break; case PclRECORD : /*Returned data */ CheckRecord(ActivityType, StatementNo, ActivityCount); break; case PclFAILURE : /*Failure parcel*/ case PclERROR : /*Error parcel */ status = STOP; Write_error(dbc.fet_data_ptr); ReturnCode = PclERROR; break; } /*switch*/ } } /*while*/ if (status == NOT_OK) { printf("fetch failed -- %s \n", dbc.msg_text); exitout(CONNECTED); } /*if*/ return(ReturnCode); } /**end fetch_request**/ static Boolean MonSession() { monsess_t MonSess; int i; char InString[MAXNAME]; /* Initializations */ MonSess.monheader.version = TargetVersion; MonSess.monheader.indicbyte = '\0'; for (i = 0; i < MAXNAME; i++) monsess.user[i] = ' '; printf("Enter logical hostid (* for all hosts) or Q)uit: "); gets(InString); if (!strcmp(InString, "*") || (strlen(InString) == 0)) MonSess.hostid = (Int16) 65535; else if (!strcmp(InString, "Q") || !strcmp(InString, "q")) return (TRUE); else MonSess.hostid = atoi(InString); printf("Enter user name (* for all users): "); gets(InString); if (!strcmp(InString, "*") || (strlen(InString) == 0)) { for (i = 0; i < MAXNAME; i++) { if (InString[i] == '\0') break; MonSess.user[i] = InString[i]; } } printf("Enter session number (* for all sessions): "); gets(InString); if (!strcmp(InString, "*") || (strlen(InString) == 0)) MonSess.session = 0; else MonSess.session = atoi(InString); if (RespMode == 'I' || RespMode == 'i') { dbc.resp_mode = 'I'; IndicatorMode = TRUE; } else { dbc.resp_mode = 'R'; IndicatorMode = FALSE; } open_request( MON_SESS_REQ,&MonSess); fetch_request(dbc.o_req_id, dbc.o_sess_id); close_request(dbc.o_req_id, dbc.o_sess_id); return (FALSE); } main (int argc, char **argv) { char LogonString[MAXLOGONSIZE]; Boolean stop = FALSE; initialize_dbcarea(); set_options(); //6: Teradata 12.x; 5: Teradata 6.x 4: Teradata 5.x TargetVersion = 6; // 'R' no presence bits returned; 'I' presence bits returned RespMode = 'I'; IndicatorMode = TRUE; printf ("TargetVersion(argv1) = %d, RespMode(argv2) = %c \n\n", TargetVersion, RespMode); /* Establish session */ printf ("Enter logon string (tdpid/user,password): "); gets (LogonString); if (strlen(LogonString) == 0) { printf ("NULL logon string not accepted.\n"); return (1); } logon_to_dbc(LogonString); if (fetch_request(dbc.o_req_id,dbc.o_sess_id) != OK) exitout(NOT_CONNECTED); close_request(dbc.o_req_id,dbc.o_sess_id); while (stop == FALSE) stop = MonSession(); /* Logoff and cleanup */ exitout(CONNECTED); return 0; } /**end main**/