home *** CD-ROM | disk | FTP | other *** search
- /* --- WVHEADER.C ---------------------------------------------
- *
- * This file contains the code necessary to create the initial skeleton
- * version of an article, which will be edited by the user.
- *
- * Mark Riordan 24-JAN-1990
- */
-
-
- /*
- *
- * $Id: wvheader.c 1.26 1994/09/16 00:42:53 jcooper Exp $
- * $Log: wvheader.c $
- * Revision 1.26 1994/09/16 00:42:53 jcooper
- * cc-by-mail feature and cleanup for 92.6
- *
- * Revision 1.25 1994/08/24 18:40:15 mrr
- * authorization enables post/mail
- *
- * Revision 1.24 1994/05/27 01:29:29 rushing
- * unnecessary winundoc.h
- *
- * Revision 1.23 1994/02/24 21:31:49 jcoop
- * jcoop changes
- *
- * Revision 1.22 1994/02/09 18:01:08 cnolan
- * cnolan 90.2 changes
- *
- * Revision 1.21 1994/01/18 09:51:34 jcoop
- * Use new version number scheme on X-Mailer header line
- *
- * Revision 1.20 1994/01/15 20:31:16 jcoop
- * Font/color stuff and signature file handling
- *
- * Revision 1.19 1993/12/08 01:27:21 rushing
- * new version box and cr lf consistency
- *
- * Revision 1.18 1993/08/25 18:53:17 mbretherton
- * MRB merge, mail & post logging
- *
- *
- * remove underscore for BC++ compile Bretherton
- *
- * Revision 1.17 1993/08/17 21:53:06 UNKNOWN
- * Updated version to Version 0.82 (JD)
- *
- * Revision 1.16 1993/07/13 22:11:31 rushing
- * strncpy crashing in parseaddress
- *
- * Revision 1.15 1993/07/06 21:09:50 cnolan
- * win32 support
- *
- * Revision 1.14 1993/06/29 20:06:07 rushing
- * use localtime for Date header
- *
- * Revision 1.13 1993/06/29 00:22:13 rushing
- * correct rfc822/rfc1036 MakeArtHeaderDate function
- *
- * Revision 1.12 1993/06/28 17:51:21 rushing
- * warnings
- *
- * Revision 1.11 1993/06/22 19:08:40 rushing
- * remove warnings
- *
- * Revision 1.10 1993/06/22 16:46:33 bretherton
- * robust parse_address
- *
- * Revision 1.9 1993/06/11 01:05:17 rushing
- * new version number
- *
- * Revision 1.8 1993/06/11 00:11:26 rushing
- * second merge from Matt Bretherton sources
- *
- *
- * Revision 1.7 1993/05/24 23:34:12 rushing
- * further refinements to header manipulation
- * extend reuse of header formatting capabilities
- *
- *
- * Revision 1.5 1993/05/18 22:10:45 rushing
- * smtp support
- *
- * Revision 1.4 1993/05/06 19:44:10 rushing
- * CompareStringNoCase was using _tolower rather than tolower.
- * according to c70 docs, _tolower is undefined for letters that
- * are not uppercase. Yikes!
- *
- * Revision 1.3 1993/04/30 21:17:01 rushing
- * put the X-Newsreader: line back in.
- *
- * Revision 1.2 1993/03/30 20:07:37 rushing
- * MAPI
- *
- * Revision 1.1 1993/02/16 20:54:22 rushing
- * Initial revision
- *
- *
- */
-
- #include <windows.h>
- #include <windowsx.h>
- #include "wvglob.h"
- #include "winvn.h"
- #pragma hdrstop
- #include <ctype.h>
- #include <time.h>
- #include <stdlib.h>
-
- #define MAXHEADERLINE 256
- int NewDocType;
-
- BOOL (*PostHeaderFuncs[])(TypDoc * Doc, char *Buf, long int BufLen) =
- {
- MakeArtHeaderFrom,
- MakeArtHeaderNewsgroups,
- MakeArtHeaderSubject,
- /* MakeArtHeaderMessageID, */
- /* MakeArtHeaderDate, */
- MakeArtHeaderReferences,
- MakeArtHeaderOrganization,
- MakeArtHeaderReplyTo,
- MakeArtHeaderNewsreader,
- NULL
- };
-
-
- /*--- function GetHeaderLine -------------------------------------------
- *
- * Given a document, get a line from the header portion of that document
- * whose prefix matches a given prefix. Prefix = first word in line.
- * For instance, you might call this routine to say "Get the 'Subject:'"
- * line from this document.
- *
- * Entry Doc points to the document whose header we are scanning.
- * The header is all the lines up to the first blank line.
- * Prefix is the character string which will identify the
- * line we are seeking. It is the first word
- * (blank-delimited) in a line in the header.
- * BufLen is the number of bytes left in the buffer Buf.
- *
- * Exit Returns TRUE iff we returned a line.
- * Buf if line was returned, contains that line, zero-
- * terminated.
- */
- BOOL
- GetHeaderLine (Doc, Prefix, Buf, BufLen)
- TypDoc *Doc;
- char *Prefix;
- char *Buf;
- int BufLen;
- {
- char *bufptr = Buf;
- TypBlock far *BlockPtr;
- TypLine far *LinePtr;
- unsigned int Offset;
- HANDLE hBlock;
- TypLineID MyLineID;
- int found = FALSE;
-
- TopOfDoc (Doc, &BlockPtr, &LinePtr);
- while (ExtractTextLine (Doc, LinePtr, Buf, BufLen))
- {
-
- /* Is this a blank line signifying the end of the header? */
-
- if (IsLineBlank (Buf))
- break;
-
- if (CompareStringNoCase (Buf, Prefix, strlen (Prefix)) == 0)
- {
- found = TRUE;
- break;
- }
- if (!NextLine (&BlockPtr, &LinePtr))
- break;
- }
- UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
- return (found);
- }
-
- /*--- function CreatePostingWnd -----------------------------------------
- *
- * Create the window for composing the text of a posting,
- * if it's OK to post.
- *
- * Entry Hwnd Handle to parnet window
- * Doc points to the document to which we are posting
- * a followup--NULL if it's a new posting.
- *
- * Exit Returns the handle of the newly-created window
- * (zero if failure).
- */
-
- HWND
- CreatePostingWnd (hWnd,Doc, DocType)
- HWND hWnd ;
- TypDoc *Doc;
- int DocType;
- {
- int ih;
- BOOL found = FALSE;
- BOOL AuthReq;
- unsigned int width;
- char *TitlePtr, *WndName;
-
- if (DocType == DOCTYPE_POSTING)
- {
- AuthReq = AuthReqPost;
- WndName = "WinVnPost";
- PostDoc = Doc;
- if (Doc)
- {
- TitlePtr = "Composing Followup Article";
- }
- else
- {
- TitlePtr = "Composing New Article";
- }
- for (ih = 0; !found && ih < MAXPOSTWNDS; ih++)
- {
- if (!WndPosts[ih].hWnd)
- {
- found = TRUE;
- break;
- }
- }
- }
- else
- {
- AuthReq = AuthReqMail;
- WndName = "WinVnMail";
- MailDoc = Doc;
- if (Doc)
- {
- TitlePtr = "Composing Reply Message";
- }
- else
- {
- TitlePtr = "Composing New Mail Message";
- strcpy(AddressString,"") ;
- }
- for (ih = 0; !found && ih < MAXMAILWNDS; ih++)
- {
- if (!WndMails[ih].hWnd)
- {
- found = TRUE;
- break;
- }
- }
- }
- if (found && AuthenticatePosting (AuthReq))
- {
-
- if (xScreen > 78 * ArtCharWidth)
- {
- width = 78 * ArtCharWidth;
- }
- else
- {
- width = xScreen - 2 * ArtCharWidth;
- }
-
- hWnd = CreateWindow (WndName,
- TitlePtr,
- WS_OVERLAPPEDWINDOW /* | WS_VSCROLL */ ,
- /* Initial X pos */
- ih * CharWidth,
- /* Initial Y pos */
- (int) (yScreen * 3 / 8) + (1 + ih) * LineHeight,
- /* Initial X Width */
- (int) width,
- /* Initial Y height */
- (int) (yScreen * 5 / 8) - (2 * LineHeight),
- NULL,
- NULL,
- hInst,
- NULL);
-
- if (hWnd)
- {
- SetHandleBkBrush (hWnd, hArticleBackgroundBrush);
- ShowWindow (hWnd, SW_SHOWNORMAL);
- UpdateWindow (hWnd);
- }
- }
- return (hWnd);
- }
-
-
- /*--- function CreatePostingText ------------------------------------------
- *
- * Create the text of the skeleton article to be edited by
- * the user before posting. Display that text in an edit window.
- */
- BOOL
- CreatePostingText (Doc, hWndPost, hWndEdit, DocType)
- TypDoc *Doc;
- HWND hWndPost;
- HWND hWndEdit;
- int DocType;
- {
- char far *lpTextBuffer;
- HANDLE hTextBuffer;
- int nLines;
- long lParam;
-
- if (NULL == (hTextBuffer = ExtractPostingText(Doc,DocType)))
- {
- MessageBox (hWndPost, "Cannot allocate memory for text", "", MB_OK);
- return FALSE;
- }
- lpTextBuffer = GlobalLock(hTextBuffer) ;
-
- /* Set the edit window text to this skeleton article. */
-
-
- SetWindowText (hWndEdit, lpTextBuffer);
- FreePostingText (hTextBuffer);
-
- nLines = (int) SendMessage (hWndEdit, EM_GETLINECOUNT, 0, 0L);
- lParam = (long) ((long) nLines);
-
- return TRUE;
- }
-
- /*--------- Extract the Text for the Posting ---------------------------
- *
- * Entry Doc points to the document to which we are posting
- * a followup--NULL if it's a new posting. *
- * DocType either build skeletal mail or posting document
- *
- * Exit a pointer to the unlocked memory area for skeletal posting
- *
- * Remember to call FreePosting Text to reclaim the memory allocated to
- * the posting text
- */
-
- HANDLE
- ExtractPostingText (Doc, DocType)
- TypDoc *Doc;
- int DocType;
- {
- long int BytesLeft;
- char far *lpTextBuffer;
- BOOL (**HeaderFuncs) (TypDoc * Doc, char *Buf, long int BufLen);
- char far *lpCurPtr;
- HANDLE hTextBuffer;
- BOOL gotline;
- char line[MAXHEADERLINE];
- int ifunc;
-
- NewDocType = DocType;
- if (DocType == DOCTYPE_POSTING)
- {
- HeaderFuncs = PostHeaderFuncs;
- }
- else
- {
- HeaderFuncs = MailCtrl.MailHeaderFuncs;
- }
-
- /* Compute the number of bytes we need to hold a straight ASCII representation
- * of the initial text of the reply, and allocate a buffer of that size.
- */
- if (Doc)
- {
- BytesLeft = (2 + NumBlocksInDoc (Doc)) * Doc->BlockSize;
- }
- else
- {
- BytesLeft = 3000;
- }
-
- if (NULL == (hTextBuffer = GlobalAlloc (GHND, (DWORD) BytesLeft)))
- {
- return ((HANDLE) NULL) ;
- }
-
- lpCurPtr = lpTextBuffer = GlobalLock (hTextBuffer);
-
- for (ifunc = 0; HeaderFuncs[ifunc]; ifunc++)
- {
- gotline = (HeaderFuncs[ifunc]) (Doc, line, (long int) MAXHEADERLINE);
- if (gotline)
- {
- AppendTextToEditBuf (line, &lpCurPtr, &BytesLeft);
- }
- }
- MakeArtBody (Doc, &lpCurPtr, &BytesLeft, DocType);
-
- GlobalUnlock (hTextBuffer);
- return(hTextBuffer) ;
- }
- /*---------- FreePostingText ---------------------------------------------
- *
- * Free the memory of the skeletal posting text
- *
- */
- BOOL
- FreePostingText (hTextBuffer)
- HANDLE hTextBuffer;
- {
- GlobalUnlock (hTextBuffer);
- GlobalFree (hTextBuffer);
-
- strcpy(AddressString,"") ;
- strcpy(NameString,"") ;
- strcpy(DialogString,"") ;
-
- return(TRUE) ;
- }
-
- /*--- functions MakeArtHeaderXXXXX ---------------------------------------
- *
- * Functions with names of the form MakeArtHeaderXxxxxx are all called
- * the same way and have similar purposes. They are called to
- * create and return a line of text that will become a line in
- * the header of an article to be posted. The source of
- * this information varies; it may be taken from an article
- * being replied to, it may be taken from a configuration file,
- * read from the system clock, etc.
- *
- * Entry Doc points to a document containing an article
- * being replied to; NULL if we're not replying
- * to an article.
- * BufLen is the length of the output buffer.
- *
- * Exit Returns TRUE iff we returned a line.
- * Buf contains the line, if any, terminated by a
- * zero byte.
- */
-
- /*--- function MakeArtHeaderSubject -------------------------------------
- *
- * Returned "Subject:"
- *
- */
-
- BOOL
- MakeArtHeaderSubject (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- char *outptr = Buf;
- char from[MAXHEADERLINE];
- char *fromptr;
-
- CopyBuf ("Subject: ", &outptr, &BufLen);
- if (Doc)
- {
- GetArtHeaderSubject (Doc, NULL, NULL);
- // if (!DialogString[0]) // always allow reply-subject confirmation
-
- if (NewDocType == DOCTYPE_POSTING) {
- fromptr = from;
- if (GetHeaderLine (Doc, "From:", from, MAXHEADERLINE-1))
- {
- NextToken (&fromptr);
- ParseAddress (fromptr, CcAddress, MAXDIALOGSTRING , str, MAXINTERNALLINE ) ;
- } else
- CcAddress[0] = (char) NULL;
- }
- DialogBoxParam (hInst, "WinVnSubject", Doc->hDocWnd, lpfnWinVnSubjectDlg, (LPARAM)(NewDocType == DOCTYPE_POSTING));
- }
- else
- {
- DialogString[0] = (char) NULL;
- CcAddress[0] = (char) NULL;
-
- DialogBoxParam (hInst, "WinVnSubject", hWndConf, lpfnWinVnSubjectDlg, (LPARAM)(NewDocType == DOCTYPE_POSTING));
- }
-
- CopyBuf (DialogString, &outptr, &BufLen);
- return (TRUE);
- }
-
- /*--- function GetArtHeaderSubject -------------------------------------
- *
- * Fill the DialogString global variable if a subject can be extracted
- * of the form "Subject: Re: <previous subject>".
- * If the article being replied to had a subject already starting
- * with "Re:", the "Re:" is not repeated.
- * returns FALSE as no line assembled
- * if no previous subject is found SubjestString is ""
- */
-
- GetArtHeaderSubject (Doc, NA, NALen)
- TypDoc *Doc;
- char *NA;
- long int NALen;
- {
- char HeadLine[MAXHEADERLINE];
- char *outptr = DialogString ;
- char *headptr = HeadLine;
- long int BufLen = MAXDIALOGSTRING ;
-
- *outptr='\0' ;
- if (Doc && ( GetHeaderLine (Doc, "Subject:", HeadLine, MAXHEADERLINE)))
- {
- NextToken (&headptr);
- if (CompareStringNoCase (headptr, "Re:", 3) != 0)
- {
- CopyBuf ("Re: ", &outptr, &BufLen);
- }
- CopyBuf (headptr, &outptr, &BufLen);
- }
-
- return(FALSE) ;
- }
- #if 0
- /*--- function MakeArtHeaderMessageID ----------------------------------
- *
- * Returned "Message-ID:" line is computed from the time and
- * the ServerName (from Windows profile file). This needs to
- * be improved.
- */
- BOOL
- MakeArtHeaderMessageID (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- #define MAXSERVERNAME 32
- char ServerName[MAXSERVERNAME];
-
- GetPrivateProfileString (szAppName, "ServerName", "titan.ksc.nasa.gov",
- ServerName, MAXSERVERNAME, szAppProFile);
-
- sprintf (Buf, "Message-ID: <%ld@%s>", time ((time_t *) NULL), ServerName);
- return TRUE;
- }
-
- #endif
-
- /*--- function MakeArtHeaderFrom ----------------------------------
- *
- * Returned "From:" is taken from Windows profile entries.
- */
- BOOL
- MakeArtHeaderFrom (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- char *outptr = Buf;
-
- CopyBuf ("From: ", &outptr, &BufLen);
- if (MailAddress[0])
- {
- CopyBuf (MailAddress, &outptr, &BufLen);
- }
- else
- {
- CopyBuf ("<Unknown>", &outptr, &BufLen);
- }
- if (UserName[0])
- {
- CopyBuf (" (", &outptr, &BufLen);
- CopyBuf (UserName, &outptr, &BufLen);
- CopyBuf (")", &outptr, &BufLen);
- }
-
- return TRUE;
- }
-
- /*--- function MakeArtHeaderReplyTo -------------------------------
- *
- * Returned "Reply-To:" is taken from Windows profile entries.
- */
- BOOL
- MakeArtHeaderReplyTo (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- char *outptr = Buf;
-
- if (ReplyTo[0] && strcmp(ReplyTo, MailAddress))
- {
- CopyBuf ("Reply-To: ", &outptr, &BufLen);
- CopyBuf (ReplyTo, &outptr, &BufLen);
- return TRUE;
- }
- return FALSE;
- }
-
- /*--- function MakeArtHeaderTo ----------------------------------
- *
- * Returns a well formed "To:" line or if user selected cancel
- * returns "To:" (blank) which if not edited will be rejected by
- * the server.
- */
- BOOL
- MakeArtHeaderTo (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- char HeadLine[MAXHEADERLINE];
- char *outptr = Buf, *cptr = HeadLine;
- GetArtHeaderTo(Doc,NULL,NULL);
-
- if (!strcmp(AddressString, "")) {
-
- DialogString[0]=(char)NULL;
- while (!strcmp(DialogString,""))
- if (!DialogBox (hInst, "WinVnMail", hWndConf, lpfnWinVnMailDlg))
- break;
-
- sprintf(HeadLine,"To: %s", DialogString);
- }
- else
- sprintf(HeadLine,"To: %s", AddressString);
-
- CopyBuf (HeadLine, &outptr, &BufLen);
- return TRUE;
- }
-
- /*--- function GetArtHeaderTo ----------------------------------
- *
- * Simply returns contents for a "To:" Line
- *
- * Global Variables
- * NameString and AddressString are extracted from the Document
- * returns FALSE as no line has been assembled
- */
- BOOL
- GetArtHeaderTo (Doc, NA, NALen)
- TypDoc *Doc;
- char *NA;
- long int NALen;
- {
- char HeadLine[MAXHEADERLINE];
- char *cptr = HeadLine ;
- BOOL gotwho;
- char ReplyAddress[MAXDIALOGSTRING], ReplyName[MAXDIALOGSTRING];
-
- if (Doc)
- {
- if (GetHeaderLine (Doc, "From:", HeadLine, MAXHEADERLINE))
- {
- NextToken (&cptr);
- ParseAddress (cptr, AddressString,MAXDIALOGSTRING , NameString,MAXDIALOGSTRING ) ;
- }
- if (gotwho = GetHeaderLine (Doc, "Reply-To:", HeadLine, MAXHEADERLINE))
- {
- NextToken (&cptr);
- ParseAddress (cptr, ReplyAddress,MAXDIALOGSTRING , ReplyName,MAXDIALOGSTRING ) ;
- }
- if (gotwho && strcmp (AddressString, ReplyAddress))
- {
- if (AddressString[0] && ConfirmReplyTo)
- {
- sprintf (str, "Use Reply-To: (%s) instead of\nFrom: (%s) in reply?",
- ReplyAddress, AddressString);
-
- if (MessageBox (Doc->hDocWnd, str, "Confirm Reply-To",
- MB_YESNO|MB_ICONQUESTION) == IDNO)
- gotwho = FALSE;
- }
- if (gotwho)
- strcpy (AddressString, ReplyAddress);
- }
- }
-
- return FALSE;
- }
- /*--- function ParseAddress --------------------------
- * Scan the
- * address field (null terminated ascii string)
- * representing any email address and optional
- * name
- *
- * and extract
- * addressout which is the email address
- * nameout which is the name (enclosed in parenthises)
- *
- *--------------------------------------------------------*/
- void ParseAddress(headerline,addressout,addressoutlen,nameout,nameoutlen)
- char *headerline ;
- char *addressout ;
- long int addressoutlen ;
- char *nameout ;
- long int nameoutlen ;
- { char *ptra = headerline , *ptrb, *ptrc ;
- char *iptr , *optr;
- int lastspace ;
- long int adlen = addressoutlen - 1 ,nmlen = nameoutlen -1 ;
- long int l;
-
- nameout[0]=addressout[0]=0 ;
-
- // Note parsing not strictly correct as anything in quotes '"'
- // overrides the meaning of lexical constructs '<' and '('
-
- // Seems this works and is robust but is now in the main
- // group list read and should be extremely efficient
- // suggest a single pass 'stream' parse more appropriate
- // but is more work
-
- if (ptrb=strchr(headerline,'<'))
- { // address enclosed in brackets
- l=min(ptrb-ptra-1,nmlen) ;
- if (l < 0) l = 0; /* this was killing print??? */
- if (l>0)
- { // otherwise strncpy crashes
- nmlen-=l ;
- strncpy(nameout,ptra,(int)l) ;
- nameout[l]=0;
- }
- if( ptrc=strchr(headerline,'>') )
- {
- if (nmlen >0)
- {
- strncpy(nameout+l,ptrc+1,(int)nmlen) ;
- nameout[nameoutlen-1]=0 ;
- }
- l=min(ptrc-ptrb-1,adlen) ;
- } else
- {
- l=adlen ;
- }
- if (l>0)
- {
- strncpy(addressout,ptrb+1,(int)l);
- addressout[l]=0;
- }
-
- } else
- if (ptrb=strchr(headerline,'('))
- { // name enclosed in braces
- l=min(ptrb-ptra-1,adlen) ;
- if (l>0)
- {
- adlen-=l ;
- strncpy(addressout,ptra,(int)l) ;
- addressout[l+1]=0;
- }
- if( ptrc=strchr(headerline,')'))
- {
- if (adlen > 0)
- {
- strncpy(addressout+l,ptrc+1,(int)adlen) ;
- addressout[addressoutlen-1]=0 ;
- }
- l=min(ptrc-ptrb-1,nmlen) ;
- } else
- {
- l=nmlen ;
- }
- if (l>0)
- {
- strncpy(nameout,ptrb+1,(int)l);
- nameout[l]=0;
- }
-
- } else
- { // just an address
- strncpy(addressout,ptra,(int)adlen) ;
- addressout[addressoutlen-1]=0 ;
- }
-
- // Clean Name - remove multiple space and quotes
- lastspace=TRUE ;
- for(iptr=optr=nameout ; *iptr ; iptr++)
- { switch( *iptr)
- {
- case ' ':
- if (!lastspace) *optr++=*iptr ;
- lastspace=TRUE ;
- break;
- case '"':
- break ;
- default :
- *optr++=*iptr ;
- lastspace=FALSE ;
- }
- }
- *optr=0 ;
-
- // Clean Address
- for(iptr=optr=addressout ; *iptr ; iptr++)
- { switch( *iptr)
- {
- case ' ':
- break;
- default :
- *optr++=*iptr ;
- lastspace=FALSE ;
- }
- }
- *optr=0 ;
-
- if (*nameout==0)
- { // if no name default to address
- strncpy(nameout,addressout,(int)nmlen) ;
- addressout[nameoutlen-1]=0 ;
- }
-
- }
-
- /* original code for parsing address
- char *adptr = addressout, *nmptr=nameout, *cptr = headerline;
- char *tptr ;
-
-
- if ( *cptr == '(' )
- { // skip Name in brackets
- tptr = strchr(headerline,')') ;
- if (tptr != NULL) cptr=tptr ;
- NextToken(&cptr); // skip parenthesis and white space
- }
- while (*cptr && *cptr != ' ' && adlen)
- {
- *(adptr++) = *(cptr++);
- adlen-- ;
- }
- *adptr = '\0';
-
- cptr = strchr(headerline,'(');
- if (cptr != NULL)
- {
- cptr++; // skip (
- while (*cptr && *cptr != ')' && nmlen) // copy to )
- {
- if (*cptr != '"') // drop quote characters
- {
- *(nmptr++) = *(cptr);
- nmlen--;
- }
- cptr++ ;
- }
- *nmptr = '\0';
- }
- else
- {
- strncpy( nmptr,addressout,(int)nmlen) ;
- nmptr[nmlen+1]= '\0' ;
- }
-
- }
-
- */
-
- /*--- function MakeArtHeaderOrganization ----------------------------------
- *
- * Returned "Organization:" line is gotten from the Windows
- * profile file.
- */
- BOOL
- MakeArtHeaderOrganization (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- char *outptr = Buf;
-
- if (Organization[0])
- {
- CopyBuf ("Organization: ", &outptr, &BufLen);
- CopyBuf (Organization, &outptr, &BufLen);
- return (TRUE);
- }
-
- return FALSE;
- }
-
- /*--- function MakeArtHeaderNewsreader ----------------------------------
- *
- * Returned "Newsreader: " line is simply a constant.
- */
- BOOL
- MakeArtHeaderNewsreader (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- char *outptr = Buf;
-
- CopyBuf ("X-Newsreader: ", &outptr, &BufLen);
- CopyBuf (WINVN_VERSION, &outptr, &BufLen);
- /* easier than examining this closely */
- /* CopyBuf ("\r", &outptr , &BufLen); */
- return (TRUE);
-
- }
-
- /*--- function MakeArtHeaderXmailer ----------------------------------
- *
- * Returned "Mailer: " line is simply a constant.
- */
- BOOL
- MakeArtHeaderXmailer (TypDoc * Doc, char *Buf, long int BufLen)
- {
- char *outptr = Buf;
-
- CopyBuf ("X-Mailer: ", &outptr, &BufLen);
- // CopyBuf ("WinVN version 0.82 SMTP", &outptr, &BufLen);
- CopyBuf (WINVN_VERSION, &outptr, &BufLen);
- return (TRUE);
- }
-
-
- /*--- function MakeArtHeaderDate ----------------------------------
- *
- * Returned "Date:" line is computed from operating system time.
- * Be sure to set the TZ environment variable correctly for
- * "gmtime" to work properly. Typical setting: SET TZ=EST5
- */
- BOOL
- MakeArtHeaderDate (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- struct tm *timeptr;
- time_t curtime;
- static char * days[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
- static char * months[] = { "Jan","Feb","Mar","Apr","May","Jun",
- "Jul","Aug","Sep","Oct","Nov","Dec"};
-
-
- if (!getenv("TZ")) {
- MessageBox (hWndConf,
- "Timezone environment variable 'TZ' not set.\n"
- "You must set this variable for your messages\n"
- "to be timestamped correctly.\n"
- "For example, you could add the following to your\n"
- "'autoexec.bat' file:\n"
- "set TZ=EST5EDT\n",
- "Warning:",
- MB_OK|MB_ICONHAND);
- }
-
- curtime = time ((time_t *) NULL);
- timeptr = localtime (&curtime);
-
- /* rfc1036&rfc822 acceptable format */
- /* Mon, 29 Jun 93 02:15:23 GMT */
- sprintf (Buf, "Date: %s, %.2d %s %.2d %.2d:%.2d:%.2d %s",
- days[timeptr->tm_wday],
- timeptr->tm_mday,
- months[timeptr->tm_mon],
- timeptr->tm_year,
- timeptr->tm_hour,
- timeptr->tm_min,
- timeptr->tm_sec,
- tzname[0]);
- return TRUE;
- }
-
-
- /*--- function MakeArtHeaderReferences -----------------------------------
- *
- * Returned "References:" line contains all the previous article's
- * References (if any), plus its Message-ID (if any).
- */
- BOOL
- MakeArtHeaderReferences (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- char HeadLine[MAXHEADERLINE];
- BOOL gotrefs;
- BOOL gotmesID;
- char *outptr = Buf;
- char *headptr = HeadLine;
-
-
- if (Doc)
- {
- gotrefs = GetHeaderLine (Doc, "References:", HeadLine, MAXHEADERLINE);
- if (gotrefs)
- {
- CopyBuf (HeadLine, &outptr, &BufLen);
- CopyBuf (" ", &outptr, &BufLen);
- }
- gotmesID = GetHeaderLine (Doc, "Message-ID:", HeadLine, MAXHEADERLINE);
- if (gotmesID)
- {
- if (!gotrefs)
- {
- CopyBuf ("References: ", &outptr, &BufLen);
- }
- NextToken (&headptr);
- CopyBuf (headptr, &outptr, &BufLen);
- }
- if (gotrefs || gotmesID)
- return (TRUE);
- }
- return FALSE;
- }
-
- /*--- function MakeArtHeaderNewsgroups -----------------------------------
- *
- * Returned "Newsgroups:" line is simply a copy of previous article's.
- */
- BOOL
- MakeArtHeaderNewsgroups (Doc, Buf, BufLen)
- TypDoc *Doc;
- char *Buf;
- long int BufLen;
- {
- char HeadLine[MAXHEADERLINE];
- BOOL gotnews = FALSE;
- char *outptr = Buf;
-
- if (Doc)
- {
- gotnews = GetHeaderLine (Doc, "Newsgroups:", HeadLine, MAXHEADERLINE);
- if (gotnews)
- {
- CopyBuf (HeadLine, &outptr, &BufLen);
- }
- }
- if (!gotnews)
- {
- CopyBuf ("Newsgroups: ", &outptr, &BufLen);
- CopyBuf (NewsgroupsPtr, &outptr, &BufLen);
- }
- return TRUE;
- }
-
- /*--- function MakeArtBody ----------------------------------------------
- *
- * Make the body of the article. This is null if there's no article
- * to reply to, else it's text of the form:
- * In article <Message-ID>, <user> says:
- * >line 1
- * >line 2
- * > .....
- *
- * Entry Doc points to the article being replied to, else
- * NULL if none.
- * left is the number of bytes left in MesBuf.
- *
- * Exit MesBuf contains the added lines, and has been updated
- * to point to just after the last added byte.
- * left has been decremented appropriately.
- * Return value is not used, for now.
- */
- BOOL
- MakeArtBody (Doc, MesBuf, left, DocType)
- TypDoc *Doc;
- char far **MesBuf;
- long int *left;
- int DocType;
- {
- HANDLE hBlock;
- unsigned int Offset;
- TypLineID MyLineID;
- TypBlock far *BlockPtr;
- TypLine far *LinePtr;
- char mesID[MAXHEADERLINE];
- char from[MAXHEADERLINE];
- char line[MAXHEADERLINE];
- BOOL gotmesID, gotfrom;
- char *outptr = line;
- char *fromptr = from;
- char *mesptr = mesID;
- register unsigned long i;
-
- AppendTextToEditBuf ("", MesBuf, left); /* blank line after header */
-
- /* Create the "In message xxx, yyy says:" line. */
-
- if (Doc)
- {
- gotmesID = GetHeaderLine (Doc, "Message-ID:", mesID, MAXHEADERLINE);
- if (gotmesID)
- {
- NextToken (&mesptr);
- }
- else
- {
- mesptr = "<Unknown>";
- }
- switch (DocType) {
- case DOCTYPE_POSTING:
- gotfrom = GetHeaderLine (Doc, "From:", from, MAXHEADERLINE);
- if (gotfrom)
- NextToken (&fromptr);
- else
- fromptr = "<Unknown>";
- sprintf (line, "In article %s, %s says:", mesptr, fromptr);
- break;
-
- case DOCTYPE_MAIL:
- sprintf (line, "In article %s, you say:", mesptr);
- break;
- }
-
- AppendTextToEditBuf (line, MesBuf, left);
-
- /* Skip past header of reply document. */
-
- TopOfDoc (Doc, &BlockPtr, &LinePtr);
- while (ExtractTextLine (Doc, LinePtr, line, MAXHEADERLINE) &&
- !IsLineBlank (line))
- {
- if (!NextLine (&BlockPtr, &LinePtr))
- break;
- }
-
- /* Copy body of reply document into the body of this article, */
- /* prepending a ">" to each line */
-
- /* following line commented after a merge of MRB code (SMR)*/
- /* line[0] = '>'; */
-
- line[0] = QuoteLineInd ;
-
- while (ExtractTextLine (Doc, LinePtr, line + 1, MAXHEADERLINE - 1))
- {
- AppendTextToEditBuf (line, MesBuf, left);
- if (!NextLine (&BlockPtr, &LinePtr))
- break;
- }
- UnlockLine (BlockPtr, LinePtr, &hBlock, &Offset, &MyLineID);
- if (EnableSig && Signature->numLines > 0)
- AppendTextToEditBuf ("", MesBuf, left); /* blank line before sig */
- }
-
- if (EnableSig)
- {
- for (i = 0; i < Signature->numLines; i++)
- AppendTextToEditBuf (TextBlockLine(Signature, i), MesBuf, left);
- }
- return TRUE;
- }
-
-
- /*--- function CompareStringNoCase -------------------------------------
- *
- * Compare two strings, case insensitive.
- *
- * Entry str1, str2 are two strings to compare.
- * slen is the number of characters to compare
- * (but stop at a zero byte).
- *
- * Exit returns -1 if str1 is earlier in collating sequence,
- * 0 if strings are equal, 1 otherwise
- */
- int
- CompareStringNoCase (str1, str2, slen)
- char *str1;
- char *str2;
- int slen;
- {
- /* bug when either string is zero length mrb */
- if (strlen(str1) < (unsigned) slen)
- {
- return(-1) ;
- }
- if (strlen(str2) < (unsigned) slen)
- {
- return(+1) ;
- }
-
- while (slen-- && *str1 && *str2)
- {
- if (tolower (*str1) < tolower (*str2))
- {
- return (-1);
- }
- else if (tolower (*str1) > tolower (*str2))
- {
- return (1);
- }
- str1++;
- str2++;
- }
- return (0);
- }
-
- /*--- function CopyBuf -----------------------------------------------
- *
- * Copy a string into a buffer, being sure not to overrun the
- * buffer.
- *
- * Entry instr points to the string to copy into the buffer,
- * zero-terminated.
- * buf is the buffer
- * left is the number of bytes left in the buffer
- * Exit buf contains the LWA+1 of the bytes copied into
- * the output buffer. A Zero byte is stored
- * into this location.
- * left is the number of bytes left in the buffer.
- */
-
- void
- CopyBuf (instr, buf, left)
- char *instr;
- char **buf;
- long int *left;
- {
- while (--(*left) > 1 && *instr)
- {
- *((*buf)++) = *(instr++);
- }
- if (*left > 0)
- **buf = '\0';
- }
-
- /*--- function NextToken -----------------------------------------------
- *
- * Position a pointer to the next token in a string.
- * Delimiters are space and tab.
- *
- * Entry cptr points to a position in a zero-terminated string.
- *
- * Exit Returns TRUE iff a next token was found.
- * cptr points to the next token, if found--else
- * it is unchanged.
- */
- BOOL
- NextToken (cptr)
- char **cptr;
- {
- /* Skip to end of current token, if any. */
-
- while (**cptr != ' ' && **cptr != '\t' && **cptr)
- (*cptr)++;
-
- /* Skip past white space. */
-
- while (**cptr && (**cptr == ' ' || **cptr == '\t'))
- (*cptr)++;
- if (**cptr)
- {
- return (TRUE);
- }
- else
- {
- return (FALSE);
- }
- }
-
- /*--- function AppendTextToEditBuf ----------------------------------------
- *
- * Appends a zero-terminated text line to a buffer to be given
- * to an Edit window. Used in building messages to be displayed
- * and edited by an Edit window.
- *
- * Entry instr points to a text line to add. It is terminated
- * by a zero byte and does not end in CR or LF.
- * left is the number of characters left in buf.
- *
- * Exit buf contains the line, terminated by CR and LF.
- * buf now points to the next available byte.
- * left has been decremented as appropriate.
- */
- void
- AppendTextToEditBuf (instr, buf, left)
- char *instr;
- char far **buf;
- long int *left;
- {
- while (--(*left) > 0 && *instr)
- {
- *((*buf)++) = *(instr++);
- }
- if (--(*left) > 0)
- *((*buf)++) = '\r';
-
- if (--(*left) > 0)
- *((*buf)++) = '\n';
-
- if ((*left) > 0)
- **buf = '\0';
- }
-
- /*--- function IsLineBlank ------------------------------------------------
- *
- * Determine whether a zero-terminated line is blank.
- * "Blank" means it contains nothing but spaces and tabs.
- *
- * Entry line points to the line.
- *
- * Exit returns TRUE iff the line is blank.
- */
- BOOL
- IsLineBlank (line)
- char far *line;
- {
- while (*line == ' ' || *line == '\t' || *line == '\n')
- line++;
- return (!(*line));
- }
-
- /*------------ editIntercept ----------------------------------
- *
- * the subclassed WindowProc for the edit component
- *
- * Capture key messages and pass them to parent
- * as may contain accelerator information
- *
- *--------------------------------------------------------------*/
-
- BOOL FAR PASCAL editIntercept(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- HWND parWnd ;
- BOOL res ;
-
- if (msg == WM_KEYDOWN || msg == WM_KEYUP)
- /* if it receives a keyboard event, pass it to your parent */
- {
- parWnd = GetParent(hwnd);
- res = PostMessage(parWnd,msg, wParam,lParam );
- }
- /* and always let the edit control do its thing */
- return (BOOL) CallWindowProc((WNDPROC)GetClassLong(hwnd, GCL_WNDPROC),
- hwnd, msg, wParam , lParam);
- }
-
- /* --------------- prepareEditMenu -----------------
- *
- * Common (wvpost and wvmail) preparartion
- * of edit menus
- *
- * -------------------------------------------------
- */
-
- void prepareEditMenu(HWND parWnd,HWND hWndEdit)
-
- { DWORD dwResult ;
- UINT action;
- HMENU hMenu = GetMenu(parWnd);
-
- dwResult = SendMessage (hWndEdit, EM_GETSEL, 0, 0L);
-
- if ( HIWORD (dwResult) == LOWORD (dwResult) )
- { /* No selection to ROT,Copy or Cut */
- action=MF_GRAYED ;
- } else
- {
- action=MF_ENABLED ;
- }
- EnableMenuItem(hMenu,IDM_ROT13,action) ;
- EnableMenuItem(hMenu,IDM_COPY,action) ;
- EnableMenuItem(hMenu,IDM_CUT,action) ;
- EnableMenuItem(hMenu,IDM_CLEAR,action) ;
-
- if (IsClipboardFormatAvailable(CF_TEXT))
- {
- action=MF_ENABLED ;
- } else
- { /* No Clip board contents to paste */
- action=MF_GRAYED ;
- }
- EnableMenuItem(hMenu,IDM_PASTE,action) ;
-
-
- if (SendMessage (hWndEdit, EM_CANUNDO, 0, 0L))
- {
- action=MF_ENABLED ;
- } else
- { /* Undo Buffer is empty so cannot Undo changes */
- action=MF_GRAYED ;
- }
- EnableMenuItem(hMenu,IDM_UNDO,action) ;
-
- }
-
- /* ---------------- function DoEditCommands -------------
- *
- * Command edit commands between wvpost and wvmail
- *
- * ------------------------------------------------------*/
- DoEditCommands(HWND hWndEdit,WPARAM wParam,LPARAM lParam)
- {
- switch (LOWORD(wParam))
- {
- case IDM_UNDO:
- SendMessage (hWndEdit, WM_UNDO, 0, 0L);
- break;
-
- case IDM_CUT:
- SendMessage (hWndEdit, WM_CUT, 0, 0L);
- break;
-
- case IDM_COPY:
- SendMessage (hWndEdit, WM_COPY, 0, 0L);
- break;
-
- case IDM_PASTE:
- SendMessage (hWndEdit, WM_PASTE, 0, 0L);
- break;
-
- case IDM_CLEAR:
- SendMessage (hWndEdit, WM_CLEAR, 0, 0L);
- break;
-
- case IDM_SELALL:
- SendMessage (hWndEdit, EM_SETSEL, 0,
- MAKELONG (0, 32767));
- break;
-
- case IDM_ROT13:
- { DWORD dwResult ;
- WORD wStart, wEnd ;
- char *editptr;
-
- dwResult = SendMessage (hWndEdit, EM_GETSEL, 0, 0L);
- wStart = LOWORD (dwResult) ;
- wEnd = HIWORD (dwResult) ;
-
- editptr = GetEditText (hWndEdit);
- strnROT13(editptr + wStart, wEnd - wStart) ;
- SetEditText (hWndEdit, editptr);
- GlobalFreePtr (editptr);
- InvalidateRect (hWndEdit, NULL, TRUE);
- }
- break;
-
- default :
- return(0) ; // signnify no action
- }
- return(1) ; // signify actions completed
- }
-
- /*
- * function DoEditClose
- * close down the edit window only if clean to close
- * or user agrees to lose information
- *
- */
-
- void DoEditClose(HWND hWnd,int dirty)
- {
- if ( dirty == DT_DIRTY)
- {
- if (MessageBox(hWnd, "Are you sure you want to exit?", "Unsaved Work",
- MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
- DestroyWindow(hWnd);
- }
- else
- DestroyWindow(hWnd);
- }
-