#pragma module NNTP_HDR_PARSE "NNTP_HDR_PARSE-1-X" /* **++ ** FACILITY: NNTP Server for OpenVMS ** ** MODULE DESCRIPTION: ** ** This module contains routines to parse and extract requested by callers fields from ** a RFC 822/821 header. ** ** AUTHORS: ** ** Ruslan R. Laishev ** ** CREATION DATE: 1-APR-2001 ** ** DESIGN ISSUES: ** ** This module uses a parser table has been declared externaly (see NNTP_HDR_PARSE_TBL.MAR), to ** performs a scanning and an extraction of selected number of fields. ** An information about found fields is strored in the array, in form: pointer,length. ** ** ** MODIFICATION HISTORY: ** ** {@tbs@}... **-- */ /* ** ** INCLUDE FILES ** */ #include #include #include #include #include #include #include /* ** ** RFC 821/822 DEFINITONS ** */ #include "rfc822def.h" /* ** ** LIB$TPARSE stuff ** */ extern char ufd_state, ufd_key; /* ** An array to store of the found fields */ struct tp_block { struct tpadef tpb; ile2 *itmlst; }; /* **++ ** FUNCTIONAL DESCRIPTION: ** ** An action routine called from LIB$TPARSE routine, if a field token is matched ** store a length and a pointer to the found field. ** ** FORMAL PARAMETERS: ** ** tblock: A pointer to the TPARSE block ** ** RETURN VALUE: ** ** VMS condition code ** ** SIDE EFFECTS: ** ** Modify a string pointer and length in the TPARSE block. ** ** **-- */ int hdr_parse_cpy ( struct tp_block *tblock ) { int len = 0; char *ptr; ile2 *ileptr; /* ** Search for the field terminator */ ptr = memchr(tblock->tpb.tpa$l_tokenptr,'\r', tblock->tpb.tpa$l_stringcnt-tblock->tpb.tpa$l_tokencnt); /* ** Shift string pointer to the next portion of a has being parsed string */ if ( ptr ) { len = ptr - tblock->tpb.tpa$l_tokenptr; tblock->tpb.tpa$l_stringcnt -= len; tblock->tpb.tpa$l_stringptr += len; } else { len = tblock->tpb.tpa$l_stringcnt; tblock->tpb.tpa$l_stringcnt = 0; tblock->tpb.tpa$l_stringptr += len; } /* ** Run over itemlist array to match a found token with requested */ for (ileptr = tblock->itmlst;ileptr->ile2$w_code;ileptr++) { if ( ileptr->ile2$w_code == tblock->tpb.tpa$l_param ) { /* ** The field has been requested to be extracted, store length and pointer */ ileptr->ile2$w_length = len; ileptr->ile2$ps_bufaddr = tblock->tpb.tpa$l_tokenptr; break; } } /* ** Always return a success status */ return SS$_NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** A routine to perform a parsing and extraction of the selected fields ** from a mail RFC822/821 headers. ** ** FORMAL PARAMETERS: ** ** ptr: a pointer to string to be parsed ** len: a length of the string ** itmlst: an array of ile2 elements to store a pointers and lengths of the found fields ** ** RETURN VALUE: ** ** VMS condition code ** **-- */ int hdr_parse ( char *ptr, int len, ile2 *itmlst[] ) { int status; struct tp_block tblock = {{TPA$K_COUNT0,TPA$M_BLANKS},{itmlst}}; /* ** Prepare a TPARSE block */ tblock.tpb.tpa$l_stringcnt = len; tblock.tpb.tpa$l_stringptr = ptr; /* ** Call parser, and return status */ return lib$table_parse( &tblock,&ufd_state,&ufd_key); } #if 0 char msghdr [] = "From: \"Terry C. Shannon\" \r\n\ To: \r\n\ Subject: And Now For Something Completely Different: CHARLIE MATCO HAS RISEN\ FROM THE GRAVE\r\n\ X-Path: x-path\r\n\ Path: path\r\n\ XX-Path: xx-path\r\n\ Date: Sat, 31 Mar 2001 16:20:18 -1200\r\n\ MIME-Version: 1.0\r\n\ Content-Type: multipart/mixed; boundary=\"----=_NextPart_000_00C8_01C0B9FE.7A2523E0\"\r\n\ X-Priority: 3\r\n\ X-MSMail-Priority: Normal\r\n\ X-Mailer: Microsoft Outlook Express 5.50.4133.2400\r\n\ X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400\r\n\ X-Mozilla-Status: 8001"; void main (void) { int status,count; ile2 itmlst[] = {{0,RFC822$K_FROM,0},{0,RFC822$K_PATH,0}, {0,RFC822$K_DATE,0},{0,RFC822$K_SUBJECT,0},{0,0,0}}; if ( !(1 & (status = hdr_parse( &msghdr,sizeof(msghdr),&itmlst))) ) lib$signal(status); for (count = 0;itmlst[count].ile2$w_code;count++) { printf("Field #%u = '%.*s'\n",itmlst[count].ile2$w_code, itmlst[count].ile2$w_length,itmlst[count].ile2$ps_bufaddr); } } #endif