|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
ASCII to EBCDIC Conversion |
« View previous topic :: View next topic » |
Author |
Message
|
KramJ |
Posted: Wed Apr 25, 2007 6:27 am Post subject: ASCII to EBCDIC Conversion |
|
|
Voyager
Joined: 09 Jan 2006 Posts: 80 Location: Atlanta
|
We have SDR channels from AIX MQ 5.3 queue managers to MQ 6.0 mainframe queue managers that use message exits to convert ASCII to EBCDIC. The exit was written and implemented a while before I started working here and the previous MQ admin is gone.
Planning to upgrade the AIX queue managers to version 6 I see that the channel exits will need to be converted to 64-bit. I have the source so I can recompile the exit, but I am wondering why the previous admin would use a message exit instead of turning on data conversion on the channel. Is there, or was there, a limitation on data conversion going from AIX to mainframe? The other thing that the exit does is convert the userid to uppercase for RACF. Would this be handled by the channels data conversion? |
|
Back to top |
|
 |
wschutz |
Posted: Wed Apr 25, 2007 7:46 am Post subject: |
|
|
 Jedi Knight
Joined: 02 Jun 2005 Posts: 3316 Location: IBM (retired)
|
Without looking at the source, it'd be hard to say exactly why builtin conversion wasn't used, but I think normally most people simply used the builtin conversion.
Iff you don't have a security exit, MQ will fold the userid to uppercase automatically. _________________ -wayne |
|
Back to top |
|
 |
KramJ |
Posted: Wed Apr 25, 2007 8:29 am Post subject: |
|
|
Voyager
Joined: 09 Jan 2006 Posts: 80 Location: Atlanta
|
Here's the code. It doesn't look like the is a whole lot to it.
/********************************************************************/
/* */
/* Program name: CONVMSG */
/* */
/* Description: MQ exit program to convert ASCII to EBCDIC and */
/* vice versa */
/* */
/********************************************************************/
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <cmqc.h> /* For MQI datatypes */
#include <cmqxc.h> /* For MQI exit-related definitions */
/*
convert EBCDIC to ASCII or vice-versa, "in-place"
etoa x'00' will convert to x'20'
*/
static char etoa_[256] = {
0040,0001,0002,0003,0234,0011,0206,0177,0227,0215,0216,0013,0014,0015,0016,0017,
0020,0021,0022,0023,0235,0205,0010,0207,0030,0031,0222,0217,0034,0035,0036,0037,
0200,0201,0202,0203,0204,0012,0027,0033,0210,0211,0212,0213,0214,0005,0006,0007,
0220,0221,0026,0223,0224,0225,0226,0004,0230,0231,0232,0233,0024,0025,0236,0032,
0040,0240,0241,0242,0243,0244,0245,0246,0247,0250,0040,0056,0074,0050,0053,0174,
0046,0251,0252,0253,0254,0255,0256,0257,0260,0261,0041,0044,0052,0051,0073,0176,
0055,0057,0262,0263,0264,0265,0266,0267,0270,0271,0313,0054,0045,0137,0076,0077,
0272,0273,0274,0275,0276,0277,0300,0301,0302,0140,0072,0043,0100,0047,0075,0042,
0303,0141,0142,0143,0144,0145,0146,0147,0150,0151,0304,0305,0306,0307,0310,0311,
0312,0152,0153,0154,0155,0156,0157,0160,0161,0162,0136,0314,0315,0316,0317,0320,
0321,0345,0163,0164,0165,0166,0167,0170,0171,0172,0322,0323,0324,0133,0326,0327,
0330,0331,0332,0333,0334,0335,0336,0337,0340,0341,0342,0343,0344,0135,0346,0347,
0173,0101,0102,0103,0104,0105,0106,0107,0110,0111,0350,0351,0352,0353,0354,0355,
0175,0112,0113,0114,0115,0116,0117,0120,0121,0122,0356,0357,0360,0361,0362,0363,
0134,0237,0123,0124,0125,0126,0127,0130,0131,0132,0364,0365,0366,0367,0370,0371,
0060,0061,0062,0063,0064,0065,0066,0067,0070,0071,0372,0373,0374,0375,0376,0377
};
static char atoe_[256] = {
0000,0001,0002,0003,0067,0055,0056,0057,0026,0005,0045,0013,0014,0015,0016,0017,
0020,0021,0022,0023,0074,0075,0062,0046,0030,0031,0077,0047,0034,0035,0036,0037,
0100,0132,0177,0173,0133,0154,0120,0175,0115,0135,0134,0116,0153,0140,0113,0141,
0360,0361,0362,0363,0364,0365,0366,0367,0370,0371,0172,0136,0114,0176,0156,0157,
0174,0301,0302,0303,0304,0305,0306,0307,0310,0311,0321,0322,0323,0324,0325,0326,
0327,0330,0331,0342,0343,0344,0345,0346,0347,0350,0351,0255,0340,0275,0232,0155,
0171,0201,0202,0203,0204,0205,0206,0207,0210,0211,0221,0222,0223,0224,0225,0226,
0227,0230,0231,0242,0243,0244,0245,0246,0247,0250,0251,0300,0117,0320,0137,0007,
0040,0041,0042,0043,0044,0025,0006,0027,0050,0051,0052,0053,0054,0011,0012,0033,
0060,0061,0032,0063,0064,0065,0066,0010,0070,0071,0072,0073,0004,0024,0076,0341,
0101,0102,0103,0104,0105,0106,0107,0110,0111,0121,0122,0123,0124,0125,0126,0127,
0130,0131,0142,0143,0144,0145,0146,0147,0150,0151,0160,0161,0162,0163,0164,0165,
0166,0167,0170,0200,0212,0213,0214,0215,0216,0217,0220,0152,0233,0234,0235,0236,
0237,0240,0252,0253,0254,0112,0256,0257,0260,0261,0262,0263,0264,0265,0266,0267,
0270,0271,0272,0273,0274,0241,0276,0277,0312,0313,0314,0315,0316,0317,0332,0333,
0334,0335,0336,0337,0352,0353,0354,0355,0356,0357,0372,0373,0374,0375,0376,0377
};
char *cvtea(s, len, tbl)
char *s;
long len;
char *tbl;
{
int i;
for (i = 0; i < len; i++)
s[i] = tbl[(int) s[i] & 0xff];
return(s);
}
#define etoa(e,len) cvtea(e, len, etoa_)
#define atoe(a,len) cvtea(a, len, atoe_)
#define CCS_ASCII_1 850L
#define CCS_ASCII_2 819L
#define CCS_EBCDIC 500L
/********************************************************************/
/* Insert the functions prototypes */
/********************************************************************/
/* MQCHANNELEXIT AscEbcCvt; */
/********************************************************************/
/* The name of the function is not actually used to call the */
/* conversion exit BUT it must be marked as the entry point using */
/* the -e option during linking. */
/********************************************************************/
void MQStart ( void ) { ; }
void cvttolc (char *, long);
void cvttouc (char *, long);
void MQENTRY AscEbcCvt(
PMQCXP pChannelExitParms, /* Channel exit parameter block */
PMQCD pChannelDefinition, /* Channel definition */
PMQLONG pDataLength, /* Length of data */
PMQLONG pAgentBufferLength, /* Length of agent buffer */
PMQBYTE pAgentBuffer, /* Agent buffer */
PMQLONG pExitBufferLength, /* Length of exit buffer */
PMQPTR pExitBufferAddr) /* Address of exit buffer */
{
PMQCXP pChannelExitParmBlk = (PMQCXP)pChannelExitParms;
PMQXQH pTransQueueHdr;
PMQBYTE pData;
MQLONG DataLength;
PMQMD pMsgDesc;
if (pChannelExitParmBlk->ExitId == MQXT_CHANNEL_MSG_EXIT ) {
if (pChannelExitParmBlk->ExitReason == MQXR_MSG) {
/********************************************************************/
/* If the length of the actual data (not counting the MQXQH) */
/* is not greater than zero then do nothing */
/********************************************************************/
pTransQueueHdr = (PMQXQH)pAgentBuffer;
pData = (PMQBYTE)pAgentBuffer + sizeof(MQXQH);
DataLength = (MQLONG)*pDataLength - sizeof(MQXQH);
pMsgDesc = (PMQMD)&(pTransQueueHdr->MsgDesc);
/* set the feedback code to none for caller... */
pChannelExitParmBlk->Feedback = MQFB_NONE;
/* if we are going to an EBCDIC machine, convert userid to upper */
/* case for RACF... */
if (!strncmp(pChannelExitParmBlk->ExitData,"EBCDIC",6)) {
cvttouc(pMsgDesc->UserIdentifier,MQ_USER_ID_LENGTH);
} /* endif */
/* if we are going to an ASCII machine, convert userid to lower */
/* case for UNIX security... */
if (!strncmp(pChannelExitParmBlk->ExitData,"ASCII",5)) {
cvttolc(pMsgDesc->UserIdentifier,MQ_USER_ID_LENGTH);
} /* endif */
/* if there is data in the buffer, and it is in a codeset that we */
/* can convert, have at it!... */
if (DataLength > 0) {
/* if (!strncmp(pMsgDesc->Format,MQFMT_ADMIN, */
/* sizeof(pMsgDesc->Format)) || */
if (!strncmp(pMsgDesc->Format,MQFMT_STRING,
sizeof(pMsgDesc->Format)) ||
!strncmp(pMsgDesc->Format,MQFMT_COMMAND_1,
sizeof(pMsgDesc->Format)) ||
!strncmp(pMsgDesc->Format,MQFMT_COMMAND_2,
sizeof(pMsgDesc->Format))
) {
if (!strncmp(pChannelExitParmBlk->ExitData,"EBCDIC",6) &&
( pMsgDesc->CodedCharSetId == CCS_ASCII_1 ||
pMsgDesc->CodedCharSetId == CCS_ASCII_2)) {
atoe(pData,DataLength);
pMsgDesc->CodedCharSetId = CCS_EBCDIC;
} /* endif */
if (!strncmp(pChannelExitParmBlk->ExitData,"ASCII",5) &&
pMsgDesc->CodedCharSetId == CCS_EBCDIC) {
etoa(pData,DataLength);
pMsgDesc->CodedCharSetId = CCS_ASCII_1;
} /* endif */
} /* endif */
} else {
pChannelExitParmBlk->ExitResponse = MQXCC_SUPPRESS_FUNCTION;
pChannelExitParmBlk->Feedback = MQFB_STOPPED_BY_MSG_EXIT;
} /* endif */
} /* endif */
/* set a nice return code for the caller... */
pChannelExitParmBlk->ExitResponse = MQXCC_OK;
} /* endif */
return;
}
/* Convert to Upper Case */
void cvttouc(char * str, long len)
{
int i;
for (i = 0; i < len; i++)
{
*str = toupper(*str);
str++;
}
}
/* Convert to Lower Case */
void cvttolc(char * str, long len)
{
int i;
for (i = 0; i < len; i++)
{
*str = tolower(*str);
str++;
}
}
/********************************************************************/
/********************************************************************/
/* */
/* END OF CONVMSG */
/* */
/********************************************************************/
Does it look like it is doing anything that the builtin conversion wouldn't do? |
|
Back to top |
|
 |
bruce2359 |
Posted: Wed Apr 25, 2007 5:00 pm Post subject: |
|
|
Guest
|
"I am wondering why the previous admin would use a message exit instead of turning on data conversion on the channel"
Possible reasons for the message exit method: a non-supported code-page (coded character set id); or there's something unique (not conforming to an existing code-pate) about the data that conversion via channel attribute or MQGET with Convert could not accomplish.
Lacking any documentation about why this method was used, or access to the sysadmin that implemented it to explain why, your next step is to check the tables in your/his code, character-by-character, to validate that the tables do convert from the Sender qmgrs code-page (CCSID) to the Receiver code-page (CCSID). |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|