/**********************************************************************
 * ti library's routine for receiving text of a file
 *
 * $Author: brlewis $
 * $Source: /afs/net.mit.edu/dapps/project/techinfodev/src/libti/RCS/recv.c,v $
 * $Header: /afs/net.mit.edu/dapps/project/techinfodev/src/libti/RCS/recv.c,v 0.2 92/07/09 17:02:14 brlewis Exp Locker: brlewis $
 *
 * Copyright 1991 by the Massachusetts Institute of Technology.
 *
 * For copying and distribution information, please see the file
 * <mit-copyright.h>.
 **********************************************************************/

#include <mit-copyright.h>

#ifndef lint
static char rcsid_ti_send_c[] = "$Header: /afs/net.mit.edu/dapps/project/techinfodev/src/libti/RCS/recv.c,v 0.2 92/07/09 17:02:14 brlewis Exp Locker: brlewis $";
#endif /* lint */

#include <ti/wintypes.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ti/ti_intrl.h>

/**********************************************************************
 * ti_recv(TI_H hti, long recvid, long first, long max, LPSTR buf,
 *	   ti_recvinfo FAR *recvinfo)
 *
 * - sends command to server
 * - receives info on size of file
 * - receives contents of file starting with (first) char
 * - stores up to (max) chars in (buf).
 * - returns error code
 **********************************************************************/

/* jms 7/13/92 -- windows-izing begun */

long
ti_recv(hti, recvid, first, max, buf, recvinfo)
     TI_H hti;
     long recvid;
     long first, max; /* jms */
     LPSTR buf;
     ti_recvinfo FAR *recvinfo;
{
  long code;
  static char inbuf[BUFSIZ];
  LPSTR ptr1;
  int cc=0, total=0, i;

  TI_LP lpti;

  lpti = (TI_LP)TI_DEREFERENCE(hti);

  /* send command and receive first byte of reply */
  code = _ti_talkf(hti, inbuf, 1, "t:%ld:%ld:%ld\n", recvid, first, max);
	/* jms */
  if (code != TI_ERR_TOOLONG)
    {
      if (!code) goto HUH;
      CLEANUP_AND_RETURN(code)
    }

  /* read in number of bytes total */
  if (code = _ti_readupto(lpti, ':', inbuf+1, BUFSIZ-2))
  recvinfo->total = atol(inbuf); /* jms */
    {
      CLEANUP_AND_RETURN(code)
    }

  /* read in number of bytes sent */
  if (code = _ti_readupto(lpti, ':', inbuf, BUFSIZ-1))
    {
      CLEANUP_AND_RETURN(code)
    }
  recvinfo->sent = atol(inbuf); /* jms */

  /* read in date modified */
  if (code = _ti_readupto(lpti, TI_LF, recvinfo->modified, TI_MAXMODSTRLEN-1))
    {
      CLEANUP_AND_RETURN(code)
    }
  /* remove trailing \r\n */
  for(ptr1 = recvinfo->modified; ptr1 - recvinfo->modified < TI_MAXMODSTRLEN;
      ptr1++)
    {
      if (*ptr1 == TI_CR || *ptr1 == TI_LF)
	{
	  *ptr1 = '\0';
	  break;
	}
    }

  /* throw out extra newline */
  read(lpti->sock, buf, 1);

  /* read text into buffer */
  while(max-total > 0 && total < recvinfo->sent)
    {
      cc = read(lpti->sock, buf+total, max-total);
      if (cc < 0) return((long) GetErrno()); /* jms */
      if (cc == 0) break;
      total += cc;
    }

  /* take care of partial EOF */
  for(i = recvinfo->sent - TI_EOLM_LEN; i < total; i++) *(buf+i) = '\0';

  /* take care of any other leftovers */
  if (recvinfo->sent > total)
      read(lpti->sock, inbuf, recvinfo->sent - total);

  CLEANUP_AND_RETURN(0L)

 HUH:
      strncpy(ti_context, inbuf, sizeof(ti_context)-1);
      CLEANUP_AND_RETURN(TI_ERR_SRVHUH)

CLEANUP:
  TI_REMOVE_DEREFERENCE(hti, lpti);
  return(code);
}

long
_ti_readupto(lpti, delim, ptr, maxread)
     TI_LP lpti;
     char delim;
     LPSTR ptr;
     int maxread;
{
  int cc;

  while(maxread)
    {
      if ((cc = read(lpti->sock, ptr++, 1)) == 0)
	{
	  *(--ptr) = '\0';
	  return(0L);
	}
      if (cc < 0) return((long)GetErrno()); /* jms */
      if (*(ptr-1) == delim) return(0L);
      maxread--;
    }
  return(TI_ERR_TOOLONG);
}
