/*

$Id: quote.c,v 1.1 94/03/11 23:16:10 bert Exp $

*/

#include "extern.h"
#include "proto.h"
#include "version.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <malloc.h>
#include "status.h"

extern char w_buf[];     /* temporary buffer for random output */

#define ok_char(c) ((c!='\r')&&(c!='\n')&&(c!='<')&&(c!= '>')&&(c!= '&'))

/*
 *  write_quoted is a http- and network-happy version of write().
 *  It translates "\r", "\n", "<", ">" and "&"/
 */
int write_quoted(int fd, char *buf, int nbytes)
{
  char *qq;
  int cnt;
  int pos = 0;
  int ret = 0;

  qq = buf;

  for (cnt=0; (cnt<nbytes) && ok_char(*qq); cnt++, qq++);

  while (cnt < nbytes) {
    if (cnt > 0) {
      if ((ret = write(fd, buf, cnt)) < 0) return ret;
    }

    switch (*qq) {  /* since cnt<nbytes, *qq points somewhere */
    case '\n': if ((ret = write(fd, "\r\n", 2)) < 0) return ret;  break;
    case '<':  if ((ret = write(fd, "&lt;", 4)) < 0) return ret;  break;
    case '>':  if ((ret = write(fd, "&gt;", 4)) < 0) return ret;  break;
    case '&':  if ((ret = write(fd, "&amp;", 5)) < 0) return ret; break;
    }

    buf = (++qq);
    nbytes -= (cnt+1);
    pos += (cnt+1);
    for (cnt=0; (cnt<nbytes) && ok_char(*qq); cnt++, qq++);
  }
  if (nbytes > 0) {
    ret = write(fd, buf, nbytes);
    if (ret < 0) return ret;
    else return (pos+ret);
  }
  else return pos;
}

/*
 *  fd_write_quoted is just a simple wrapper for write_quoted
 *  (a la fd_write)
 */
int fd_write_quoted(int fd, char* text)
{
  return write_quoted(fd, text, strlen(text));
}

/*
 *  fd_print_quoted is analogous to fd_print, but with quoting.
 */
int fd_print_quoted(int fd, const char* fmt, ...)
{
  va_list pvar;

  va_start(pvar, fmt);
  vsprintf(w_buf, fmt, pvar);
  va_end(pvar);
  return fd_write_quoted(fd, w_buf);
}


