/* Copyright (C) 1995 NetWin World, New Zealand, All rights reserved. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "dnews.h"
#include "conf.h"
#include "lib.h"
#include "emsg.h"
#include "nntp.h"
void nprintf(int chan,char * arg_list, ...);

int article_read(void);
int article_save(void);
int article_send(void);
void nprintf(int chan,char * arg_list, ...);
int ngetline(int chan, char *bf);
int article_munge(void);

#ifndef TRUE
#define FALSE 0
#define TRUE (!FALSE)
#endif
char *hide_data(char *a, char *b, char *c);
char *unhide_data(char *s);
int debug_lvl;
char dnews_conf[BFSZ];
int do_register(void);
static FILE *fin;
static char tosite[BFSZ];
static char togroup[BFSZ];
static char infile[BFSZ];
static char approved[BFSZ];
static char expires[BFSZ];
static int isapproved;
static int chan;
FILE *flog;
char logfile[300];
static int article_ok;
int main(int argc, char *argv[])
{
	char bf[300];
	static char bf2[300];
	char out[1001];
	char myname[300];
	int c;
	char *s;
	int i,n;

	if (argc<2) {
	 	printf("Usage: drobot -to nntp.site[:port] [-approved me@x.y] [-group comp.os.vms] [-f filename] \n");
		goto ret;
	}

	for (i=1; i<argc; i++) {
		if (strcmp(argv[i],"-f")==0) {strcpy(infile,argv[++i]);}
		else if (strcmp(argv[i],"-approved")==0) {isapproved = TRUE; strcpy(approved,argv[++i]);}
		else if (strcmp(argv[i],"-expires")==0) {strcpy(expires,argv[++i]);}
		else if (strcmp(argv[i],"-to")==0) {strcpy(tosite,argv[++i]);}
		else if (strcmp(argv[i],"-group")==0) {strcpy(togroup,argv[++i]);}
	}

	/* Open the input file if it isn't stdin*/
	strcpy(bf,togroup);
	for (s=bf;*s!=0; s++) {
		if (*s=='.') *s = '_';
		if (*s=='+') *s = '_';
		if (*s=='-') *s = '_';
	}
	sprintf(logfile,"%s.log",bf);
	

	fin = stdin;
	if (strlen(infile)!=0) {
		fin = fopen(infile,"r");
		if (fin==NULL) {perror(infile); goto ret;}
	}
	emsg("Read article\n");
 	article_ok = article_read();
	emsg("Read article done\n");
 	 

	nntp_startup();
	nntp_alwaysblock();
	chan = nntp_open(tosite); 
	if (chan<0) {
		emsg("Couldn't open nntp to == {%s}\n",tosite);
		emsg("Saving {%s}\n",tosite);
	 	article_save(); goto ret;
	}
	nntp_setblock(chan,TRUE); /* Set to blocking IO */

	if (!article_ok) {emsg("Couldn't read article\n"); goto ret;}
	if (!article_munge()) {article_save(); goto ret;}
	if (!article_send()) {article_save();}
	
 ret: emsg("drobot exiting\n");
 	return 0;
}
#define BIGBF 10000
static String *article;
#define matches(a,b) (strncmp(a,b,strlen(b))==0)

int article_pread()
{
	char *content,*tmp;
	int		contentLength,i;
	int		x;
	char *s;

	emsg("Pread\n");
	article = str_new();
	s =  getenv("CONTENT_LENGTH");
	if (s!=NULL) contentLength = atoi( getenv("CONTENT_LENGTH"));
	else contentLength = 10000;



	// Read the mail message from STDIN into a buffer...
	content = (char *)mymalloc( contentLength+1 );
	tmp = content;


	while ((x = fgetc( stdin )) != EOF) {
		*tmp++ = x;
		if ((tmp-content)>=contentLength) break;
	}
	*tmp = '\0';

	emsg("Pread done\n");
	str_addsn(article,content);
}		


#define EOL "\015\012"
#define addline(xx) {strcat(xout,xx); strcat(xout,EOL); xout += strlen(xx)+2;}
static char subject[BFSZ];
int article_munge(void)
{
	char *s,*s2;
	char *out;
	char *xout;
	int p;
	int r = TRUE;
	int donehead = FALSE;
	int done_extras = FALSE;
	int gotreply = FALSE;
	char from[BFSZ];
	char bf[BFSZ];
	char *x;

	out = mymalloc(str_len(article)+30000);
	xout = out;
	s = str_s(article);
	s2 = strchr(s,'\012');
	for (;s2!=NULL;) {
		*s2 = 0;
		strcpy(bf,s);
		s = strchr(bf,'\015'); if (s!=NULL) *s = 0;
		s = strchr(bf,'\012'); if (s!=NULL) *s = 0;
		if (strcmp(bf,".")==0) strcpy(bf,".."); /* convert single .'s */
		if (matches(bf,"Control:")) {emsg("Rejecting control message\n"); return FALSE; }
		if (matches(bf,"Newsgroups:")) if (strlen(togroup)>0) goto cont;
		if (matches(bf,"Approved:")) if (strlen(approved)>0) goto cont;
		if (matches(bf,"Expires:")) if (strlen(expires)>0) goto cont;
		if (matches(bf,"Subject:")) {strcpy(subject,bf+8);}
		if (matches(bf,"To:")) goto cont; /* Illegal news headers */
		if (matches(bf,"Cc:")) goto cont; /* Illegal news headers */
		if (strlen(bf)==0) if (!done_extras) {
			done_extras = TRUE;
			if (strlen(expires)>0) {
				sprintf(bf,"Expires: %s",expires); 
				addline(bf);
			}
			if (strlen(approved)>0) {
				sprintf(bf,"Approved: %s",approved);
				addline(bf);
			}
			if (strlen(togroup)>0) {
				sprintf(bf,"Newsgroups: %s",togroup); 
				addline(bf);
			}
			sprintf(bf,"X-Gated-To: %s",tosite);  addline(bf);
			strcpy(bf,"");
		}
		addline(bf);

cont:		s = s2 + 1;
		s2 = strchr(s,'\012');
	}
	str_copysn(article,out);
	return TRUE;	
}
int article_read(void)
{
	char bf[BIGBF];
	int done_extras = FALSE;
	int cnt;
	char *s;

	if (strlen(infile)==0) return article_pread();

	article = str_new();
 	for (cnt=0;!feof(fin);cnt++) {
	  if (fgets(bf,BIGBF-10,fin)!=NULL) {
		s = strchr(bf,'\015'); if (s!=NULL) *s = 0;
		s = strchr(bf,'\012'); if (s!=NULL) *s = 0;
		s = bf + strlen(bf);
		strcpy(s,"\015\012");
		str_addsn(article,bf);
	  }
	}
		
	fclose(fin);
	return TRUE;	
}
int article_save(void)
{
	FILE *f;
	char bf[BFSZ];
	char fname[BFSZ];
	static int upto;

 	f = fopen("failed.cnt","r");
	if (f!=NULL) {
		fgets(bf,BFSZ-10,f);
		fclose(f);
	}
	upto = atoi(bf);
	upto++;
	f = fopen("failed.cnt","w");
	if (f!=NULL) {
		fprintf(f,"%d\n",upto);
		fclose(f);
	}
	sprintf(fname,"fail_%d.itm",upto);
	emsg("Saving failed article to file {%s} \n",fname);
	f = fopen(fname,"w");
	if (f==NULL) {perror(fname); return FALSE;}
	fwrite(str_s(article),1,str_len(article),f);
	fclose(f);
	return TRUE;

}
int article_send(void)
{
	char bf[BFSZ];
	if (!ngetline(chan,bf)) {emsg("Error:1 channel closed\n"); return FALSE;}
	if (atoi(bf)!=200) {emsg("Error, posting not ok: %s",bf); return FALSE;}
	nprintf(chan,"post\015\012");
	if (!ngetline(chan,bf)) {emsg("Error:2 channel closed\n"); return 0;}
	if (atoi(bf)!=340) {emsg("Error:3 %s",bf); return FALSE;}
	nntp_write(chan,article);
	nprintf(chan,".\015\012");
	if (!ngetline(chan,bf)) {emsg("Error:4 channel closed\n"); return 0;}
   	if (atoi(bf)!=240) {emsg("Error:5 %s",bf); return FALSE;}
	emsg("Article successfully posted :-) {%s}\n",subject);
	return TRUE;
}
void nprintf(int chan,char * arg_list, ...)
{
	char *s;
 	va_list arg_ptr;
 	char *format, output[1000];
	int len;
 	va_start(arg_ptr, arg_list);
 	format = arg_list;
	vsprintf(output, format, arg_ptr);
	nntp_write_s(chan,output,strlen(output));
	printf("nntpcmd [%d] %s ",chan,output); 
}
int ngetline(int chan, char *bf)
{
	int n;
	n = nntp_read(chan,bf,500);
	if (n<0) return FALSE;
	return TRUE;	 	
}

char *group_name(int i)
{
	return "(none)";
}


void log_write(char *bf);
void dmsg(char * arg_list, ...)
{
	return;
}
void filemsg(char * arg_list, ...)
{
 	va_list arg_ptr;
 	char *format, output[1000];
	int len;
 	va_start(arg_ptr, arg_list);
 	format = arg_list;
	vsprintf(output, format, arg_ptr);
	perror("File error:");
	printf("%s",output);
	log_write(output);

}
void imsg(char * arg_list, ...)
{
 	va_list arg_ptr;
 	char *format, output[1000];
	int len;
 	va_start(arg_ptr, arg_list);
 	format = arg_list;
	vsprintf(output, format, arg_ptr);
/* printf("%s",output); */
	log_write(output);
}
void wmsg(char * arg_list, ...)
{
 	va_list arg_ptr;
 	char *format, output[1000];
	int len;
 	va_start(arg_ptr, arg_list);
 	format = arg_list;
	vsprintf(output, format, arg_ptr);
	printf("%s",output);
	log_write(output);
}
void emsg(char * arg_list, ...)
{
 	va_list arg_ptr;
 	char *format, output[1000];
	int len;
 	va_start(arg_ptr, arg_list);
 	format = arg_list;
	vsprintf(output, format, arg_ptr);
	printf("%s",output);
	log_write(output);
}
void log_write(char *bf)
{
	if (strlen(logfile)==0) return;
	flog = fopen(logfile,"a");
	if (flog!=NULL) {
		fprintf(flog,"%s",bf);
		fclose(flog);
	}
}
#ifndef unix
int lib_mail_file(char *to, char *subj, char *fname)
{
	return TRUE;
}
int lib_freespace(char *s)
{
	return 100000;
}
#endif
int diskuse_get(void)
{
	return 0;
}
char *nt_pcname(void);

char *lib_findfile(char *x)
{
	return NULL;
}
void dnews_manager_report(char *s)
{
	
}
int post_local(void) /* String *xitem, char *addr, int ismod); */
{
	return TRUE;
}
void dnews_exit(char *reason, char *file, int line)
{
	printf("Crashing\n");
	exit(1);
}



#ifdef WIN32
#define KEY_COMPUTER_NAME "SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName"
#include <windows.h>
#include <winnt.h>
char *nt_pcname(void)
{
    HKEY MyKey;
	static    char Line[64];
    int  linelen = 64;
    DWORD type_of_entry, result;

	RegCreateKey(HKEY_LOCAL_MACHINE, KEY_COMPUTER_NAME, &MyKey);
	result = RegQueryValueEx(MyKey, "ComputerName", 0, &type_of_entry, 
		(unsigned char *)Line, &linelen);
	RegCloseKey(MyKey);
	if (result == ERROR_SUCCESS && type_of_entry == REG_SZ) {
   		return Line;
	}
}

#endif


