
#include "sumstl.h"

#include <stdio.h>
#include <ctype.h>

#include "date.h"

/* SMAKE */

// Version String
// --------------

static char VersionString[] = "$VER: sumswrite "VERSION;

static char UsageString[] = "\
  U=User      : user name.\n\
  P=Password  : user's password.\n\
  S=Server    : server name.\n\n\
Message will be read from standard input. See docs for file format.\n\n\
";


// Template
// --------

static char *TemplateString = "U=User/A,P=Password/A,S=Server/K";
enum opts {
	OPT_USER, OPT_PASSWORD, OPT_SERVER,
	OPT_COUNT};
static LONG opts[OPT_COUNT];


// Globals
// -------

extern struct DosLibrary *DOSBase;

struct Library *UMSBase = NULL;
UMSAccount acc = NULL;

#define KW_STRING  0
#define KW_NUMBER  1
#define KW_BOOLEAN 2
#define KW_DATE    3

struct Keyword
{
	char *name;
	LONG type;
	LONG tag;
	APTR data;
} Keywords[]=
{
	{ "MsgNum"       , KW_NUMBER , UMSTAG_WMsgNum       , NULL },
	{ "MsgDate"      , KW_DATE   , UMSTAG_WMsgDate      , NULL },
	{ "ChainUp"      , KW_NUMBER , UMSTAG_WChainUp      , NULL },
	{ "HardLink"     , KW_NUMBER , UMSTAG_WHardLink     , NULL },
	{ "SoftLink"     , KW_NUMBER , UMSTAG_WSoftLink     , NULL },
	{ "AutoBounce"   , KW_BOOLEAN, UMSTAG_WAutoBounce   , NULL },
	{ "HdrFill"      , KW_NUMBER , UMSTAG_WHdrFill      , NULL },
	{ "TxtFill"      , KW_NUMBER , UMSTAG_WTxtFill      , NULL },
	{ "NoUpdate"     , KW_BOOLEAN, UMSTAG_WNoUpdate     , NULL },
	{ "FromName"     , KW_STRING , UMSTAG_WFromName     , NULL },
	{ "FromAddr"     , KW_STRING , UMSTAG_WFromAddr     , NULL },
	{ "ToName"       , KW_STRING , UMSTAG_WToName       , NULL },
	{ "ToAddr"       , KW_STRING , UMSTAG_WToAddr       , NULL },
	{ "MsgID"        , KW_STRING , UMSTAG_WMsgID        , NULL },
	{ "CreationDate" , KW_STRING , UMSTAG_WCreationDate , NULL },
	{ "ReceiveDate"  , KW_STRING , UMSTAG_WReceiveDate  , NULL },
	{ "ReferID"      , KW_STRING , UMSTAG_WReferID      , NULL },
	{ "Group"        , KW_STRING , UMSTAG_WGroup        , NULL },
	{ "Subject"      , KW_STRING , UMSTAG_WSubject      , NULL },
	{ "Attributes"   , KW_STRING , UMSTAG_WAttributes   , NULL },
	{ "Comments"     , KW_STRING , UMSTAG_WComments     , NULL },
	{ "Organization" , KW_STRING , UMSTAG_WOrganization , NULL },
	{ "Distribution" , KW_STRING , UMSTAG_WDistribution , NULL },
	{ "Folder"       , KW_STRING , UMSTAG_WFolder       , NULL },
	{ "FidoID"       , KW_STRING , UMSTAG_WFidoID       , NULL },
	{ "MausID"       , KW_STRING , UMSTAG_WMausID       , NULL },
	{ "ReplyGroup"   , KW_STRING , UMSTAG_WReplyGroup   , NULL },
	{ "ReplyName"    , KW_STRING , UMSTAG_WReplyName    , NULL },
	{ "ReplyAddr"    , KW_STRING , UMSTAG_WReplyAddr    , NULL },
	{ "LogicalToName", KW_STRING , UMSTAG_WLogicalToName, NULL },
	{ "LogicalToAddr", KW_STRING , UMSTAG_WLogicalToAddr, NULL },
	{ "RFCMsgNum"    , KW_STRING , UMSTAG_WRFCMsgNum    , NULL },
	{ "FidoText"     , KW_STRING , UMSTAG_WFidoText     , NULL },
	{ "ErrorText"    , KW_STRING , UMSTAG_WErrorText    , NULL },
	{ "Newsreader"   , KW_STRING , UMSTAG_WNewsreader   , NULL },
	{ "RFCAttr"      , KW_STRING , UMSTAG_WRfcAttr      , NULL },
	{ "FTNAttr"      , KW_STRING , UMSTAG_WFtnAttr      , NULL },
	{ "ZerAttr"      , KW_STRING , UMSTAG_WZerAttr      , NULL },
	{ "MausAttr"     , KW_STRING , UMSTAG_WMausAttr     , NULL },
	{ NULL,0,0,0 }
};


// CTRL-C Stuff
// ------------

VOID chkabort(VOID) {}
#define ABORTED (SetSignal(0,0) & SIGBREAKF_CTRL_C)


struct Keyword *FindKeyword(UBYTE *name)
{
	struct Keyword *k;
	for (k=Keywords;k->name;k++)
		if (!strnicmp(name,k->name,strlen(k->name))) return(k);
	return(NULL);
}


BOOL GetTrueFalse(char *str)
{
	if (!stricmp(str,"true") || !stricmp(str,"on") || !stricmp(str,"yes") || !stricmp(str,"ein") || !stricmp(str,"an") || !stricmp(str,"ja"))
		return(TRUE);
	else
		return(FALSE);
}


BOOL HandleLine(char *line)
{
	struct Keyword *k;
	int len=strlen(line);
	if (!len) return(TRUE);
	if (line[len-1]=='\n') line[len-1]=0;
	if (!(k=FindKeyword(line))) return(FALSE);
	line+=strlen(k->name);
	while (isspace(*line)) line++;
	if (*line=='=') line++;
	while (isspace(*line)) line++;
	if (!*line && k->type==KW_BOOLEAN) line="true";
	if (!*line) return(TRUE);
	switch (k->type)
	{
		case KW_STRING:	k->data = strdup(line);
								break;
		case KW_NUMBER:	k->data = (APTR)atol(line);
								break;
		case KW_BOOLEAN:	k->data = (APTR)(*line ? GetTrueFalse(line) : TRUE);
								break;
		case KW_DATE:		k->data = (APTR)DateToSeconds(line);
								break;
	}
	return(TRUE);
}


// Main Function
// -------------

int main(int argc,char *argv[])
{
	static char buffer[256];
	static struct TagItem Tags[30];
	int erg = RETURN_FAIL;
	BOOL text=FALSE;
	char *textbuf=NULL,*newbuf,*tptr;
	int textbufsize=0,textlen=0,c;
	struct RDArgs *args_ptr;

	if (argc<2 || *argv[1] == '?')
		fprintf(stderr,"\33[1m%s\33[0m, written by Stefan Stuntz, Public Domain\n\nTemplate: %s\n%s",&VersionString[6],TemplateString,UsageString);

	{
		int i;

		for (i=0; i<OPT_COUNT; i++)
		opts[i]=NULL;
	}

	if (args_ptr = ReadArgs(TemplateString, opts, NULL))
	{
		if (UMSBase = OpenLibrary(UMSNAME,UMSVERSION))
		{
			if (acc = UMSRLogin((char *)opts[OPT_SERVER],(char *)opts[OPT_USER],(char *)opts[OPT_PASSWORD]))
			{
				while (!feof(stdin))
				{
					if (text)
					{
						if ((c=fgetc(stdin))==EOF) break;
						if (textlen==textbufsize)
						{
							if (!(newbuf=malloc(textbufsize+10001))) { text=FALSE; break; }
							if (textbuf)
							{
								CopyMem(textbuf,newbuf,textbufsize);
								free(textbuf);
							}
							textbuf=newbuf;
							textbufsize+=10000;
							tptr=textbuf+textlen;
						}
						*tptr++=c;
						textlen++;
					}
					else
					{
						if (fgets(buffer,255,stdin))
						{
							if (buffer[0]=='-')
							{
								text=TRUE;
							}
							else if (!HandleLine(buffer))
							{
								fprintf(stderr,"\7Invalid line: \"%s\"\n",buffer);
							}
						}
					}
				}

				if (text)
				{
					struct Keyword *k;
					struct TagItem *t=Tags;
					for (k=Keywords;k->name;k++)
					{
						if (k->data)
						{
							t->ti_Tag  = k->tag;
							t->ti_Data = (LONG)((k->tag==UMSTAG_WGroup && k->data && !stricmp(k->data,"Netmail") ? NULL : (LONG)k->data));
							t++;
						}
					}
					t->ti_Tag  = UMSTAG_WMsgText;
					t->ti_Data = (LONG)textbuf;
					t++;
					t->ti_Tag = TAG_DONE;

					*tptr=0;

					if (UMSWriteMsg(acc,Tags))
					{
						printf("Message written.\n");
						erg=0;
					}
					else
						fprintf(stderr,"\7UMS-Error %ld: %s\n",UMSErrNum(acc),UMSErrTxt(acc));
				}
				else
					fprintf(stderr,"\7Missing message text.\n");

				UMSLogout(acc);
			}
			else printf("\7UMS-Login failed.\n");


			CloseLibrary(UMSBase);
		}
		else printf("\7Could not open ums.library V10.\n");

		FreeArgs(args_ptr);
	}
	else
	{
		PrintFault(IoErr(), NULL);
		return(RETURN_ERROR);
	}

	return(erg);
}
