157 lines
4.6 KiB
C
157 lines
4.6 KiB
C
|
/****************************************************************
|
||
|
* *
|
||
|
* Copyright 2001, 2010 Fidelity Information Services, Inc *
|
||
|
* *
|
||
|
* This source code contains the intellectual property *
|
||
|
* of its copyright holder(s), and is made available *
|
||
|
* under a license. If you do not know the terms of *
|
||
|
* the license, please stop and do not read further. *
|
||
|
* *
|
||
|
****************************************************************/
|
||
|
#include "mdef.h"
|
||
|
#include "gtm_ctype.h"
|
||
|
#include "gtm_string.h"
|
||
|
#include "cmidef.h"
|
||
|
#include "hashtab_mname.h" /* needed for cmmdef.h */
|
||
|
#include "cmmdef.h"
|
||
|
#include "gtcm_protocol.h"
|
||
|
|
||
|
static char *encode_cpu(void);
|
||
|
static char *encode_os(void);
|
||
|
|
||
|
LITDEF gtcm_proto_cpu_info_t gtcm_proto_cpu_info[] =
|
||
|
{
|
||
|
LIT_AND_LEN("IA64"), "IA64",
|
||
|
LIT_AND_LEN("RS6000"), "PPC",
|
||
|
LIT_AND_LEN("AXP"), "AXP",
|
||
|
LIT_AND_LEN("HP-PA"), "PAR",
|
||
|
LIT_AND_LEN("x86"), "X86",
|
||
|
LIT_AND_LEN("x86_64"), "X86_64",
|
||
|
LIT_AND_LEN("S390"), "390",
|
||
|
LIT_AND_LEN("S390X"), "390",
|
||
|
LIT_AND_LEN("SPARC"), "SPA",
|
||
|
LIT_AND_LEN("VAX"), "VAX",
|
||
|
LIT_AND_LEN(GTCM_PROTO_BAD_CPU), GTCM_PROTO_BAD_CPU
|
||
|
};
|
||
|
|
||
|
LITDEF gtcm_proto_os_info_t gtcm_proto_os_info[] =
|
||
|
{
|
||
|
LIT_AND_LEN("AIX"), "AIX",
|
||
|
LIT_AND_LEN("OSF1"), "OSF",
|
||
|
LIT_AND_LEN("HP-UX"), "HPX",
|
||
|
LIT_AND_LEN("Linux"), "LNX",
|
||
|
LIT_AND_LEN("OS390"), "zOS",
|
||
|
LIT_AND_LEN("Solaris"), "SOL",
|
||
|
LIT_AND_LEN("VMS"), "VMS",
|
||
|
LIT_AND_LEN(GTCM_PROTO_BAD_OS), GTCM_PROTO_BAD_OS
|
||
|
};
|
||
|
|
||
|
LITREF char gtm_release_name[];
|
||
|
LITREF int4 gtm_release_name_len;
|
||
|
LITREF char gtm_version[];
|
||
|
LITREF char cm_ver_name[];
|
||
|
LITREF int4 cm_ver_len;
|
||
|
|
||
|
static int proto_built = FALSE;
|
||
|
static protocol_msg proto;
|
||
|
|
||
|
void gtcm_protocol(protocol_msg *pro)
|
||
|
{
|
||
|
if (!proto_built)
|
||
|
{
|
||
|
memcpy(proto.msg + CM_CPU_OFFSET, encode_cpu(), 3);
|
||
|
memcpy(proto.msg + CM_OS_OFFSET, encode_os(), 3);
|
||
|
memcpy(proto.msg + CM_IMPLEMENTATION_OFFSET, "GTM", 3);
|
||
|
/* gtm_version is of the form Vi.j where i and j are digits */
|
||
|
assert('V' == gtm_version[0] && ISDIGIT_ASCII(gtm_version[1]) && '.' == gtm_version[2]
|
||
|
&& ISDIGIT_ASCII(gtm_version[3]));
|
||
|
proto.msg[CM_VERSION_OFFSET] = '0';
|
||
|
proto.msg[CM_VERSION_OFFSET + 1] = gtm_version[1];
|
||
|
proto.msg[CM_VERSION_OFFSET + 2] = gtm_version[3];
|
||
|
memcpy(proto.msg + CM_TYPE_OFFSET, CMM_PROTOCOL_TYPE, 3);
|
||
|
/* cm_ver_name is of the form Vijk where i, j, and k are digits */
|
||
|
assert('V' == cm_ver_name[0] && ISDIGIT_ASCII(cm_ver_name[1]) && ISDIGIT_ASCII(cm_ver_name[2])
|
||
|
&& ISDIGIT_ASCII(cm_ver_name[3]));
|
||
|
memcpy(proto.msg + CM_LEVEL_OFFSET, &cm_ver_name[1], 3);
|
||
|
#ifdef BIGENDIAN
|
||
|
proto.msg[CM_ENDIAN_OFFSET] = GTCM_BIG_ENDIAN_INDICATOR;
|
||
|
#else
|
||
|
proto.msg[CM_ENDIAN_OFFSET] = ' ';
|
||
|
#endif
|
||
|
memset(proto.msg + CM_ENDIAN_OFFSET + 1, ' ' , CM_FILLER_SIZE);
|
||
|
proto_built = TRUE;
|
||
|
}
|
||
|
memcpy(pro->msg, proto.msg, S_PROTSIZE);
|
||
|
/* memcpy(pro->msg, S_PROTOCOL, S_PROTSIZE); */
|
||
|
}
|
||
|
|
||
|
boolean_t gtcm_is_big_endian(protocol_msg *pro)
|
||
|
{
|
||
|
return pro->msg[CM_ENDIAN_OFFSET] == GTCM_BIG_ENDIAN_INDICATOR;
|
||
|
}
|
||
|
|
||
|
boolean_t gtcm_protocol_match(protocol_msg *peer, protocol_msg *me)
|
||
|
{
|
||
|
if (memcmp(peer->msg + CM_TYPE_OFFSET, me->msg + CM_TYPE_OFFSET, 3))
|
||
|
return FALSE;
|
||
|
assert(0 <= memcmp(me->msg, CMM_MIN_PEER_LEVEL, 3));
|
||
|
if (0 > memcmp(peer->msg + CM_LEVEL_OFFSET, me->msg + CM_LEVEL_OFFSET, 3) && /* peer running older version of GNP */
|
||
|
0 > memcmp(peer->msg + CM_LEVEL_OFFSET, CMM_MIN_PEER_LEVEL, 3)) /* older than the oldest supported version with */
|
||
|
return FALSE; /* our version */
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
static char *encode_cpu()
|
||
|
{
|
||
|
unsigned char *p;
|
||
|
int count, cpuidx;
|
||
|
|
||
|
count = 0;
|
||
|
p = (unsigned char *)gtm_release_name;
|
||
|
/* fourth arg in release name string */
|
||
|
while (*p && count < 3)
|
||
|
{
|
||
|
if (*p == ' ')
|
||
|
count++;
|
||
|
p++;
|
||
|
}
|
||
|
if (count == 3)
|
||
|
{
|
||
|
for (cpuidx = 0; cpuidx < SIZEOF(gtcm_proto_cpu_info)/SIZEOF(gtcm_proto_cpu_info_t) - 1; cpuidx++)
|
||
|
{
|
||
|
if (0 == memcmp(p, gtcm_proto_cpu_info[cpuidx].cpu_in_rel_str,
|
||
|
gtcm_proto_cpu_info[cpuidx].size_of_cpu_in_rel_str))
|
||
|
return gtcm_proto_cpu_info[cpuidx].proto_cpu;
|
||
|
}
|
||
|
}
|
||
|
GTMASSERT;
|
||
|
return NULL; /* Added to make compiler happy and not throw warning */
|
||
|
}
|
||
|
|
||
|
static char *encode_os()
|
||
|
{
|
||
|
unsigned char *p;
|
||
|
int count, osidx;
|
||
|
|
||
|
count = 0;
|
||
|
p = (unsigned char *)gtm_release_name;
|
||
|
/* third arg in release name string */
|
||
|
while (*p && count < 2)
|
||
|
{
|
||
|
if (*p == ' ')
|
||
|
count++;
|
||
|
p++;
|
||
|
}
|
||
|
if (count == 2)
|
||
|
{
|
||
|
for (osidx = 0; osidx < SIZEOF(gtcm_proto_os_info)/SIZEOF(gtcm_proto_os_info_t) - 1; osidx++)
|
||
|
{
|
||
|
if (0 == memcmp(p, gtcm_proto_os_info[osidx].os_in_rel_str,
|
||
|
gtcm_proto_os_info[osidx].size_of_os_in_rel_str))
|
||
|
return gtcm_proto_os_info[osidx].proto_os;
|
||
|
}
|
||
|
}
|
||
|
GTMASSERT;
|
||
|
return NULL; /* Added to make compiler happy and not throw warning */
|
||
|
}
|