
Turn naked '\r' into 'crlf' (only needed in header)
inbody = We know if we are in the body of a message.
Input is:
        s1 = xbuf[c];
        s1[xn[c]] = 0;   
If inbody, then split of a packet not including the ending dot.
Always add the cr if it's missing
If not inbody, then add lf if it's missing after a 'cr'
	chan_read(c,s1,rlen);
Move remainder to start of buffer
        memmove(xbuf[c],s1,strlen(s1)+1); 
If more than 1 second gone, or busy or pending or outsz, then stop for the moment.
		if ((k%1000) == 999) if ((lib_gmtime()-start)>1) goto stopit;
		if (nntp_getbusy(c) || nntp_getpending(c) || nntp_outsz(c)>100000)  {
		/* --  Then must leave the rest until next time. -- */
			chan_more[c] = FALSE;
			if (s2!=NULL) chan_more[c] = TRUE;



void chan_dorest(int chan)
{
	int inbody;
	static char rec[MAXREC+10];
	int len;
	int start;
	char *s1;
	char *lastlf;
	char savedc;
	register char cc;
	register char *s;
	int k=0;
	
        if (xn[c]<=0) return; /* Nothing to process */
	inbody = chan_inbody(c);

	start = lib_gmtime();
        s1 = xbuf[chan];
        s1[xn[chan]] = 0;   

	for (;TRUE;k++) {
		/* If in body, search for dot or last end of line */
		if (inbody) {
			lastlf = NULL;
			cc = *s1;
			for (s=s1;cc!=0;s++) {
				cc = *s;
				if (cc=='\n') lastlf = s;
				if (cc=='.') {
					if (s==s1) goto notbody;
					if (s[-1]=='\n') {
						if ((s[1]=='\r') || (s[1]=='\n') || (s[1]==0)) {
							lastlf = s-1;
							break;
						}
					}
				}
			}
			if (lastlf==NULL) break;
		/* else Search for end of line */
		} else {
notbody:
			inbody = FALSE;
			lastlf = NULL;
			cc = *s1;
			for (s=s1;cc!=0;s++) {
				cc = *s;
				if (cc=='\n') break;
			}
			lastlf = s;
		}
		/* Add missing cr */
		if ((lastlf==s1) || (lastlf[-1]!='\r')) {
			len = lastlf-s1;
			if (len>=MAXREC) len = MAXREC-1;
			ncpy(rec,s1,len);
			strcpy(rec+len-1,"\r\n");
			len++;
			chan_read(chan,rec,len);
		} else {	/* Process normal block */ 
			savedc = *lastlf;
			*lastlf = 0;
			chan_read(chan,s1,rlen);
			*lastlf = savedc;
		}
		inbody = chan_inbody(chan);
		/* End of input buffer  */
		if (*lastlf==0) break;

		/* Check for end conditions */	
	
		if ((k%1000) == 999) if ((lib_gmtime()-start)>1) goto stopit;
		if (nntp_getbusy(c) || nntp_getpending(c) || nntp_outsz(c)>100000)  {
			/* --  Then must leave the rest until next time. -- */
stopit:			chan_more[c] = TRUE;
			break;
		}		
		
		/* Around the loop again */
			
		s1 = lastlf+1;
	}
	/* Move remainder to start of buffer */
	if (*lastlf==0) {
		xn[c] = 0;
		strcpy(xbuf[c],"");
	} else {
	        memmove(xbuf[c],s1,strlen(s1)+1); 
		xn[c] = strlen(s1);
	}
}



void chan_dorest(int c)
{
	static char rec[MAXREC];
	int rlen;
	char cc,b;
        char *s1,*s2,*s3,*s4;
	int start,k;
	int inbody;
	char save;

	vtrace();
	inbody = chan_inbody(c);
	start = lib_gmtime();
        s1 = xbuf[c];
        s1[xn[c]] = 0;   

	for (s4=s1;TRUE;s4++) {
		b = *s4;
		if (b==0) return;
		if (b=='\n') break;
		if (b=='\r') {
			if (s4[1]==0) {
				return;
			}
			if (s4[1]=='\n') {s4++; break;}
			break;
		}
	}
	s2 = s4;

	for (k=1;s2!=NULL;k++) { /*loop*/
        	rlen = s2-s1+1;
		/* If getting body, and this line doesnt 
		start '.'  and rec isn't too big and 
		next line is not a dot, then

		*/
		if (inbody) {
			if (rlen<2) goto donormal;
			if (*s2=='\r') goto donormal;
		}

		if (inbody) if (s1[0]!='.') if ((s2-s1)<(MAXREC-100)) if (s2>s1) if (s2[-1]=='\r') if (s2[1]!='.') {
again:
		/* If this is normal end of lien, and next line
		doesn't start with a dot */
			if (s2[-1]=='\r') if (s2[1]!='.') {
		/* Search for end of next line */
				for (s3=s2+1;*s3!=0;s3++) {
					b = *s3;
					if (b=='\n') break;
					if (b=='\r') {
						if (s3[1]=='\n') {
							s3++;
							break;
						} else {
							inbody = FALSE;
							goto dochunk;
						}
					}
				}
				if ((s3-s2)<(MAXREC-100)) if (*s3=='\n') {
					s2 = s3;
					goto again;
				}
			} else inbody = FALSE;
		/* Send chunk without copying it */
dochunk:		stat_start(X_CHREAD);
	        	rlen = s2-s1+1;
			save = s1[rlen];
			s1[rlen] = 0;
/*
ncpy(rec,s1,50);
emsg("chan_chunk %d bytes (%s)\n",rlen,rec);
*/

			chan_read(c,s1,rlen);
			s1[rlen] = save;
			stat_end(X_CHREAD);
			xn[c] -= rlen;
			goto endline;
		}	
		
donormal:		
		
		if (rlen>=(MAXREC-100)) {
                      emsg("Record too big %d \n",rlen);
                      rlen = MAXREC-100;
        	}
		cc = s1[rlen];
		s1[rlen] = 0;
		strcpy(rec,s1); 
		s1[rlen] = cc;
/*		dmsg("chanrec: Got rec xn[%d]=%d (%d) \n",c,xn[c],rlen);*/
		xn[c] -= rlen;
		if (rlen>1) if (rec[rlen-2]!='\r') { /* add CR if missing */
		        strcpy(rec+rlen-1,EOL); rlen++;
		}
		if (rlen==1) if (rec[rlen-1]=='\n') { /* add CR if missing */
		        strcpy(rec+rlen-1,EOL); rlen++;
		}
		if (rlen==1) if (rec[rlen-1]=='\r') { /* add CR if missing */
		        strcpy(rec+rlen-1,EOL); rlen++;
		}
		stat_start(X_CHREAD);
		chan_read(c,rec,rlen);
		stat_end(X_CHREAD);
endline:
		inbody = chan_inbody(c);
		s1 = s2 + 1;
		/*for (s2=s1;*s2!=0;s2++) if (*s2=='\n') break;*/
		for (s2=s1;TRUE;s2++) {
			b = *s2;
			if (b==0) break;
			if (b=='\r') {
				if (s2[1]=='\n') {s2++; break;}
				if (s2[1]==0) {
					s2++; /* so it stops processing lines as we have a partial line */
				}
				break;
			}
			if (b=='\n') break;
		}
		if (*s2==0) s2 = NULL;
		if ((k%1000) == 999) if ((lib_gmtime()-start)>1) goto stopit;
		if (nntp_getbusy(c) || nntp_getpending(c) || nntp_outsz(c)>100000)  {
stopit:;		/* --  Then must leave the rest until next time. -- */
			chan_more[c] = FALSE;
			if (s2!=NULL) chan_more[c] = TRUE;

			break;
		}
	}
        memmove(xbuf[c],s1,strlen(s1)+1); 
}
