#pragma module ADC_UTILS "ADC_UTILS-1-X" /* **++ ** FACILITY: ** ** MODULE DESCRIPTION: ** This module contains utility routines used by the server. ** ** ** AUTHORS: ** ** Ruslan R. Laishev ** ** CREATION DATE: 9-JUL-2009 ** ** DESIGN ISSUES: ** ** ** MODIFICATION HISTORY: ** ** {@tbs@}... **-- */ /* ** ** INCLUDE FILES ** */ #include #include #include #include #include #include #include #include #include #include #include #include #define __NEW_STARLET 1 #include #include #include #include #include /* ** ** ADC DEFINITONS ** */ #include "adcdef.h" #include "macros.h" $DESCRIPTOR(VMZoneName_ADCMSG, "ADC messages"); $DESCRIPTOR(VMZoneName_ADCCTX, "ADC sessions contexts"); $DESCRIPTOR(VMZoneName_BUF, "ICHC Buffers"); int VMZoneDetail=3, VMZoneId_ADCMSG = 0, VMZoneId_ADCCTX = 0, VMZoneId_BUF = 0; /* ** National Character Set conversion stuff */ int cfenc = 0,cfdec = 0; $DESCRIPTOR(cfenc_dsc, "ADC_ENC"); $DESCRIPTOR(cfdec_dsc, "ADC_DEC"); $DESCRIPTOR(ncslib_dsc, "ADC_DIR:ADC_NCS.NLB"); int __adc_enc ( struct dsc$descriptor * inp, struct dsc$descriptor * out ) { int status; if ( !cfenc && !(1 & (status = ncs$get_cf(&cfenc,&cfenc_dsc,&ncslib_dsc))) ) lib$signal(status); return ncs$convert(&cfenc,inp,out,&out->dsc$w_length); } int __adc_dec ( struct dsc$descriptor * inp, struct dsc$descriptor * out ) { int status; if ( !cfdec && !(1 & (status = ncs$get_cf(&cfdec,&cfdec_dsc,&ncslib_dsc))) ) lib$signal(status); return ncs$convert(&cfdec,inp,out,&out->dsc$w_length); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Put formated message to standard output device (SYS$OUTPUT). ** ** FORMAL PARAMETERS: ** ** ctx: A session context ** msgid: VMS condition code ** variable agriments list ** ** RETURN VALUE: ** ** VMS condition code ** ** **-- */ int _adc_log ( int msgid, ... ) { long status,retvalue = msgid; va_list ap; char buf[4096] = {"!%D "},outadr[4],msg_buf[4096]; struct dsc$descriptor opr_dsc,buf_dsc,fao_dsc; int argc,argl[32],idx,flag=15,lvl; /* ** Get a message text with given msgid */ INIT_SDESC(fao_dsc,sizeof(buf)-4,&buf[4]); if ( !(1 & (status = sys$getmsg (msgid,&fao_dsc.dsc$w_length,&fao_dsc,flag,&outadr))) ) lib$signal(status); /* ** Reorganize parameters list for $FAOL */ va_start(ap,msgid); argl[0] = 0; for (idx = 1,va_count(argc);idx < argc;idx++) argl[idx] = va_arg(ap,unsigned); va_end((void *) msgid); /* ** Format a message, put it to SYS$OUTPUT */ fao_dsc.dsc$a_pointer -=4; fao_dsc.dsc$w_length +=4; INIT_SDESC(buf_dsc, sizeof(msg_buf),msg_buf); if ( !(1 & (status = sys$faol(&fao_dsc,&buf_dsc.dsc$w_length,&buf_dsc,argl))) ) lib$signal(status); lib$put_output(&buf_dsc); return retvalue; } int _adc_getvm ( void * * adr, unsigned sz ) { int status = SS$_NORMAL; static int VMZoneAlg = LIB$K_VM_FIXED, VMZoneFlags = LIB$M_VM_EXTEND_AREA | LIB$M_VM_GET_FILL0, VMZoneAlign = 16; int VMZoneBlockSz = 0,*VMZid = NULL; struct dsc$descriptor *VMZname = NULL; switch (sz) { case sizeof(ADC_MSG): VMZid = &VMZoneId_ADCMSG; VMZname = &VMZoneName_ADCMSG; break; case sizeof(ADC_CTX): VMZid = &VMZoneId_ADCCTX; VMZname = &VMZoneName_ADCCTX; break; case sizeof(ICHC_BUF): VMZid = &VMZoneId_BUF; VMZname = &VMZoneName_BUF; break; default: lib$signal(SS$_DEBUG); } VMZoneBlockSz = sz*32; /* ** At first call initalize the Expression VM Zone ** LIB$CREATE_VM_ZONE zone-id [,algorithm] [,algorithm-argument] [,flags] ** [,extend-size] [,initial-size] [,block-size] [,alignment] ** [,page-limit] [,smallest-block-size] [,zone-name] [,get-page] [,free-page] */ /* if ( !(*VMZid) && !(1 & (status = lib$create_vm_zone(VMZid, &VMZoneAlg,&VMZoneAlign,&VMZoneFlags, &VMZoneBlockSz,&VMZoneBlockSz,&sz,&VMZoneAlign, 0,0,VMZname,0,0))) ) lib$signal(SS$_DEBUG); */ if ( !(*VMZid) && !(1 & (status = lib$create_vm_zone(VMZid, &VMZoneAlg,&sz,&VMZoneFlags))) ) lib$signal(status); /* ** Allocate a memory */ if ( !(1 & (status = lib$get_vm(&sz,adr,VMZid))) ) { lib$show_vm_zone(VMZid,&VMZoneDetail); lib$signal(status); } return status; } int _adc_freevm ( void * adr, unsigned sz ) { int status,*VMZid = NULL; if ( !adr ) return SS$_NORMAL; switch (sz) { case sizeof(ADC_MSG): VMZid = &VMZoneId_ADCMSG; break; case sizeof(ADC_CTX): VMZid = &VMZoneId_ADCCTX; break; case sizeof(ICHC_BUF): VMZid = &VMZoneId_BUF; break; default: lib$signal(SS$_DEBUG); } if ( !(1 & (status = lib$free_vm(&sz,&adr,VMZid))) ) lib$signal(status); return status; } int _adc_vmfreemsg ( ADC_MSG * msg ) { int status; if ( !msg ) return SS$_NORMAL; return _adc_freevm(msg,sizeof(ADC_MSG)); } void hex2bin ( unsigned char * src, unsigned char * dst, unsigned short dstsz ) { char c = 0; for(;dstsz;dstsz--,src++) { if ( isdigit(*src) ) c = *src - '0'; else if ( isupper(*src) ) c = *src - 'A' + 10; else c = *src - 'a' + 10; if ( dstsz & 1 ) *(dst++)|= c; else *dst = c<<4 ; } } void bin2hex ( unsigned char * src, unsigned char * dst, unsigned short dstsz ) { char l,h; for(;dstsz;dstsz--,src += 2,dst++) { h = (*dst) >>4; l = (*dst) & 0x0F; *src = (h < 10)?h + '0':h + 'a' - 10; *(src+1)= (l < 10)?l + '0':l + 'a' - 10; } } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Put formated message to standard output device (SYS$OUTPUT). ** ** FORMAL PARAMETERS: ** ** ctx: A session context ** faos: A string with FAO directive ** ...: A variable argument list ** ** **-- */ const char _fao[2][64] = { {"!%D %ADC-I-TRACE, "}, {"!%D %ADC-I-TRACE [SID:!XW !AC:!UW NI:!AC], "}}; void _adc_trace ( ADC_CTX * ctx, char * faos, ... ) { int status,argc,argl[32] = {0,0,0,0,0},idx; va_list ap; char buf[4096],fao[255]; struct dsc$descriptor buf_dsc,fao_dsc; ADC_INF *inf = &ctx->ctx$r_inf; /* ** Get a message text with given msgid */ memset(argl,0,sizeof(argl)); status = strnlen(faos,128); if ( ctx ) { memcpy(&fao,_fao[1],43); memcpy(&fao[43],faos,status); INIT_SDESC(fao_dsc,status + 43,fao); argl[1] = ctx->ctx$v_sid; argl[2] = &ctx->ctx$r_addr; argl[3] = ctx->ctx$w_port; argl[4] = &inf->inf$r_ni; } else { memcpy(&fao,_fao[0],18); memcpy(&fao[18],faos,status); INIT_SDESC(fao_dsc,status + 18,fao); } /* ** Reorganize parameters list for $FAOL */ va_start(ap,faos); va_count(argc); argc -= 2; for (idx = 0,va_count(argc); idx < argc; idx++) argl[(ctx?5:1)+idx] = va_arg(ap,unsigned); va_end((void *) faos); /* ** Format a message, put it to SYS$OUTPUT */ INIT_SDESC(buf_dsc, sizeof(buf),buf); if ( !(1 & (status = sys$faol(&fao_dsc,&buf_dsc.dsc$w_length,&buf_dsc,argl))) ) lib$signal(status); lib$put_output(&buf_dsc); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Put formated message to standard output device (SYS$OUTPUT). ** ** FORMAL PARAMETERS: ** ** ctx: A session context ** faos: A string with FAO directive ** ...: A variable argument list ** ** **-- */ unsigned short _adc_format ( char * buf, unsigned short bufsz, char * faos, ... ) { unsigned status,argc,argl[32],idx; unsigned short len = 0; va_list ap; struct dsc$descriptor fao_dsc,buf_dsc; memset(argl,0,sizeof(argl)); status = strnlen(faos,128); INIT_SDESC(fao_dsc,status,faos); /* ** Reorganize parameters list for $FAOL */ va_start(ap,faos); va_count(argc); argc -= 3; for (idx = 0,va_count(argc); idx < argc; idx++) argl[idx] = va_arg(ap,unsigned); va_end((void *) faos); /* ** Format a message, put it to SYS$OUTPUT */ INIT_SDESC(buf_dsc,bufsz,buf); if ( !(1 & (status = sys$faol(&fao_dsc,&len,&buf_dsc,argl))) ) lib$signal(status); return len; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Encode data buffer to Base32 ** ** FORMAL PARAMETERS: ** ** ctx: A session context ** faos: A string with FAO directive ** ...: A variable argument list ** ** **-- */ const unsigned char base32Table[256] = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,26,27,28,29,30,31,-1,-1,-1,-1,-1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; const unsigned char base32Alphabet[32] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '2', '3', '4', '5', '6', '7' }; unsigned short _adc_base32enc ( unsigned char * src, unsigned short srclen, unsigned char * dst ) { unsigned index; unsigned char word = 0; for(int i = 0, index = 0; i < srclen;) { if ( index > 3 ) { word = src[i] & (0xFF >> index); index = (index + 5) % 8; word <<= index; if ((i + 1) < srclen) word |= src[i + 1] >> (8 - index); i++; } else { word = (src[i] >> (8 - (index + 5))) & 0x1F; index = (index + 5) % 8; if ( index == 0 ) i++; } if ( word > 32 ) lib$signal(SS$_BADESCAPE); *(dst++) = base32Alphabet[word]; } return srclen * 8/5 + 1; } unsigned short _adc_base32dec ( unsigned char * src, unsigned short srclen, unsigned char * dst, unsigned short dstlen ) { unsigned index = 0,pos = 0; unsigned char tmp = 0; for(int i = 0; i < srclen; i++) { /* ** Skip what we don't recognise */ if ( -1 == (tmp = base32Table[(unsigned char)src[i]]) ) { lib$signal(SS$_BADESCAPE); continue; } if ( index <= 3 ) { index = (index + 5) % 8; if (index == 0) { dst[pos++] |= tmp; if ( pos == dstlen ) break; } else dst[pos] |= tmp << (8 - index); } else { index = (index + 5) % 8; dst[pos++] |= (tmp >> index); if ( pos == dstlen ) break; dst[pos] |= tmp << (8 - index); } } return pos; } int get_uic ( unsigned char *user, unsigned short userlen, unsigned char *uic, unsigned short uicsz, unsigned short *uiclen ) { int status,uai_flags; __int64 uai_expire_date,lgi_time; UICDEF uai_uic; ILE3 get_itmlst[] = { {4, UAI$_FLAGS, &uai_flags, 0}, {8, UAI$_EXPIRATION, &uai_expire_date,0}, {4, UAI$_UIC, &uai_uic, 0}, {0, 0, 0, 0}}; struct dsc$descriptor dsc,dsc2; char buf[64]; INIT_SDESC(dsc2,userlen,user); INIT_SDESC(dsc,userlen,buf); if ( !(1 & (status = str$upcase(&dsc,&dsc2))) ) lib$signal(status); /* ** Get login time for future checking */ if ( !(1 & (status = sys$gettim(&lgi_time))) ) lib$signal(status); if ( !(1 & (status = sys$getuai(EFN$C_ENF, 0, &dsc, &get_itmlst, 0, 0, 0))) ) return status; if ( uai_flags & UAI$M_DISACNT ) return LGI$_DISUSER; if ( uai_expire_date & (uai_expire_date < lgi_time) ) return LGI$_ACNTEXPIR; *uiclen = sprintf(uic,"%o,%o",uai_uic.uic$w_grp,uai_uic.uic$w_mem); return status; } int chk_user( unsigned char *user, unsigned short userlen ) { int status,uai_uic = 0; struct dsc$descriptor dsc,dsc2; char buf[64]; ILE3 get_itmlst[] = { {4, UAI$_UIC, &uai_uic, 0}, {0, 0, 0, 0}}; INIT_SDESC(dsc2,userlen,user); INIT_SDESC(dsc,userlen,buf); if ( !(1 & (status = str$upcase(&dsc,&dsc2))) ) lib$signal(status); return status = sys$getuai(EFN$C_ENF, 0, &dsc, &get_itmlst, 0, 0, 0); }