#include "nntp.h" typedef struct {char *name; int value;} TABLE; #define HOUR(x) (x*60) static TABLE tzone_table[] = { { "gmt",HOUR( 0) }, /* Greenwich Mean */ { "ut", HOUR( 0) }, /* Universal */ { "utc",HOUR( 0) }, /* Universal Coordinated */ { "cut",HOUR( 0) }, /* Coordinated Universal */ { "z", HOUR( 0) }, /* Greenwich Mean */ { "wet",HOUR( 0) }, /* Western European */ { "bst",HOUR( 0) }, /* British Summer */ { "nst",HOUR(3)+30 },/* Newfoundland Standard */ { "ndt",HOUR(3)+30 },/* Newfoundland Daylight */ { "ast",HOUR( 4) }, /* Atlantic Standard */ { "adt",HOUR( 4) }, /* Atlantic Daylight */ { "est",HOUR( 5) }, /* Eastern Standard */ { "edt",HOUR( 5) }, /* Eastern Daylight */ { "cst",HOUR( 6) }, /* Central Standard */ { "cdt",HOUR( 6) }, /* Central Daylight */ { "mst",HOUR( 7) }, /* Mountain Standard */ { "mdt",HOUR( 7) }, /* Mountain Daylight */ { "pst",HOUR( 8) }, /* Pacific Standard */ { "pdt",HOUR( 8) }, /* Pacific Daylight */ { "yst",HOUR( 9) }, /* Yukon Standard */ { "ydt",HOUR( 9) }, /* Yukon Daylight */ { "akst",HOUR( 9) }, /* Alaska Standard */ { "akdt",HOUR( 9) }, /* Alaska Daylight */ { "hst",HOUR(10) }, /* Hawaii Standard */ { "hast",HOUR(10) }, /* Hawaii-Aleutian Standard */ { "hadt",HOUR(10) }, /* Hawaii-Aleutian Daylight */ { "ces",-HOUR(1) }, /* Central European Summer */ { "cest",-HOUR(1) }, /* Central European Summer */ { "mez",-HOUR(1) }, /* Middle European */ { "mezt",-HOUR(1) }, /* Middle European Summer */ { "cet",-HOUR(1) }, /* Central European */ { "met",-HOUR(1) }, /* Middle European */ { "eet",-HOUR(2) }, /* Eastern Europe */ { "msk",-HOUR(3) }, /* Moscow Winter */ { "msd",-HOUR(4) }, /* Moscow Summer */ { "wast",-HOUR(8) }, /* West Australian Standard */ { "wadt",-HOUR(8) }, /* West Australian Daylight */ { "hkt",-HOUR(8) }, /* Hong Kong */ { "cct",-HOUR(8) }, /* China Coast */ { "jst",-HOUR(9) }, /* Japan Standard */ { "kst",-HOUR(9) }, /* Korean Standard */ { "kdt",-HOUR(9) }, /* Korean Daylight */ { "cast",-(HOUR(9)+30) }, /* Central Australian Standard */ { "cadt",-(HOUR(9)+30) }, /* Central Australian Daylight */ { "east",-HOUR(10) }, /* Eastern Australian Standard */ { "eadt",-HOUR(10) }, /* Eastern Australian Daylight */ { "nzst",-HOUR(12) }, /* New Zealand Standard */ { "nzdt",-HOUR(12) }, /* New Zealand Daylight */ { NULL, 0 } /* End of table */ }; static char *Mont = {"JanFebMarAprMayJunJulAugSepOctNovDec"}; static char *Wdyt = {"SunMonTueWedThuFriSat"}; int cvt_tz_to_min (char *tz,int tzlen) { int i; char tzl [ 16 ]; char s,h[3],m[3]; strncpy (tzl,tz,tzlen); strnlwr(tzl,tzlen); if ( !(tzl[1]) ) { /* Military time zones, could have sign wrong*/ if (*tzl>='a' && *tzl<='m') return -(*tzl-'a'+1)*60; if (*tzl>='n' && *tzl<='y') return (*tzl-'n'+1)*60; return 0; } for (i=0; tzone_table[i].name!=NULL; i++) if (strncasecmp(tzl,tzone_table[i].name,tzlen)==0) return tzone_table[i].value; i = 0; s = '+'; if ( tzl[0] == '-' ) {s = '-';i++;} if ( tzl[0] == '+' ) {s = '+';i++;} h[0] = tzl[i++]; h[1] = tzl[i++]; h[2] = 0; m[0] = tzl[i++]; m[1] = tzl[i++]; m[2] = 0; i = 60*atoi (h); i+= atoi (m); if (s == '+') return i; return -i; } /* * "YYMMDD HHMMSS [GMT]" -> time_t */ time_t cvt_nntp_to_vms (char *date_time) { time_t t; struct tm ta; int tzi,i; char GMT [8]; memset(&ta,0,sizeof(ta)); if ( 6 > (i = sscanf(date_time,"%2d%2d%2d %2d%2d%2d %5s", &ta.tm_year,&ta.tm_mon,&ta.tm_mday, &ta.tm_hour,&ta.tm_min,&ta.tm_sec, &GMT)) ) return 0; ta.tm_mon--; if ( (i = 7) && (tzi = cvt_tz_to_min(GMT,8)) ) { ta.tm_hour += (tzi/60); ta.tm_min += (tzi%60); } ta.tm_year = ta.tm_year < 70?ta.tm_year+100:ta.tm_year; return (mktime(&ta)); } /* * time_t -> "YYMMDD HHMMSS [GMT]" */ void cvt_vms_to_nntp ( time_t t, char *ts, ushort *tslen ) { struct tm ta; ta = *gmtime(&t); ta.tm_year = ta.tm_year > 99?ta.tm_year-100:ta.tm_year; *tslen = sprintf(ts,"%02.2d%02.2d%02.2d %02.2d%02.2d%02.2d", ta.tm_year,ta.tm_mon+1,ta.tm_mday, ta.tm_hour,ta.tm_min,ta.tm_sec); } /* * */ time_t cvt_rfc_to_vms ( char *msgt, int msgtlen ) { time_t t; struct tm ta; char Wdy[4]; int DD; char Mon[4]; int YY; int HH; int MM; int SS; char *cp; char c; char TZ [ 16 ]; int tzi; /*msgt = "Tue, 12 Nov 1996 21:50:04 GMT" msgt = "Tue, 12 Nov 1996 21:50:04 MSK" msgt = "Tue, 12 Nov 96 21:50:04 +0300" msgt = "Tue, 12 Nov 1996 21:50:04 0300" msgt = "18 Nov 1996 22:37:31 +1100" msgt = "18 Nov 1996 22:37:31 MSK" msgt = "18 Nov 1996 22:37:31 EET" @TSV msgt = "18 Nov 1996 22:37 +1100" msgt = "18 Nov 1996 22 MSK" msgt = "18 Nov 1996 22:37 EET" @TSV - old USENET time format in article header msgt = "Mon Jul 7 16:53:39 1997" */ $DESCRIPTOR(set_dsc,"0123456789"); struct dsc$descriptor_s msgt_dsc; if ( !msgtlen ) return time(&t); Wdy[0] = Mon[0] = TZ [0] = 0; if ( memchr(msgt,',',msgtlen) ) sscanf(msgt,"%3s%c %d %3s %d %2d%c%2d%c%2d %15s", &Wdy,&c, &DD, &Mon, &YY, &HH,&c,&MM,&c, &SS, &TZ); else { INIT_SDESC(msgt_dsc,msgtlen,msgt); if ( str$find_first_not_in_set(&msgt_dsc,&set_dsc) ) { sscanf(msgt,"%d %3s %d %2d:%2d:%2d %15s", &DD, &Mon , &YY, &HH,&MM,&SS,&TZ); } else { sscanf(msgt,"%3s %3s %d %2d:%2d:%2d %d %15s", &Wdy, &Mon , &DD ,&HH,&MM,&SS,&YY,&TZ); } } ta.tm_wday = 0; ta.tm_mday = DD; if ( cp = strstr(Mont,Mon) ) ta.tm_mon = (cp-Mont)/3; if (YY < 1900) ta.tm_year = YY; else ta.tm_year = YY - 1900; tzi = cvt_tz_to_min(TZ,sizeof(TZ)); ta.tm_hour = HH+(tzi/60); ta.tm_min = MM+(tzi%60); ta.tm_sec = SS; return (mktime(&ta)); } /* * */ char *cvt_vms_to_rfc (time_t t,char *msgt,char *LocalTZ) { struct tm ta; ta = *localtime(&t); sprintf(msgt,"%3.3s, %2.2d %3.3s %2.2d %02.2d%:%02.2d%:%02.2d %s", (Wdyt+ta.tm_wday*3), ta.tm_mday, (Mont+ta.tm_mon*3), ta.tm_year, ta.tm_hour, ta.tm_min, ta.tm_sec, LocalTZ); return msgt; } /* *-------------------------------------------------------------------------------- */ char *strnlwr (char *s,int n) { char *ss=s; for (;(*s!=0) && (n);s++,n--) *s = tolower(*s); return ss; } /* * strstrip - remove all characters which contain in a "strip set" * from source string */ int strstrip ( char *src, int srclen, char *strip_set, int strip_setlen ) { char *cp = src; int ret_len; for (ret_len = 0;srclen > 0; srclen--,src++) { if (memchr(strip_set,*src,strip_setlen)) continue; *(cp) = *src; ret_len++;cp++; } return ret_len; } /* *-------------------------------------------------------------------------------- * strelem - extract substring which terminated by "separator" * in a source string,optionaly coping string to 'elembuf' */ int strelem ( struct dsc$descriptor *src_dsc, char sep, ushort idx, char **elem ) { int cnt,localidx; struct dsc$descriptor sep_dsc,src = *src_dsc; INIT_SDESC(sep_dsc,1,&sep); for (cnt = localidx = 0;localidx <= idx;localidx++) { src.dsc$a_pointer += cnt; src.dsc$w_length -= cnt; if ( !(cnt = lib$index(&src,&sep_dsc)) ) break; } if ( localidx < idx ) return 0; if ( elem ) *elem = src.dsc$a_pointer; return cnt?cnt-1:src.dsc$w_length; } /* *-------------------------------------------------------------------------------- * strmatch - doing of a string matching with a string pattern, for a pattern * you can use '*','%','!' (as NOT operator), and ',' as pattern * separator, return index of pattern in the pattern list (from 1...) * * as example: * sts - "vmsnet.test" * pat - "vmsnet.*,!microf%%ck.*,!*windoze*,*vms*" * */ int strmatch ( char *pat, ushort patlen, char *sts, ushort stslen ) { int status,match_f = 0,match_ok= 0; ushort elem; struct dsc$descriptor dsc_sts,dsc_elm,dsc_pat; INIT_SDESC (dsc_sts,stslen,sts); INIT_SDESC (dsc_pat,patlen,pat); INIT_SDESC (dsc_elm,0,0); for ( elem = 0;;elem++ ) { match_f = 1; /* * Get next wildcard pattern from list */ if ( !(dsc_elm.dsc$w_length = strelem(&dsc_pat,',', elem,&dsc_elm.dsc$a_pointer)) ) break; /* * Check inversion flag */ if ( *dsc_elm.dsc$a_pointer == '!' ) { dsc_elm.dsc$w_length--; dsc_elm.dsc$a_pointer++; match_f = 0; } /* * Performing math and check result */ status = str$match_wild(&dsc_sts,&dsc_elm); if ( STR$_MATCH == status ) { if ( match_f ) { match_ok = 1; break; } else { match_ok = 0; } } } return match_ok?elem+1:0; } void strinsert ( char *sts, ushort stslen, char *substr, ushort substrlen ) { memmove(sts+substrlen,sts,stslen); memcpy(sts,substr,substrlen); } void MDString ( char src0, char *src1, ushort srclen1, char *src2, ushort srclen2, char *dst ) { MD5_CTX context; MD5Init (&context); MD5Update (&context,&src0,1); MD5Update (&context, src1, srclen1); MD5Update (&context, src2, srclen2); MD5Final (dst, &context); } void MDbin2hex ( char *sts, char *dest ) { int i; int c; for (i=0;i < 16;i++,dest +=2,sts++) { c = *sts; c &= 255; sprintf(dest,"%02.2X",c); } }