
#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=Name/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 },
        { "FileName"     , KW_STRING , UMSTAG_WFileName     , 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 },
        { "TempFileName" , KW_STRING , UMSTAG_WTempFileName , 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);
}
