/*  QWKExport.c
 */

#include <exec/types.h>
#include <clib/exec_protos.h>
#include <dos/dos.h>
#include <dos/datetime.h>
#include <clib/dos_protos.h>
#include <libraries/ums.h>
#include <clib/ums_protos.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <fcntl.h>

#include "QWKExport.v"

extern ULONG *RDArgs_Array;
char *RDArgs_Template = "SITE/A,PASSWORD,SERVER/K,ADD/S";
char *RDArgs_Help =
"$VER: QWKExport "__VERSION__" ("__COMMODORE_DATE__") © 1993, 1994 Iain Hibbert\n"
"\n"
"  SITE         BBS to Export to (\"qwk.\" is prepended to make the username)\n"
"  PASSWORD     Password\n"
"  SERVER       Server\n"
"  ADD          Add to a .REP packet, if one is already present\n"
"\n";

#define Site        ((char *)RDArgs_Array[0])
#define Password    (RDArgs_Array[1] ? (char *)RDArgs_Array[1] : "")
#define Server      ((char *)RDArgs_Array[2])
#define Add         ((BOOL)RDArgs_Array[3])

void chkabort(void) { } // disable ^C checking for DICE

//  ReadUMSVar()
//              a wrapper for ReadUMSConfig that is guaranteed to return
//  a default, just so I don't have to check the return value.
//
char *
ReadUMSVar(UMSUserAccount login, char *varname, char *def)
{
char *t1 = ReadUMSConfigTags(login, UMSTAG_CfgName, varname, TAG_DONE);
char *t2 = NULL;

    if( t1 ) {
        t2 = strdup(t1);
        FreeUMSConfig(login, t1);
    }

    return( t2 ? t2 : def);
}

//  command()
//           takes printf style arguments, assembles the command in its
//           buffer, prints it in highlighted colour, and executes it.
void
command(char *fmt, ...)
{
va_list va;
char buffer[256];

    va_start(va,fmt);

    vsprintf(buffer, fmt, va);
    printf("\033[2m> %s\033[0m\n", buffer);
    system(buffer);

    va_end(va);
}

// do_Export()
//              do the actual exporting, to the supplied file handle; the
//              header is already written, since there may be other messages
//              in the file (with Add)
//              exports all messages with local flag 0 set.
void
do_Export(UMSUserAccount login, FILE *out, char *pvtarea)
{
long msgnum = 0;
char *from, *to, *text, *subject, *group, *attributes, *reader;
char fname[26], tname[26], block[128];
long date;
int area, count;
struct DateTime dt;
char datestr[LEN_DATSTRING], timestr[LEN_DATSTRING];

    while( msgnum = UMSSearchTags(login, UMSTAG_SearchLast, msgnum,
                                         UMSTAG_SearchLocal, TRUE,
                                         UMSTAG_SearchDirection, 1,
                                         UMSTAG_SearchMask, (1L<<0),
                                         UMSTAG_SearchMatch, (1L<<0),
                                         TAG_DONE) ) {

        if( ReadUMSMsgTags(login, UMSTAG_RMsgNum, msgnum,
//                                  UMSTAG_RNoUpdate, 1,
                                  UMSTAG_RFromName, &from,
                                  UMSTAG_RToName, &to,
                                  UMSTAG_RSubject, &subject,
                                  UMSTAG_RGroup, &group,
                                  UMSTAG_RMsgDate, &date,
                                  UMSTAG_RAttributes, &attributes,
                                  UMSTAG_RMsgText, &text,
                                  UMSTAG_RNewsreader, &reader,
                                  TAG_DONE) ) {

            if( group )
                sscanf(group, "qwk.%*[^.].%d", &area);
            else
                sscanf(pvtarea, "%d", &area);

            strncpy(fname, from, 25);
            fname[25] = '\0';
            strupper(fname);

            strncpy(tname, to ? to : "ALL", 25);
            tname[25] = '\0';
            strupper(tname);

            dt.dat_Stamp.ds_Days = date / 86400;
            dt.dat_Stamp.ds_Minute = (date % 86400) /60 ;
            dt.dat_Stamp.ds_Tick = 0;
            dt.dat_Format = FORMAT_USA;
            dt.dat_Flags = 0;
            dt.dat_StrDate = datestr;
            dt.dat_StrDay = NULL;
            dt.dat_StrTime = timestr;
            DateToStr(&dt);

            // msg header
            fprintf(out, "%c%-7d%-8.8s%-5.5s%-25.25s%-25.25s%-25.25s            %-8d%-6dá%c%c   ",
                !group || strstr(attributes, "private") ? '+' : ' ',
                area % 9999999,
                datestr,
                timestr,
                tname,
                fname,
                subject,
                msgnum % 99999999,
                ((127 + strlen(text) + strlen(reader) + 7) / 128 + 1) % 999999,
                area % 0xff,
                area / 0xff );

            // msg body
            count = 128;
            while( count == 128 ) {
                for( count = 0 ; count < 128 && text[count] ; count++ )
                    block[count] = (text[count] == '\n' ? 'ã' : text[count]);

                fprintf(out, "%.*s", count, block);
                text += 128;
            }

            // newsreader info and padding
            count += fprintf(out, "ã * %s *ã", reader);
            fprintf(out, "%*s", (128 - (count % 128)) % 128, "");

            UMSExportedMsg(login, msgnum);
            FreeUMSMsg(login, msgnum);
        }
        else {
            printf("UMS-Error: %3d, '%s'\n", UMSErrNum(login), UMSErrTxt(login));
            UMSCannotExport(login, msgnum, "Aaagh!");
        }
    }
}

int
main(int ac, char *av[])
{
char name[128];
UMSUserAccount login;

    sprintf(name, "qwk.%s", Site);
    login = UMSRLogin(Server, name, Password);

    if( login ) {
    int num = UMSSelectTags(login,
                    UMSTAG_SelMask,         UMSUSTATF_ViewAccess|UMSUSTATF_PostPoned|UMSUSTATF_Old,
                    UMSTAG_SelMatch,        UMSUSTATF_ViewAccess,
                    UMSTAG_SelWriteLocal,   TRUE,
                    UMSTAG_SelSet,          (1L<<0),
                    UMSTAG_SelUnset,        0,
                    TAG_DONE);

        printf("Found %d message%s for Export\n", num, (num == 1 ? "" : "s"));

        if( num ) {
        char *outbound = ReadUMSVar(login, "qwk.outbound", "Comms:Uploads/");
        char repname[256], msgname[256];
        char SITE[10];
        FILE *msg;

            strncpy( SITE, Site, 8);
            SITE[8] = '\0';
            strupper(SITE);

            if( chdir(outbound) == 0 ) {
                sprintf(repname, "%s.REP", SITE);
                sprintf(msgname, "%s.MSG", SITE);

                // clean up old files
                if( access(repname, 0) == 0 ) {
                    if( Add || stricmp(ReadUMSVar(login, "qwk.addpacket", "N"), "yes") == 0 )
                        command(ReadUMSVar(login, "qwk.unpacker", "lharc e %s"), repname);
                    else if( access(msgname, 0) == 0 )
                        command("delete %s force", msgname);

                    command("delete %s force", repname);
                }

                if( msg = fopen(msgname, "a") ) {
                    if( ftell(msg) == 0 )
                        fprintf(msg, "%-128.128s", SITE);

                    do_Export(login, msg, ReadUMSVar(login, "qwk.pvtarea", "0"));

                    fclose(msg);
                    command(ReadUMSVar(login, "qwk.packer", "lharc a %s %s"), repname, msgname);
                }
                else
                    fprintf(stderr, "Can't write to %s\n", msgname);
            }
            else
                fprintf(stderr, "Can't CD to %s\n", outbound);
        }

        UMSLogout(login);
    }
    else
        fprintf(stderr, "Can't login as %s\n", name);

    exit(0);
}
