/* stripslash.c -- remove trailing slashes from a string
   Copyright (C) 1990 Free Software Foundation, Inc.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.  */

#include "cvs.h"

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

int emx_rmdir (char * path )
{
  char * unlink_owner;

  unlink_owner = xmalloc( strlen( path ) + strlen( EMX_CVSLCKOWN ) + 10 );
  sprintf( unlink_owner, "%s/%s", path, EMX_CVSLCKOWN );
  unlink( unlink_owner );
  free( unlink_owner );
  return rmdir( path );
}

#ifdef FSEEK_BUG
int emx_fseek (FILE *stream, long offset, int origin)
{
  if (trace)
    {
      fprintf( stdout, "fseek( %d[%d:%d], to: %ld, from: %d\n",
         stream -> _handle, stream -> _rcount, stream -> _wcount, offset, origin );
    }
  rewind( stream );
  return fseek(stream, offset, origin);
}
#endif

/* _str_rd.c (emx+gcc) -- Copyright (c) 1996 by Eberhard Mattes */

#include <unistd.h>
#include <errno.h>
#include <emx/io.h>

int _stream_read (int fd, void *buf, size_t nbyte)
{
  int r;

  do
    {
      r = _read (fd, buf, nbyte);
    } while (r == -1 && errno == EINTR);
  return r;
}

/* fread.c (emx+gcc) -- Copyright (c) 1990-1998 by Eberhard Mattes */

#include <sys/builtin.h>        /* For <sys/fmutex.h> */
#include <sys/fmutex.h>         /* For <sys/rmutex.h> */
#include <sys/rmutex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <errno.h>
#include <emx/io.h>

#define min(a,b) (((a) < (b)) ? (a) : (b))

size_t fread (void *buffer, size_t size, size_t count, FILE *stream)
{
  size_t total, left, n;
  int r;   /* signed! */
  char *dst;
  int fh, c;

  if (size == 0 || count == 0)
    return 0;
  total = size * count;
  if (total / count != size)
    {
      errno = ERANGE;
      return 0;
    }

  STREAM_LOCK (stream);
  if (nbuf (stream))
    _fbuf (stream);
  left = total;
  dst = buffer;
  fh = stream->_handle;
  stream->_flags |= _IOREAD;
  if (bbuf (stream))
    while (left != 0)
      {
        if (stream->_rcount > 0)
          {
            n = min ((size_t)stream->_rcount, left);
            memcpy (dst, stream->_ptr, n);
            stream->_ptr += n;
            stream->_rcount -= n;
            dst += n;
            left -= n;
          }
        else if (left > BUFSIZ && stream->_ungetc_count == 0)
          {
            n = (left / BUFSIZ) * BUFSIZ;      /* Number of buffers */
            r = _stream_read (fh, dst, n);
            if (r < 0)
              {
                stream->_flags |= _IOERR;
                break;
              }
            if (r == 0)
              {
                stream->_ptr = stream->_buffer;
                stream->_flags |= _IOEOF;
                if (stream->_flags & _IORW)
                  stream->_flags &= ~(_IOREAD|_IOWRT);
                break;
              }
            left -= r;
            dst += r;
          }
        else
          {
            --stream->_rcount;
            c = _fill (stream);
            if (c == EOF)
              break;
            *dst++ = (char)c;
            --left;
          }
      }
  else
    {
      if (stream->_rcount > 0)
        {
          n = min ((size_t)stream->_rcount, left);
          memcpy (dst, stream->_ptr, n);
          stream->_ptr += n;
          stream->_rcount -= n;
          dst += n;
          left -= n;
        }
      while (left != 0)
        {
          if (stream->_ungetc_count != 0)
            {
              --stream->_rcount;
              c = _fill (stream);
              if (c == EOF)
                break;
              *dst++ = (char)c;
              --left;
            }
          else
            {
              r = _stream_read (fh, dst, left);
              if (r < 0)
                {
                  stream->_flags |= _IOERR;
                  break;
                }
              if (r == 0)
                {
                  stream->_ptr = stream->_buffer;
                  stream->_flags |= _IOEOF;
                  if (stream->_flags & _IORW)
                    stream->_flags &= ~(_IOREAD|_IOWRT);
                  break;
                }
              dst += r;
              left -= r;
            }
        }
    }
  STREAM_UNLOCK (stream);
  return (total - left) / size;
}

