#pragma module ADC_MSGCODEC "ADC_MSGCODEC-1-X" #define __MODULE__ "ADC_MSGCODEC" /* **++ ** FACILITY: StarLet Advanced Direct Connection for OpenVMS ** ** MODULE DESCRIPTION: ** ** This module contains routines to parses (decode) incoming ADC' Message, ** to encode outgoing messages. ** ** AUTHORS: ** ** Ruslan R. Laishev ** ** CREATION DATE: 9-JUL-2009 ** ** ** [@optional module tags@]... ** ** MODIFICATION HISTORY: ** ** {@tbs@}... **-- */ /* ** ** INCLUDE FILES ** */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "md5.h" #define __NEW_STARLET 1 #include #include "adcdef.h" #include "adc_msg.h" #include "macros.h" #define $ascic(a) sizeof(a)-1,(a) /* extern ADC_CONF conf; */ /* ** ** LIB$TPARSE stuff ** */ extern char UFD_STATE, UFD_KEY; struct tp_block { struct tpadef tpb; ADC_MSG * msg; }; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** An action routine called from LIB$TPARSE routine when a ADC message id ** has been recognized. Allocate a memory for new message, set message method/type, ** store in the tblock a pointer to current processed message. ** ** FORMAL PARAMETERS: ** ** tblock: A pointer to the TPARSE block ** ** RETURN VALUE: ** ** VMS condition code ** **-- */ int _adc_setmt ( struct tp_block *tblock ) { int status; /* ** Allocate new ADC message/request */ if ( !(1 & (status = _adc_getvm(&tblock->msg,sizeof(ADC_MSG)))) ) return status; /* ** Set ADC Method (Message Type) */ tblock->msg->msg$b_mt = (unsigned char) tblock->tpb.tpa$l_param; return SS$_NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** An action routine called from LIB$TPARSE routine when a ADC command/action ** has been recognized. ** ** FORMAL PARAMETERS: ** ** tblock: A pointer to the TPARSE block ** ** RETURN VALUE: ** ** VMS condition code ** **-- */ int _adc_setact ( struct tp_block *tblock ) { int status; if ( !tblock->msg ) return LIB$_SYNTAXERR; /* ** Set ADC Method (Message Type) */ tblock->msg->msg$b_act = (unsigned char) tblock->tpb.tpa$l_param; return SS$_NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** An action routine called from LIB$TPARSE routine when a ADC command/action ** has been recognized. ** ** FORMAL PARAMETERS: ** ** tblock: A pointer to the TPARSE block ** ** RETURN VALUE: ** ** VMS condition code ** **-- */ int _adc_addopt ( struct tp_block *tblock ) { int status; if ( !tblock->msg ) return LIB$_SYNTAXERR; /* ** Set ADC Method (Message Type) */ tblock->msg->msg$l_opts |= tblock->tpb.tpa$l_param; return SS$_NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** An action routine called from LIB$TPARSE routine when a ADC command/action ** has been recognized. ** ** FORMAL PARAMETERS: ** ** tblock: A pointer to the TPARSE block ** ** RETURN VALUE: ** ** VMS condition code ** **-- */ int _adc_remopt ( struct tp_block *tblock ) { int status; if ( !tblock->msg ) return LIB$_SYNTAXERR; /* ** Set ADC Method (Message Type) */ tblock->msg->msg$l_opts &= (~tblock->tpb.tpa$l_param); return SS$_NORMAL; } int _adc_setinf_int ( struct tp_block *tblock ) { unsigned status,*intp; ADC_INF *inf = &tblock->msg->msg$r_inf; char *cp; struct dsc$descriptor buf_dsc; inf->inf$l_inf |= tblock->tpb.tpa$l_param; switch ( tblock->tpb.tpa$l_param ) { case INF$M_CT: intp = &inf->inf$l_ct; break; case INF$M_DS: intp = &inf->inf$l_ds; break; case INF$M_AS: intp = &inf->inf$l_as; break; case INF$M_AM: intp = &inf->inf$l_am; break; case INF$M_AW: intp = &inf->inf$l_aw; break; case INF$M_SS: inf->inf$q_ss = 0; intp = &inf->inf$q_ss; break; case INF$M_SF: intp = &inf->inf$l_sf; break; case INF$M_SL: intp = &inf->inf$l_sl; break; case INF$M_HN: intp = &inf->inf$l_hn; break; case INF$M_HR: intp = &inf->inf$l_hr; break; case INF$M_HO: intp = &inf->inf$l_ho; break; case INF$M_U4: intp = &inf->inf$l_u4; break; case INF$M_U6: intp = &inf->inf$l_u6; break; case INF$M_US: intp = &inf->inf$l_us; break; default: return SS$_ABORT; } if ( cp = memchr(tblock->tpb.tpa$l_stringptr,' ',tblock->tpb.tpa$l_stringcnt) ) status = cp - tblock->tpb.tpa$l_stringptr; else status = tblock->tpb.tpa$l_stringcnt; if ( (status > 10) && (tblock->tpb.tpa$l_param == INF$M_SS) ) { INIT_SDESC(buf_dsc,status,tblock->tpb.tpa$l_stringptr); if ( !(1 & (status = ots$cvt_tu_l(&buf_dsc,intp,sizeof(__int64),0))) ) lib$signal(status); } else lib$cvt_dtb(status,tblock->tpb.tpa$l_stringptr,intp); /* ** Jump to end of arguments */ tblock->tpb.tpa$l_stringptr += status; tblock->tpb.tpa$l_stringcnt -= status; return SS$_NORMAL; } int _adc_setinf_ip ( struct tp_block *tblock ) { int status, *intp; char *cp; ADC_INF *inf = &tblock->msg->msg$r_inf; inf->inf$l_inf |= tblock->tpb.tpa$l_param; switch ( tblock->tpb.tpa$l_param ) { case INF$M_I4: intp = &inf->inf$l_i4; break; case INF$M_I6: intp = &inf->inf$q_i6; break; default: return SS$_ABORT; } if ( cp = memchr(tblock->tpb.tpa$l_stringptr,' ',tblock->tpb.tpa$l_stringcnt) ) status = cp - tblock->tpb.tpa$l_stringptr; else status = tblock->tpb.tpa$l_stringcnt; inet_aton(tblock->tpb.tpa$l_stringptr, (struct in_addr *) intp); /* ** Jump to end of arguments */ tblock->tpb.tpa$l_stringptr += status; tblock->tpb.tpa$l_stringcnt -= status; return SS$_NORMAL; } int _adc_setinf_str ( struct tp_block *tblock ) { int status; ADC_INF *inf = &tblock->msg->msg$r_inf; ASC *asc; char *cp; inf->inf$l_inf |= tblock->tpb.tpa$l_param; switch ( tblock->tpb.tpa$l_param ) { case INF$M_ID: asc = &inf->inf$r_id; break; case INF$M_PD: asc = &inf->inf$r_pd; break; case INF$M_VE: asc = &inf->inf$r_ve; break; case INF$M_EM: asc = &inf->inf$r_em; break; case INF$M_NI: asc = &inf->inf$r_ni; break; case INF$M_DE: asc = &inf->inf$r_de; break; case INF$M_TO: asc = &inf->inf$r_to; break; case INF$M_SU: asc = &inf->inf$r_su; break; case INF$M_RF: asc = &inf->inf$r_rf; break; default: return SS$_ABORT; } if ( cp = memchr(tblock->tpb.tpa$l_stringptr,' ',tblock->tpb.tpa$l_stringcnt) ) asc->asc_b_asc = (unsigned char) (cp - tblock->tpb.tpa$l_stringptr); else asc->asc_b_asc = (unsigned char) tblock->tpb.tpa$l_stringcnt; asc->asc_b_asc = $min(asc->asc_b_asc,sizeof(asc->asc_t_asc)); memcpy(asc->asc_t_asc,tblock->tpb.tpa$l_stringptr,asc->asc_b_asc); /* ** Jump to end of arguments */ tblock->tpb.tpa$l_stringptr += asc->asc_b_asc; tblock->tpb.tpa$l_stringcnt -= asc->asc_b_asc; return SS$_NORMAL; } extern char ufd_state, ufd_key; int _adc_decode ( ADC_MSG * * msg, char * buf, unsigned short buflen ) { int status,bodylen = 0; struct tp_block tblock = {{TPA$K_COUNT0}}; /* ** Don't try to parse zero-length message */ if ( !buflen ) return SS$_NORMAL; *msg = NULL; tblock.tpb.tpa$l_stringcnt = buflen; tblock.tpb.tpa$l_stringptr = buf; if ( !(1 & (status = lib$table_parse(&tblock,&ufd_state,&ufd_key))) ) { if ( *msg && !(1 & (status = _adc_freevm(*msg,sizeof(ADC_MSG)))) ) lib$signal(status); status = _adc_log(ADC_CANTPARSE,buflen-tblock.tpb.tpa$l_stringcnt,buf); } else *msg = tblock.msg; return status; } #if 0 char msgbuf [] = "HSUP ADBASE ADTIGR"; int main (void) { int status; ADC_MSG * msg = NULL; status = _adc_decode(&msg,msgbuf,sizeof(msgbuf)-1); lib$signal(SS$_DEBUG); return status; } #endif