head	1.16;
access;
symbols
	V0-99-8:1.15
	V0-99-7:1.14
	V0-99-6:1.14
	V0-99-5:1.14
	V0-99-4:1.14
	V0-99-2:1.13
	V0-99-1:1.13
	V0-93-14:1.13
	V0-93-13:1.13
	V0-93-12:1.13
	V0-93-11:1.13
	V0-93-10:1.12
	V0-93-9:1.12
	V0-93-8:1.12
	V0-93-7:1.12
	V0-93-5:1.12
	V80:1.1
	V76d:1.1;
locks; strict;
comment	@ * @;


1.16
date	97.02.06.17.26.06;	author dumoulin;	state Exp;
branches;
next	1.15;

1.15
date	96.08.13.04.35.17;	author dumoulin;	state Exp;
branches;
next	1.14;

1.14
date	95.05.19.22.12.22;	author dumoulin;	state Exp;
branches;
next	1.13;

1.13
date	94.12.14.17.02.13;	author brydon;	state Exp;
branches;
next	1.12;

1.12
date	94.11.10.01.54.15;	author rushing;	state Exp;
branches;
next	;


desc
@winvn version 0.76 placed into RCS
@


1.16
log
@formatting changes. Tab stops at 2 instead of 4
@
text
@/********************************************************************
 *                                                                  *
 *  MODULE    :  WVFILE.C                                           *
 *                                                                  *
 *  PURPOSE   : This file contains interface functions that allow   *
 *              WinVN to communicate with the local file system.    *
 *                                                                  *
 *******************************************************************/

/*
 * $Id: wvfile.c 1.14 1995/05/19 22:12:22 dumoulin Exp $
 */

#include <windows.h>
#include <windowsx.h>
#include "wvglob.h"
#include "winvn.h"
#pragma hdrstop
#include <io.h>
#include <ctype.h>
#include <conio.h>
#include <stdio.h>
#include <fcntl.h>          /* _O_ constant definitions */
#include <sys\types.h>
#include <sys\stat.h>       /* _S_ constant definitions */
#include <malloc.h>
#include <errno.h>

/*--- function MRROpenFile --------------------------------------------
 *
 *  Perform the same function as Windows' OpenFile, but also
 *  create an instance of a structure that keeps track of file-related
 *  information (most importantly, a file buffer so I don't have to
 *  do 1-byte system reads).
 *
 *    Entry    FileName    is the file name of the file to open.
 *             Mode        is the mode under which to open the file.
 *
 *    Exit     MRRFile     points to a dynamically-allocated structure
 *                         containing info about the file.
 *             Returns a handle to the file; NULL if failure.
 */
HFILE
MRROpenFile (char *FileName, int Mode, TypMRRFile **MRRFile)
{
  HFILE hMyFile;
  TypMRRFile *MyMRRFile;
  int retcode;

  MyMRRFile = (TypMRRFile *) GlobalAllocPtr (GMEM_FIXED, sizeof (TypMRRFile));
  if (MyMRRFile == NULL)
    return (HFILE) NULL;

  MyMRRFile->bufidx = 0;
  MyMRRFile->bytesread = 0;
  MyMRRFile->eofflag = FALSE;
  MyMRRFile->mode = Mode;

  if (Mode == OF_WRITE) {
    hMyFile = OpenFile (FileName, &(MyMRRFile->of), OF_EXIST);
    if (hMyFile == -1)
      Mode = OF_CREATE;
  }
  hMyFile = retcode = OpenFile ((char far *) FileName, &(MyMRRFile->of), Mode);
  if (retcode == -1) {
    GlobalFreePtr (MyMRRFile);
    return (0);
  }
  else {
    MyMRRFile->hFile = hMyFile;
  }

  *MRRFile = MyMRRFile;
  return (hMyFile);
}

/*--- function MRRCloseFile --------------------------------------------
 *
 *  Perform the same function as the close function, but also
 *  deallocate the structure allocated by MRROpenFile.
 *
 *    Entry    MRRFile  points to a structure describing the file.
 */
void
MRRCloseFile (TypMRRFile *MRRFile)
{
  if (MRRFile->mode == OF_WRITE || MRRFile->mode == OF_CREATE) {
    _lwrite (MRRFile->hFile, MRRFile->buf, MRRFile->bufidx);
  }
  _lclose (MRRFile->hFile);

  GlobalFreePtr (MRRFile);
}

/*--- function MRRReadLine ---------------------------------------------
 *
 *  Read in a line from a file, very much like "fgets".
 *  Lines are assumed to be terminated by CR/LF (except that this
 *  is optional for the last line in a file).
 *
 *  No CR, LF, or zero byte is placed in the user's buffer or
 *  counted as a data byte in the returned count.
 *
 *    Entry    MRRFile  points to a structure describing the file.
 *             Linebuf  is the place to put the line.
 *             Len      is the length of Linebuf.
 *
 *    Exit     Linebuf  contains a line.
 *             Returns number of characters read.  0 means an empty line;
 *              -1 means EOF.
 */
int MRRReadLine (TypMRRFile *MRRFile, char *Linebuf, int Len)
{
  int BytesReturned = 0;
  unsigned char ch;

  /* If we hit the EOF while reading last time, we might not have   */
  /* had to return an EOF indication then--but we certainly do now. */

  if (MRRFile->eofflag)
    return (-1);

  /* Read bytes until we exhaust the user's buffer,                 */
  /* empty our own internal buffer,                                 */
  /* or hit a CR (which hopefully belongs to a CR/LF pair).         */

readlp:;
  while (Len && MRRFile->bufidx < MRRFile->bytesread &&
    /*   (ch = MRRFile->buf[MRRFile->bufidx]) != '\r' && ch != '\n') { */
//ishido         (ch = MRRFile->buf[MRRFile->bufidx]) >= ' ') {
         (!iscntrl( (ch = MRRFile->buf[MRRFile->bufidx]))) ) {
    *(Linebuf++) = ch;
    BytesReturned++;
    (MRRFile->bufidx)++;
    Len--;
  }

  /* If we emptied our own internal buffer, fill 'er up again       */
  /* from the file.  If the read hits EOF, return the user's        */
  /* data now (indicating EOF if we never got any data bytes        */
  /* else go back up and continue taking from the buffer.           */

  if (MRRFile->bufidx >= MRRFile->bytesread) {
    MRRFile->bufidx = 0;
    MRRFile->bytesread = _lread (MRRFile->hFile, MRRFile->buf, BUFSIZE);
    if (MRRFile->bytesread > 0) {
      goto readlp;
    }
    else {
      MRRFile->eofflag = TRUE;
      if (!BytesReturned)
        BytesReturned--;
      goto endit;
    }
  }

  /* If we reach here, we either filled the user's buffer or        */
  /* hit a CR.  No EOF was encountered.                             */
  /* Either way, we must now skip to the beginning of the next      */
  /* line.  This means skipping to the next LF.  Since in most      */
  /* cases the user does specify a big enough buffer, in most       */
  /* cases all we are doing here is reading up the next character   */
  /* (assuming it's a LF).                                          */
  /* All data that should go in the user's buffer is there by now.  */

skipLF:;

  while (MRRFile->bufidx < MRRFile->bytesread &&
         MRRFile->buf[MRRFile->bufidx] != '\n') {
    (MRRFile->bufidx)++;
  }

  /* We either found the LineFeed we were looking for, or hit       */
  /* the end of our internal buffer.  If the latter, fill 'er       */
  /* up and try again.                                              */

  if (MRRFile->bufidx >= MRRFile->bytesread) {
    MRRFile->bufidx = 0;
    MRRFile->bytesread = _lread (MRRFile->hFile, MRRFile->buf, BUFSIZE);
    if (MRRFile->bytesread > 0) {
      goto skipLF;
    }
    else {
      MRRFile->eofflag = TRUE;
      goto endit;
    }
  }

  /* The buffer pointer is now pointing at the LF.  Advance         */
  /* it by one so we'll get the first character of the next         */
  /* line next time.                                                */
  /* If this takes us past the end of the buffer, no problem.       */


  if (MRRFile->buf[MRRFile->bufidx] == '\n')
    (MRRFile->bufidx)++;

endit:;
  return (BytesReturned);
}


/*--- function MRRReadInternalBuff ---------------------------------------------
 *
 *  Fill the internal MRRFile buffer.  Adjust the bufidx and bytesread
 *   counters accordingly.  Append '\0' at EOF.
 *
 *    Entry    MRRFile  points to a structure describing the file.
 *             Linebuf  is the place to put the line.
 *             Len      is the length of Linebuf.
 *
 *    Exit     Linebuf  contains a line.
 *
 *    Returns:  0 if success;
 *             -1 if EOF.
 */
int MRRReadInternalBuff (TypMRRFile *MRRFile)
{
  int nToRead;
  int nRet;
  
  if(MRRFile->bufidx)
  {
    MRRFile->bytesread -= MRRFile->bufidx;
    MoveBytes((void far*) (MRRFile->buf + MRRFile->bufidx),
      (void far*) MRRFile->buf,
      MRRFile->bytesread);
    MRRFile->bufidx = 0;
  }
  
  if(MRRFile->eofflag)
    return (-1);
  
  if(nToRead = sizeof(MRRFile->buf) - MRRFile->bytesread)
  {
    nRet = _lread(MRRFile->hFile, MRRFile->buf + MRRFile->bytesread, nToRead);
    if(nRet == HFILE_ERROR)
    {
      DEBUG_BREAK;
      MRRFile->eofflag = TRUE;
      return -1;
    }
    MRRFile->bytesread += nRet;
    if(nRet < nToRead)
    {
      MRRFile->buf[MRRFile->bytesread++] = '\0';
      MRRFile->eofflag = TRUE;
      return -1;
    }
  }
  return 0;
}

/*--- function MRRWriteLine ---------------------------------------------
 *
 *  Write out a line of text, followed by a CR and LF.
 *
 *    Entry    MRRFile  points to a structure describing the file.
 *             LineBuf  points to line buffer to write out.
 *             Len      is the number of bytes to write.
 */
BOOL
MRRWriteLine (TypMRRFile *MRRFile, char far *LineBuf, unsigned int Len)
{
  unsigned int BytesToCopy;
  int needsNewline = strcmp (LineBuf, "\r\n");
  do {
    BytesToCopy = Len < (BUFSIZE - (unsigned int) MRRFile->bufidx) ?
      Len : BUFSIZE - (unsigned int) MRRFile->bufidx;

    MoveBytes (LineBuf, (char far *) (MRRFile->buf + MRRFile->bufidx), BytesToCopy);
    MRRFile->bufidx += BytesToCopy;
    LineBuf += BytesToCopy;
    Len -= BytesToCopy;
    if (MRRFile->bufidx >= BUFSIZE) {
      _lwrite (MRRFile->hFile, MRRFile->buf, BUFSIZE);
      MRRFile->bufidx = 0;
    }
  }
  while (Len > 0);

  if (needsNewline) {
    MRRWriteLine (MRRFile, "\r\n", 2);
  }
  return (1);
}


/*--- function MRRWriteBuff ---------------------------------------------
 *
 *  Write a buffered line, NOT followed by a CR and LF.
 *
 *    Entry    MRRFile  points to a structure describing the file.
 *             LineBuf  points to line buffer to write out.
 *             Len      is the number of bytes to write.
 */
BOOL MRRWriteBuff(TypMRRFile *MRRFile, char far *LineBuf, unsigned int Len)
{
  unsigned int BytesToCopy;
  do
  {
    BytesToCopy = Len < (BUFSIZE - (unsigned int) MRRFile->bufidx) ?
      Len : BUFSIZE - (unsigned int) MRRFile->bufidx;
    
    MoveBytes (LineBuf, (char far *) (MRRFile->buf + MRRFile->bufidx), BytesToCopy);
    MRRFile->bufidx += BytesToCopy;
    LineBuf += BytesToCopy;
    Len -= BytesToCopy;
    if (MRRFile->bufidx >= BUFSIZE)
    {
      _lwrite (MRRFile->hFile, MRRFile->buf, BUFSIZE);
      MRRFile->bufidx = 0;
    }
  } while (Len > 0);
  
  return (1);
}

/*-- function MRRWriteDocument -----------------------------------------
 *
 *  Write out an entire document to disk.
 *
 *  Entry   Document    points to a document.
 *          Offset      is the number of bytes to skip at the beginning
 *                      of the line (between the end of the structure
 *                      described in TypLine and the beginning of text).
 *                      In most cases this will be zero.
 *          szFileName  points to the file name to save to.
 *          Append      is TRUE iff we should append to the file.
 *
 *    Returns TRUE iff we wrote the file OK.
 */
BOOL
MRRWriteDocument (TypDoc *Document, int Offset, char *szFileName, BOOL Append)
{
  TypMRRFile *MRRFile;
  HFILE hFile;
  TypBlock far *BlockPtr;
  TypLine far *LinePtr;
  int mode, len;
  char temp[MAXHEADERLINE], dateStr[MAXINTERNALLINE];
  int result = TRUE;

  hSaveCursor = SetCursor (hHourGlass);
  SetCapture (Document->hDocWnd);

  if (Append) {
    mode = OF_WRITE;
  }
  else {
    mode = OF_CREATE;
  }

  hFile = MRROpenFile (szFileName, mode, &MRRFile);
  if (hFile &&
      (!Append || _llseek (hFile, 0L, 2) != HFILE_ERROR)) {

    /* first write a mailbox header (jsc) */
    MRRWriteLine (MRRFile, "\r\n", 2);
    GetMailboxDate (dateStr, MAXINTERNALLINE - 1);
    len = _snprintf (temp, MAXHEADERLINE, "From %s %s",
                     (*MailAddress) ? MailAddress : "Unknown", dateStr);

    MRRWriteLine (MRRFile, temp, len);

    LockLine (Document->hFirstBlock, sizeof (TypBlock), (TypLineID) 0L, &BlockPtr, &LinePtr);
    while (LinePtr->length != END_OF_BLOCK) {
      MRRWriteLine (MRRFile, ((char far *) LinePtr) + Offset + sizeof (TypLine),
              lstrlen (((char far *) LinePtr) + sizeof (TypLine) + Offset));
      NextLine (&BlockPtr, &LinePtr);
    }
    /* make sure end with blank line */
    MRRWriteLine (MRRFile, "\r\n", 2);

    GlobalUnlock (BlockPtr->hCurBlock);
    MRRCloseFile (MRRFile);
  }
  else {
    result = FALSE;
  }

  SetCursor (hSaveCursor);
  ReleaseCapture ();
  return (result);
}

#if 0                           // replaced by new logging code in wvattach.c (jsc)
/*
 *  Append the edit text to the end of the appropriate log file 
 *   hWnd  - handle to window for warning messages
 *   fName - name of the log file
 *           (will be created if does not exist) 
 *   MBuf  - pointer to string to be written to file
 */
BOOL
WriteEditLog (HWND hWnd, char *szFileName, TypTextBlock * headers, char *mBuf, unsigned int size)
{
  TypMRRFile *MRRFile;
  HFILE hFile;
  register unsigned long i;

  hFile = MRROpenFile (szFileName, OF_WRITE, &MRRFile);

  if (hFile) {
    _llseek (hFile, 0L, 2);     /* seek end of file */

    for (i = 0; i < headers->numLines; i++) {
      MRRWriteLine (MRRFile, TextBlockLine (headers, i),
                    strlen (TextBlockLine (headers, i)));
    }

    MRRWriteLine (MRRFile, mBuf, size);

    MRRCloseFile (MRRFile);
  }
  else {
    return (FALSE);
  }
  return (TRUE);
}
#endif


/* Copies one file to another (both specified by path). Dynamically
 * allocates memory for the file buffer. Prompts before overwriting
 * existing file. Returns TRUE if successful, otherwise FALSE.
 */

#ifndef _WIN32
BOOL CopyFile(char *source, char *target, BOOL bFailIfExists)
{
    char *buf;
    int hsource, htarget;
    unsigned count = 0xff00;

    /* Open source file and create target, overwriting if necessary. */
    if( (hsource = _open( source, _O_BINARY | _O_RDONLY )) == - 1 )
        return FALSE;
    htarget = _open( target, _O_BINARY | _O_WRONLY | _O_CREAT | _O_EXCL,
                             _S_IREAD | _S_IWRITE );
    if(errno == EEXIST)
        if (bFailIfExists)
            return FALSE;
        else
            htarget = _open( target, _O_BINARY | _O_WRONLY | _O_CREAT |
                                     _O_TRUNC, _S_IREAD | _S_IWRITE );
    if( htarget == -1 )
        return FALSE;

    if( (unsigned)_filelength( hsource ) < count )
        count = (int)_filelength( hsource );

    /* Dynamically allocate a large file buffer. If there's not enough
     * memory for it, find the largest amount available on the near heap
     * and allocate that. This can't fail, no matter what the memory model.
     */
    if( (buf = (char *)malloc( (size_t)count )) == NULL )
    {

        count = _memmax();
        if( (buf = (char *)malloc( (size_t)count )) == NULL )
            return FALSE;
    }

    /* Read-write until there's nothing left. */
    while( !_eof( hsource ) )
    {
        /* Read and write input. */
        if( (count = _read( hsource, buf, count )) == -1 )
            return FALSE;
        if( (count = _write( htarget, buf, count )) == - 1 )
            return FALSE;
    }

    /* Close files and release memory. */
    _close( hsource );
    _close( htarget );
    free( buf );
    return TRUE;
}
#endif

/*
 * Local Variables:
 * tab-width: 2
 * end:
 */
@


1.15
log
@add CopyFile routine to copy, not Rename temporary Newsrc file when rename fails
@
text
@d1 9
a13 3
/*-- WVFILE.C -- File containing routines to do I/O under Windows.
 */

d33 1
a33 1
 *  information (most importantly, an file buffer so I don't have to
d44 1
a44 4
MRROpenFile (FileName, Mode, MRRFile)
	 char *FileName;
	 int Mode;
	 TypMRRFile **MRRFile;
d52 1
a52 1
	return (HFILE) NULL;
d60 3
a62 3
	hMyFile = OpenFile (FileName, &(MyMRRFile->of), OF_EXIST);
	if (hMyFile == -1)
	  Mode = OF_CREATE;
d66 2
a67 2
	GlobalFreePtr (MyMRRFile);
	return (0);
d70 1
a70 1
	MyMRRFile->hFile = hMyFile;
d85 1
a85 2
MRRCloseFile (MRRFile)
	 TypMRRFile *MRRFile;
d88 1
a88 1
	_lwrite (MRRFile->hFile, MRRFile->buf, MRRFile->bufidx);
d121 1
a121 1
	return (-1);
d129 1
a129 1
	/*	 (ch = MRRFile->buf[MRRFile->bufidx]) != '\r' && ch != '\n') { */
d132 4
a135 4
	*(Linebuf++) = ch;
	BytesReturned++;
	(MRRFile->bufidx)++;
	Len--;
d144 11
a154 11
	MRRFile->bufidx = 0;
	MRRFile->bytesread = _lread (MRRFile->hFile, MRRFile->buf, BUFSIZE);
	if (MRRFile->bytesread > 0) {
	  goto readlp;
	}
	else {
	  MRRFile->eofflag = TRUE;
	  if (!BytesReturned)
		BytesReturned--;
	  goto endit;
	}
d169 2
a170 2
		 MRRFile->buf[MRRFile->bufidx] != '\n') {
	(MRRFile->bufidx)++;
d178 9
a186 9
	MRRFile->bufidx = 0;
	MRRFile->bytesread = _lread (MRRFile->hFile, MRRFile->buf, BUFSIZE);
	if (MRRFile->bytesread > 0) {
	  goto skipLF;
	}
	else {
	  MRRFile->eofflag = TRUE;
	  goto endit;
	}
d196 1
a196 1
	(MRRFile->bufidx)++;
d202 52
d263 1
a263 4
MRRWriteLine (MRRFile, LineBuf, Len)
	 TypMRRFile *MRRFile;
	 char far *LineBuf;
	 unsigned int Len;
d268 2
a269 2
	BytesToCopy = Len < (BUFSIZE - (unsigned int) MRRFile->bufidx) ?
	  Len : BUFSIZE - (unsigned int) MRRFile->bufidx;
d271 8
a278 8
	MoveBytes (LineBuf, (char far *) (MRRFile->buf + MRRFile->bufidx), BytesToCopy);
	MRRFile->bufidx += BytesToCopy;
	LineBuf += BytesToCopy;
	Len -= BytesToCopy;
	if (MRRFile->bufidx >= BUFSIZE) {
	  _lwrite (MRRFile->hFile, MRRFile->buf, BUFSIZE);
	  MRRFile->bufidx = 0;
	}
d283 1
a283 1
	MRRWriteLine (MRRFile, "\r\n", 2);
d288 31
d334 1
a334 5
MRRWriteDocument (Document, Offset, szFileName, Append)
	 TypDoc *Document;
	 int Offset;
	 char *szFileName;
	 BOOL Append;
d348 1
a348 1
	mode = OF_WRITE;
d351 1
a351 1
	mode = OF_CREATE;
d356 1
a356 1
	  (!Append || _llseek (hFile, 0L, 2) != HFILE_ERROR)) {
d358 16
a373 16
	/* first write a mailbox header (jsc) */
	MRRWriteLine (MRRFile, "\r\n", 2);
	GetMailboxDate (dateStr, MAXINTERNALLINE - 1);
	len = _snprintf (temp, MAXHEADERLINE, "From %s %s",
					 (*MailAddress) ? MailAddress : "Unknown", dateStr);

	MRRWriteLine (MRRFile, temp, len);

	LockLine (Document->hFirstBlock, sizeof (TypBlock), (TypLineID) 0L, &BlockPtr, &LinePtr);
	while (LinePtr->length != END_OF_BLOCK) {
	  MRRWriteLine (MRRFile, ((char far *) LinePtr) + Offset + sizeof (TypLine),
			  lstrlen (((char far *) LinePtr) + sizeof (TypLine) + Offset));
	  NextLine (&BlockPtr, &LinePtr);
	}
	/* make sure end with blank line */
	MRRWriteLine (MRRFile, "\r\n", 2);
d375 2
a376 2
	GlobalUnlock (BlockPtr->hCurBlock);
	MRRCloseFile (MRRFile);
d379 1
a379 1
	result = FALSE;
d387 1
a387 1
#if 0							// replaced by new logging code in wvattach.c (jsc)
d405 1
a405 1
	_llseek (hFile, 0L, 2);		/* seek end of file */
d407 4
a410 4
	for (i = 0; i < headers->numLines; i++) {
	  MRRWriteLine (MRRFile, TextBlockLine (headers, i),
					strlen (TextBlockLine (headers, i)));
	}
d412 1
a412 1
	MRRWriteLine (MRRFile, mBuf, size);
d414 1
a414 1
	MRRCloseFile (MRRFile);
d417 1
a417 1
	return (FALSE);
d442 4
a445 4
		if (bFailIfExists)
			return FALSE;
		else
    	    htarget = _open( target, _O_BINARY | _O_WRONLY | _O_CREAT |
@


1.14
log
@Add a space seperator between files saved in mailbox format.
@
text
@d2 1
a2 1
 * $Id: wvfile.c 1.13 1994/12/14 17:02:13 brydon Exp $
d14 8
a22 1

d113 1
a113 1
  char ch;
d128 2
a129 1
         (ch = MRRFile->buf[MRRFile->bufidx]) >= ' ') {
d344 66
@


1.13
log
@fix for non-winvn newsrc support
@
text
@d2 1
a2 1
 * $Id: wvfile.c 1.12 1994/11/10 01:54:15 rushing Exp $
d273 1
@


1.12
log
@restart
@
text
@d103 1
a103 5
int
MRRReadLine (MRRFile, Linebuf, Len)
	 TypMRRFile *MRRFile;
	 char *Linebuf;
	 int Len;
d120 2
a121 1
		 (ch = MRRFile->buf[MRRFile->bufidx]) != '\r' && ch != '\n') {
@
