ftp.nice.ch/pub/next/unix/communication/ft_bbs.1.0.s.tar.gz#/ft_bbs-1.0/nntp.c

This is nntp.c in view mode; [Download] [Up]

/* $Id$ */
#ifdef NNTPNEWS

#include "bbs.h"

int nntp_postarticle(const char *hdrstr, const char *bodyfile,
                     newsstattyp *newsstat, const confrecordtyp *confrecord)
{
  int fd, n, k, p;
  SIZE_T len;
  SSIZE_T bytes;
  char c1, c2, inbuf[BUFSIZE], outbuf[BUFSIZE];
  const char *sp;

  len = strlen(hdrstr);
  if (len < 4)  return -1;
  if ((fd=open(bodyfile,O_RDONLY)) < 0) {
    bgerror("nntp_postarticle","open %s: %m",bodyfile);
    return -1;
  }
  n = nntp_ask(NULL,newsstat,"POST");
  if (n == CONT_POST) {
    p = 0;
    for (sp=hdrstr; *sp; sp++) {
      if (*sp == '\n') {
        outbuf[p++] = '\r';
      }
      outbuf[p++] = *sp;
      if (p > BUFSIZE-8) {
        writen(newsstat->sock,outbuf,p);
        p= 0;
      }
    }
    if (hdrstr[len-1] != '\n' || hdrstr[len-2] != '\n') {
      outbuf[p++] = '\r';
      outbuf[p++] = '\n';
      outbuf[p++] = '\r';
      outbuf[p++] = '\n';
    }
    c1 = ' ';
    while ((bytes=read(fd,inbuf,BUFSIZE)) > 0) {
      for (k=0; k < bytes; k++) {
        c2 = inbuf[k];
        if (c2 == '\n') {
          outbuf[p++] = '\r';
        }
        else if (c2 == '.' && c1 == '\n') {
          outbuf[p++] = '.';
        }
        outbuf[p++] = c2;
        c1 = c2;
        if (p > BUFSIZE-8) {
          writen(newsstat->sock,outbuf,p);
          p= 0;
        }
      }
    }
    if (c1 != '\n') {
      outbuf[p++] = '\r';
      outbuf[p++] = '\n';
    }
    outbuf[p++] = '.';
    outbuf[p++] = '\r';
    outbuf[p++] = '\n';
    writen(newsstat->sock,outbuf,p);
    n = nntp_getresponse(inbuf,BUFSIZE,newsstat);
    if (n != OK_POSTED) {
      bgerror("nntp_postarticle","posting failed");
    }
    return n;
  }
  else if (n == ERR_NOPOST) {
    bgerror("nntp_postarticle","Posting not allowed");
  }
  else {
    bgerror("nntp_postarticle","POST failed");
  }
  return n;
}


int nntp_getarticle(char **header, char *file, const boolean bodyonly,
                    const int articlenumber, newsstattyp *newsstat,
                    const confrecordtyp *confrecord)
{
  int n, fd;
  SIZE_T hlen, len;
  char *buf, c;

  n = nntp_ask(NULL,newsstat,"STAT %d",articlenumber);
  if (n == OK_NOTEXT) {
    n = nntp_ask(NULL,newsstat,"HEAD");
    if (n ==OK_HEAD) {
      *header = nntp_copytext(&hlen,newsstat);
    }
    else {
      bgerror("nntp_getarticle","HEAD failed");
      return -1;
    }
    n = nntp_ask(NULL,newsstat,"BODY");
    if (n == OK_BODY) {
      buf =  nntp_copytext(&len,newsstat);
      scratchfilename(file,"news",NULL,confrecord->scratchdir);
      if ((fd=open(file,O_CREAT|O_RDWR|O_TRUNC,0600)) < 0) {
        bgerror("nntp_getarticle","open %s: %m",file);
        free(*header);
        return -1;
      }
      if (! bodyonly) {
        write(fd,*header,hlen);
        c = '\n';
        write(fd,&c,1);
      }
      write(fd,buf,len);
      close(fd);
      free(buf);
      return 0;
    }
    else {
      bgerror("nntp_getarticle","HEAD failed");
      free(*header);
      return -1;
    }
  }
  else {
    bgerror("nntp_getarticle","STAT %d: failed",articlenumber);
    return -1;
  }
  return 0;
}


int nntp_getoverview(grouptyp *groupstat, const boolean unread_only,
                     newsstattyp *newsstat, const confrecordtyp *confrecord)
{
  int n, first_art;
  SIZE_T len, anz;
  char *splits[9], *buf, *sp1, *sp2, answer[NNTP_STRLEN+1], sstr[81];

  if (! newsstat->group_is_set) {
    n = nntp_ask(answer,newsstat,"GROUP %s",groupstat->groupname);
    if (n == OK_GROUP) {
      newsstat->group_is_set = TRUE;
      splitstring(splits,answer,' ',4);
      groupstat->anz_article = atoi(splits[1]);
      groupstat->first_article = atoi(splits[2]);
      groupstat->last_article = atoi(splits[3]);
    }
    else if (n == ERR_NOGROUP) {
      bgerror("nntp_getoverview","GROUP %s: not existent",
               groupstat->groupname);
      return -1;
    }
    else {
      bgerror("nntp_getoverview","GROUP %s: failed",groupstat->groupname);
      return -1;
    }
  }

  if (unread_only) {
    if (lookupnewsrcdb(newsstat->newsrcdb,groupstat->groupname,0,sstr,&len,
			confrecord) == 0) {
      if ((sp1=strchr(sstr,'-')) != NULL) {
	sp1++;
      }
      else {
	sp1 = sstr;
      }
      if (*sp1 != '\0') {
	first_art = atoi(sp1) + 1;
      }
      else {
	first_art = 0;
      }
    }
    else {
      first_art = 0;
    }
  }

  if (first_art < groupstat->first_article || ! unread_only) {
    first_art = groupstat->first_article;
  }
  if (first_art > groupstat->last_article || first_art == 0) {
    return ERR_NONEXT;
  }
   
  n = nntp_ask(NULL,newsstat,"XOVER %d-%d",first_art,groupstat->last_article);
  if (n == OK_NOV) {
    buf = nntp_copytext(&len,newsstat);
    if (len == 0)  return ERR_NONEXT;
    groupstat->ov_liste = (tlistetyp *)0;
    anz = 0;
    sp1 = buf;
    while (*sp1) {
      n = 0;
      for (sp2=sp1; *sp2 && *sp2 != '\n'; sp2++) {
	if (*sp2 == '\t')  n++;
      }
      if (*sp2)  *sp2++ = '\0';
      if (n >= 7) {
	addstrtoliste(&groupstat->ov_liste,TRUE,anz++,TL_BLOCKLEN,sp1,
		      confrecord);
      }
      else {
        bgerror("nntp_getoverview","group %s: wrong overview line: %s",
	        groupstat->groupname,sp1);
      }
      sp1 = sp2;
    }
    groupstat->ov_anz = anz;
    free(buf);
    return OK_NOV;
  }
  else {
    bgerror("nntp_getoverview","XOVER %s: failed",groupstat->groupname);
    return -1;
  }

  return 0;
}

#endif

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.