MAILROOT.C

21.8 KB 8fc51de3d431a721…
/*--------------------------------------------------------------------------*/
/*                                                                          */
/*                                                                          */
/*      ------------         Bit-Bucket Software, Co.                       */
/*      \ 10001101 /         Writers and Distributors of                    */
/*       \ 011110 /          Freely Available<tm> Software.                 */
/*        \ 1011 /                                                          */
/*         ------                                                           */
/*                                                                          */
/*  (C) Copyright 1987-91, Bit Bucket Software Co., a Delaware Corporation. */
/*                                                                          */
/*                                                                          */
/*                 This module was written by Bob Hartman                   */
/*                                                                          */
/*                                                                          */
/*                   BinkleyTerm Mail Control Routines                      */
/*                                                                          */
/*                                                                          */
/*    For complete  details  of the licensing restrictions, please refer    */
/*    to the License  agreement,  which  is published in its entirety in    */
/*    the MAKEFILE and BT.C, and also contained in the file LICENSE.250.    */
/*                                                                          */
/*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
/*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
/*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
/*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
/*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
/*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
/*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
/*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
/*                                                                          */
/*                                                                          */
/* You can contact Bit Bucket Software Co. at any one of the following      */
/* addresses:                                                               */
/*                                                                          */
/* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
/* P.O. Box 460398                AlterNet 7:491/0                          */
/* Aurora, CO 80046               BBS-Net  86:2030/1                        */
/*                                Internet f491.n343.z1.fidonet.org         */
/*                                                                          */
/* Please feel free to contact us at any time to share your comments about  */
/* our software and/or licensing policies.                                  */
/*                                                                          */
/*--------------------------------------------------------------------------*/

/* Include this file before any other includes or defines! */

#include "includes.h"

char *estring (int, int);

int do_mail (ADDRP baddr, int type) /* 1 = manual, 0 = normal, -1 = CM */
{
    int i;

    long callstart, callend;
    long call_cost, call_cost_ths;

    long eh, em, es;

    b_init ();
    caller = 1;
    got_packet = 0;
    got_arcmail = 0;
    got_mail = 0;
    sent_mail = 0;
    no_WaZOO_Session = no_WaZOO;
    callstart = 0L;

#ifdef MILQ
    UsePaths = FALSE;
#endif

    (void) sprintf (junk, "%s", Full_Addr_Str (baddr));

    called_addr = remote_addr = *baddr;     /* structure assignment */
    SendMessage( node_hWnd, WM_COMMAND, GD_CRNT, (long)baddr );

    if (!net_params)
        {
        status_line (MSG_TXT(M_INSUFFICIENT_DATA));
        set_xy ("");
        return (0);
        }

    if (!nodeproc (junk))
        return (0);

    if (type > 0)
        {
        if (flag_file (TEST_AND_SET, &called_addr, 1))
            {
            if (CARRIER)
                mdm_hangup ();
            return (0);
            }

        if (CARRIER)                        /* called manually maybe? */
            goto process_the_damned_mail;   /* yup, just do some mail */


        do_dial_strings ();
        try_2_connect ((char *) (newnodedes.PhoneNumber));  /* try to connect */
        }
    else
        {
        /* If this is supposed to be only local, then get out if it isn't */
        if (type == 0)
           {
           if (e_ptrs[cur_event].behavior & MAT_LOCAL)
               {
               if (e_ptrs[cur_event].node_cost < 0)
                   {
                   if ((int) newnodedes.RealCost < -e_ptrs[cur_event].node_cost)
                       {
                       return (0);
                       }
                   }
               else
                   {
                   if ((int) newnodedes.RealCost > e_ptrs[cur_event].node_cost)
                       {
                       return (0);
                       }
                   }
               }
           /* If it is supposed to be 24 hour mail only, get out if it isn't */
           if ((newnodelist || version7) && 
               (!(e_ptrs[cur_event].behavior & MAT_NOMAIL24)) &&
               (!(newnodedes.NodeFlags & B_CM)))
               return (0);
           /* If we aren't supposed to send to CM's now, get out */
           if ((newnodelist || version7) &&
               (e_ptrs[cur_event].behavior & MAT_NOCM) &&
               (newnodedes.NodeFlags & B_CM))
               return (0);
           }

        /* Try to connect */

        if (flag_file (TEST_AND_SET, &called_addr, 1))
            {
            if (CARRIER)
                mdm_hangup ();
            return (0);
            }

        do_dial_strings ();
        if (un_attended && fullscreen)
            {
            sb_move (hold_hWnd, 2, 1);
            sb_wa (hold_hWnd, colors.calling, 31);
            }

        callstart = time (NULL);

        if (!blank_on_key)
            screen_blank = 0;

        if ((i = try_1_connect ((char *) (newnodedes.PhoneNumber))) < 0)
            {
            if (un_attended && fullscreen)
                {
                sb_move (hold_hWnd, 2, 1);
                sb_wa (hold_hWnd, colors.hold, 31);
                }
            (void) flag_file (CLEAR_FLAG, &called_addr, 1);
            return (i);
            }
        }

process_the_damned_mail:

    if (CARRIER)                                         /* if we did,        */
        {
        if (type > 0)
           callstart = time (NULL);

        b_session (1);                                  /* do a mail session  */

        callend = time (NULL);
        hist.last_Elapsed = callend - callstart;

        eh = (callend - callstart) / 3600L;
        em = ((callend - callstart) / 60L) - (eh * 60L);
        es = (callend - callstart) - (eh * 3600L) - (em * 60L);

        hist.callcost += (call_cost = cost_of_call (callstart, callend));

        call_cost_ths = call_cost % 100L;               /* Separate dollars & */
        call_cost = call_cost / 100L;                   /* cents for formats  */

#ifdef MILQ
        sprintf( last_Elapsed_Str,
                 "%02d:%02d:%02d",
                   eh, em, es );
        sb_puts( node_Elapsed, last_Elapsed_Str );
#endif
        status_line (MSG_TXT(M_NODE_COST), Full_Addr_Str (baddr), 
                        eh, em, es, call_cost, call_cost_ths);
        mdm_hangup ();

#ifdef MILQ
        UsePaths = FALSE;
#endif

        ++hist.connects;
        if (un_attended && fullscreen)
            {
            do_today();
            SendMessage( node_hWnd, WM_COMMAND, GD_LAST, (LONG)baddr );
            }

        write_stats ();

        if (un_attended && (got_arcmail || got_packet || got_mail))
            {
            (void) bad_call (baddr, -1);
            receive_exit ();
            }
        if (un_attended && fullscreen)
            {
            sb_move (hold_hWnd, 2, 1);
            sb_wa (hold_hWnd, colors.hold, 31);
            }
        return (1);
        }
    else
        {
        status_line (MSG_TXT(M_END_OF_ATTEMPT));
        (void) flag_file (CLEAR_FLAG, &called_addr, 1);
        }
    if (un_attended && fullscreen)
        {
        sb_move (hold_hWnd, 2, 1);
        sb_wa (hold_hWnd, colors.hold, 31);
        }
    write_stats ();
    return (2);
}

int handle_inbound_mail (int answer_now)
{
    long t;                                             /* used for timeouts  */
    int mr;                                             /* Modem response     */


    caller = 0;

    (void) memset ((char *)&remote_addr, 0, sizeof (remote_addr));
    remote_addr.Domain = NULL;             /* only Microsoft can explain this */

inloop:

    /* Do we have carrier, RING, or NO DIAL TONE? */

    if (!answer_now && !(server_mode && CARRIER) && !CHAR_AVAIL ())
        {
        time_release ();
        return (0);                                     /* No, nothing to do  */
        }

    mail_only = 1;
    if ((cur_event >= 0) && (e_ptrs[cur_event].behavior & MAT_BBS))
        mail_only = 0;

should_answer:

    if (KEYPRESS ())                            /* If aborted by user,        */
        return (1);                             /* get out                    */

    if (!blank_on_key)
        screen_blank = 0;

    if (un_attended && fullscreen)
        sb_show ();

    if (server_mode && CARRIER)
        goto got_carrier;

    if (answer_now)
        {
        mr = 3;
        answer_now = 0;
        }
    else mr = modem_response (500);

    if ((mr == 3) && (ans_str != NULL)) /* saw RING  */
        {
       /*
        * Try to make sure we don't send out the answer string while stuff is
        * still coming from the modem.  Most modems don't like that kind of
        * sequence (including HST's!). 
        */
        t = timerset (100);
        while (CHAR_AVAIL () && (!timeup (t)))
            {
            t = timerset (100);
            (void) MODEM_IN ();
            }
        CLEAR_INBOUND ();
        mdm_cmd_string (ans_str, 0);            /* transmit the answer string */
        goto should_answer;
        }
    else if (mr != 2)
        {
        t = timerset (6000);                    /* set 1 minute timer         */
        while ((!timeup (t))
            && (!CHAR_AVAIL ())
            && (!KEYPRESS ()))
            time_release ();                    /* wait for another result    */
        goto inloop;                            /* then proceed along         */
        }

got_carrier:

    if (CARRIER)                                /* if we have a carrier,      */
        {
        b_session (0);                          /* do a mail session          */
        mdm_hangup ();                          /* Make sure to hang up       */

        /* We got inbound mail */
        if (got_arcmail || got_packet || got_mail)
            {
            receive_exit ();
            }
        }
    else
        mdm_hangup ();                          /* Try to reset modem         */

    mailer_banner ();
    return (1);
}

void receive_exit ()
{
    char junk1[150];
    int i;
    BINK_EVENT evt;

    if (cur_event >= 0)
        evt = e_ptrs [cur_event];

    if (cur_event >= 0)
        {
        if (got_arcmail && (evt.errlevel[2]))
            {
            status_line (MSG_TXT(M_EXIT_COMPRESSED),
                          evt.errlevel[2]);

            errl_exit (evt.errlevel[2]);
            }

        for (i = 0; i < 6; i++)
            {
            if (user_exits[i])
                {
                status_line (MSG_TXT(M_EXIT_AFTER_EXTENT),
                              &(evt.err_extent[i][0]),
                                evt.errlevel[i + 3]);
                errl_exit (evt.errlevel[i + 3]);
                }
            }
        }

    if ((got_mail || got_packet)
    &&  (cur_event >= 0) && (evt.errlevel[1]))
        {
        status_line (MSG_TXT(M_EXIT_AFTER_MAIL),
                      evt.errlevel[1]);

        errl_exit (evt.errlevel[1]);
        }

    if ((aftermail != NULL) && (got_mail || got_packet || got_arcmail))
        {
        status_line (MSG_TXT(M_AFTERMAIL));
        mdm_init (modem_busy);
        exit_DTR ();
        screen_clear ();
        vfossil_cursor (1);
        (void) strcpy (junk1, aftermail);
        if (cur_event >= 0)
            (void) strcat (junk1, evt.cmd);
        close_up ();
        b_spawn (junk1);
        come_back ();
        RAISE_DTR ();
        status_line (MSG_TXT(M_OK_AFTERMAIL));
        mdm_init (modem_init);
        xmit_reset ();
        waitfor_line = timerset ((unsigned int)6000);
        }

    got_arcmail = 0;
    got_packet = 0;
    got_mail = 0;
}

void errl_exit (int n)
{
    write_sched ();

    status_line (MSG_TXT (M_BINK_END), ANNOUNCE, COMPILER_NAME);
    mdm_init (modem_busy);                      /* Reinitialize the modem     */
    exit_DTR ();
    if (fullscreen)
        gotoxy (0, SB_ROWS);

    if (vfossil_installed)
        vfossil_close ();

    if (!share)
        MDM_DISABLE ();
    exit (n);
}

long random_time (int x)
{
    int i;

    if (x == 0)
        {
        return (0L);
        }

    /* Number of seconds to delay is random based on x +/- 50% */
    i = (rand () % (x + 1)) + (x / 2);

    return (timerset ((unsigned int) (i * 100)));
}


char *HoldAreaNameMunge(ADDRP maddr)
{
    static char munged[127];
    register char *p, *q;
    int i;

    if ((maddr->Domain != my_addr.Domain) && (maddr->Domain != NULL))
        {
        *domain_loc = '\0';
        (void) strcpy (munged, domain_area);
        q = &(munged[strlen (munged)]);
        for (i = 0; domain_name[i] != NULL; i++)
            {
            if (domain_name[i] == maddr->Domain)
                {
                if (domain_abbrev[i] != NULL)
                    {
                    p = domain_abbrev[i];
                    while (*p)
                        *q++ = *p++;
                    if (no_zones)
                        (void) sprintf (q, "\\");
                    else
                        (void) sprintf (q, ".%03x\\", maddr->Zone);
                    }
                break;
                }
            }
        }
    else
        {
        (void) strcpy (munged, hold_area);
        q = &(munged[strlen (munged)]);
        if (!((maddr->Zone == alias[0].Zone) || (no_zones)))
           {
           --q;
           (void) sprintf(q,".%03x\\",maddr->Zone);
           }
        }
    return(munged);
}


void mailer_banner ()
{
    if (fullscreen && un_attended)
        {
        vfossil_cursor (0);

        (void) sprintf (junk, "%-2d", cur_event + 1);
        sb_move (settings_hWnd, SET_EVNT_ROW, SET_COL);
        sb_puts (settings_Evt, junk);

        (void) sprintf (junk, "%-5u Com%d", cur_baud.rate_value, port_ptr + 1);
        sb_move (settings_hWnd, SET_PORT_ROW, SET_COL);
        sb_puts (settings_Port, junk);
        clear_filetransfer ();

        (void) sprintf (junk, "M'Task: %s", mtask_name );
        sb_move (settings_hWnd, SET_TASK_ROW, 2);
#ifndef MILQ
        sb_puts (settings_hWnd, "                   ");
#endif
        sb_move (settings_hWnd, SET_TASK_ROW, 2);
        sb_puts (settings_MTask, junk );
        }
    (void) set_baud (max_baud.rate_value, 0);
}

#ifdef MILQ
int PASCAL clear_enum( HWND hWnd,
                       DWORD lParam ) {
  SendMessage( hWnd, WM_SETTEXT, 0, (long)(char far *)"" );
  return TRUE;
  }
#endif

void clear_filetransfer ()
{
#ifdef MILQ
    EnumChildWindows( file_hWnd, clear_enum, 0L );
#endif
    FlLnModeSet( FILE_LN_1, 0 );
    FlLnModeSet( FILE_LN_2, 0 );
    if (fullscreen && un_attended)
        sb_fillc (file_hWnd, ' ');
}

static char ebuf[50];
char *estring (int e, int how_big)
{
    char j[30];

    ebuf[0] = '\0';
    if (e >= 0)
        {
        if (e_ptrs[e].behavior & MAT_BBS)
            {
            (void) strcat (ebuf, "B");
            if (how_big)
                (void) strcat (ebuf, " ");
            }
        if (e_ptrs[e].behavior & MAT_CM)
            {
            (void) strcat (ebuf, "C");
            if (how_big)
                (void) strcat (ebuf, " ");
            }
        if (e_ptrs[e].behavior & MAT_DYNAM)
            {
            (void) strcat (ebuf, "D");
            if (how_big)
                (void) strcat (ebuf, " ");
            }
        if (how_big && (e_ptrs[e].behavior & MAT_FORCED))
            (void) strcat (ebuf, "F ");
        if (e_ptrs[e].behavior & MAT_HIPRICM)
            {
            (void) strcat (ebuf, "H");
            if (how_big)
                (void) strcat (ebuf, " ");
            }
        if (e_ptrs[e].behavior & MAT_NOCM)
            {
            (void) strcat (ebuf, "K");
            if (how_big)
                (void) strcat (ebuf, " ");
            }
        if (e_ptrs[e].behavior & MAT_LOCAL)
            {
            (void) strcat (ebuf, "L");
            if (how_big)
                {
                if (e_ptrs[e].node_cost >= 0)
                    (void) sprintf (j, "<%d ", (e_ptrs[e].node_cost) + 1);
                else
                    (void) sprintf (j, ">%d ", -(e_ptrs[e].node_cost) - 1);
                (void) strcat (ebuf, j);
                }
            }
        if (how_big && (e_ptrs[e].behavior & MAT_NOMAIL24))
            (void) strcat (ebuf, "M ");
        if (e_ptrs[e].behavior & MAT_NOREQ)
            {
            (void) strcat (ebuf, "N");
            if (how_big)
                (void) strcat (ebuf, " ");
            }
        if (e_ptrs[e].behavior & MAT_OUTONLY)
            {
            (void) strcat (ebuf, "S");
            if (how_big)
                (void) strcat (ebuf, " ");
            }
        if (e_ptrs[e].behavior & MAT_NOOUT)
            {
            (void) strcat (ebuf, "R");
            if (how_big)
                (void) strcat (ebuf, " ");
            }
        if (how_big && (e_ptrs[e].behavior & MAT_NOOUTREQ))
            (void) strcat (ebuf, "X");
        }
    return (ebuf);
}

void do_ready (char *str)
{
    if (fullscreen && un_attended)
        {
        if (!doing_poll)
            {
            clear_filetransfer ();
            }
        (void) sprintf (junk, "%-2d/%-6.6s", cur_event + 1, estring (cur_event, 0));
        sb_move (settings_hWnd, SET_EVNT_ROW, SET_COL);
        sb_puts (settings_Evt, junk);
        sb_move (settings_hWnd, SET_STAT_ROW, SET_COL);
        sb_puts (settings_Status, str);
        SendMessage( settings_hWnd, WM_COMMAND, GD_DSP, 0L );
        sb_show ();
        }
}

void list_next_event ()
{
    int i, k;
    int read[2];
    char *p;
    char j[100];
    FILE *fpt;
    struct FILEINFO dta;

    i = time_to_next (0);

    if ((next_event >= 0) && fullscreen)
        {
        clear_filetransfer ();

        (void) sprintf (j, MSG_TXT(M_NEXT_EVENT), next_event + 1, i);
        sb_move (file_hWnd, 1, 2);
        sb_puts( GetDlgItem( file_hWnd, FILE_LN_1 ), j );
        p = estring (next_event, 1);
        if (*p != '\0')
            {
            (void) sprintf (j, MSG_TXT(M_EVENT_FLAGS), p);
            sb_move (file_hWnd, 2, 2);
            FlLnModeSet( FILE_LN_2, 0 );
            sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 ), j );
            }
        if (netmail != NULL)
            {
            (void) strcpy (j, netmail);
            (void) strcat (j, "LASTREAD");          /* Full path to LASTREAD  */

            fpt = share_fopen (j, "rb", DENY_WRITE);/* Open the file          */
            if (fpt != NULL)
                {
            /*
             * Try to read two records. If there are two, the first record is the
             * current pointer and the second one is the last-read. If there is
             * one record, it is the last-read.
             */

                i = fread (read, sizeof (int), 2, fpt); /* Get lastread ptr   */
                (void) fclose (fpt);                    /* Then close the file*/
                if (i)
                    {
                    k = read [i-1];                     /* Last msg read      */
                    (void) strcpy (j, netmail);
                    (void) strcat (j, "*.msg");         /* Wildcard for .MSG  */
                    if (!dfind (&dta, j, 0))            /* If there are any,  */
                        {
                        do
                            {
                            if (atoi(dta.name) > k)     /* See if one's more  */
                                {
                                sb_move (file_hWnd, 2, 50);
                                sb_puts( GetDlgItem( file_hWnd, FILE_LN_2 + GD_STATUS ),
                                         MSG_TXT(M_UNREAD_NETMAIL));
                                break;
                                }
                            }
                        while (!dfind (&dta, j, 1));    /* Check all of them  */
                        }
                    }   /* If any records read from LASTREAD */
                }       /* If we were able to open LASTREAD  */
            }           /* If the user specified NetMail     */

        sb_show ();
        }               /* If next event and fullscreen      */
}