home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 2 BBS / 02-BBS.zip / BTMTSRC3.ZIP / B_FRPROC.C < prev    next >
C/C++ Source or Header  |  1991-08-15  |  23KB  |  752 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*  (C) Copyright 1987-90, Bit Bucket Software Co., a Delaware Corporation. */
  11. /*                                                                          */
  12. /*                                                                          */
  13. /*                   BinkleyTerm File Request Processor                     */
  14. /*                                                                          */
  15. /*                                                                          */
  16. /*    For complete  details  of the licensing restrictions, please refer    */
  17. /*    to the License  agreement,  which  is published in its entirety in    */
  18. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.240.    */
  19. /*                                                                          */
  20. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  21. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  22. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  23. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  24. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  25. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  26. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  27. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  28. /*                                                                          */
  29. /*                                                                          */
  30. /* You can contact Bit Bucket Software Co. at any one of the following      */
  31. /* addresses:                                                               */
  32. /*                                                                          */
  33. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:132/491, 1:141/491  */
  34. /* P.O. Box 460398                AlterNet 7:491/0                          */
  35. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  36. /*                                Internet f491.n132.z1.fidonet.org         */
  37. /*                                                                          */
  38. /* Please feel free to contact us at any time to share your comments about  */
  39. /* our software and/or licensing policies.                                  */
  40. /*                                                                          */
  41. /*                                                                          */
  42. /*  This module is based largely on a similar module in OPUS-CBCS V1.03b.   */
  43. /*  The original work is (C) Copyright 1987, Wynn Wagner III. The original  */
  44. /*  author has graciously allowed us to use his code in this work.          */
  45. /*                                                                          */
  46. /*--------------------------------------------------------------------------*/
  47.  
  48. #include <stdio.h>
  49. #include <ctype.h>
  50. #include <signal.h>
  51. #include <conio.h>
  52. #include <string.h>
  53. #include <stdlib.h>
  54. #include <time.h>
  55. #include <sys\types.h>
  56. #include <sys\stat.h>
  57.  
  58. #ifdef __TURBOC__
  59. #include <mem.h>
  60. #else
  61. #include <memory.h>
  62. #endif
  63.  
  64. #define WAZOO_SECTION
  65. #include "com.h"
  66. #include "xfer.h"
  67. #include "zmodem.h"
  68. #include "keybd.h"
  69. #include "sbuf.h"
  70. #include "sched.h"
  71. #include "externs.h"
  72. #include "prototyp.h"
  73.  
  74.  
  75. static char *their_pwd;                         /* Password in REQ file */
  76. static char required_pwd[10];                   /* Password in OK file  */
  77.  
  78. static int prep_match (char *, char *);
  79. static int match (char *, char *);
  80. static void run_prog (char *);
  81. static int check_password (void);
  82. static freq_abort (long);
  83. static int what_event (void);
  84.  
  85. static int prep_match (template, buffer)
  86. char *template;
  87. char *buffer;
  88. {
  89.    register int i, delim;
  90.    register char *sptr;
  91.    int start;
  92.  
  93.    (void) memset (buffer, 0, 11);
  94.  
  95.    i = (int) strlen (template);
  96.    sptr = template;
  97.  
  98.  
  99.    for (start = i = 0; sptr[i]; i++)
  100.       if ((sptr[i] == '\\') || (sptr[i] == ':'))
  101.          start = i + 1;
  102.  
  103.    if (start)
  104.       sptr += start;
  105.    delim = 8;                                    /* last column for ? */
  106.  
  107.    (void) strupr (sptr);
  108.  
  109.    for (i = 0; *sptr && i < 12; sptr++)
  110.       switch (*sptr)
  111.          {
  112.          case '.':
  113.             if (i > 8)
  114.                return (-1);
  115.             while (i < 8)
  116.                {
  117.                buffer[i++] = ' ';
  118.                }
  119.             buffer[i++] = *sptr;
  120.             delim = 12;
  121.             break;
  122.  
  123.          case '*':
  124.             while (i < delim)
  125.                {
  126.                buffer[i++] = '?';
  127.                }
  128.             break;
  129.  
  130.          default:
  131.             buffer[i++] = *sptr;
  132.             break;
  133.  
  134.          }                                       /* switch */
  135.  
  136.    while (i < 12)
  137.       {
  138.       if (i == 8)
  139.          buffer[i++] = '.';
  140.       else buffer[i++] = ' ';
  141.       }
  142.  
  143.    buffer[i] = '\0';
  144.  
  145.    return 0;
  146. }
  147.  
  148. static int match (s1, s2)
  149. char *s1, *s2;
  150. {
  151.    register char *i, *j;
  152.  
  153.    i = s1;
  154.    j = s2;
  155.  
  156.    while (*i)
  157.       {
  158.       if ((*j != '?') && (*i != *j))
  159.          {
  160.          return 1;
  161.          }
  162.       i++;
  163.       j++;
  164.       }
  165.  
  166.    return 0;
  167. }
  168.  
  169. /*--------------------------------------------------------------------------*/
  170. /* Process file requests from the remote system. The filespec requested is  */
  171. /* turned into a local filespec if possible, then transferred via the       */
  172. /* caller-supplied routine.                                                 */
  173. /*--------------------------------------------------------------------------*/
  174.  
  175. int n_frproc (request, nfiles, callback)
  176. char *request;
  177. int nfiles;
  178. int (*callback)(char *);
  179. {
  180.    register int i;
  181.    register int j = 0;
  182.    static char s[80];
  183.    static char s1[80];
  184.    static char s2[80];
  185.  
  186.    FILE *approved;
  187.    struct FILEINFO dta;
  188.    struct stat st;
  189.    char *sptr;
  190.  
  191.    char *after_pwd;
  192.    long updreq = 0L;
  193.    char updtype = 0;
  194.    int saved_nfiles;
  195.  
  196.    char our_wildcard[15];
  197.    char their_wildcard[15];
  198.    int mfunc;
  199.    int magic_state = 0;
  200.    int tried_about = 0;
  201.    int do_dir = 0;
  202.  
  203.    int failure_reason = 1;                      /* 1 = not available */
  204.                                                 /* 2 = no update     */
  205.                                                 /* 3 = bad password  */
  206.    approved = NULL;
  207.    their_pwd = NULL;
  208.    after_pwd = NULL;
  209.    (void) strcpy (s1, request);
  210.  
  211.    /*--------------------------------------------------------------------*/
  212.    /* Fix up the file name                                               */
  213.    /*--------------------------------------------------------------------*/
  214.    for (i = 0; request[i]; i++)
  215.       {
  216.       if (request[i] <= ' ')
  217.          {
  218.          request[i++] = '\0';
  219.          j = i;
  220.          break;
  221.          }
  222.       }
  223.    
  224.    if (j)
  225.       {
  226.       /* If we have a '!', find the end of the password, point j
  227.          past it, then truncate and fold if necessary. This leaves
  228.          j properly aligned for other fields.
  229.        */
  230.  
  231.       if (request[j] == '!')
  232.          {
  233.          their_pwd = request + (++j);
  234.          for (; request[j]; j++)
  235.             {
  236.             if (request[j] <= ' ')
  237.                {
  238.                request[j++] = '\0';
  239.                break;
  240.                }
  241.             }
  242.  
  243.          if (strlen (their_pwd) > 6)
  244.             their_pwd[6] = '\0';
  245.  
  246.          (void) fancy_str (their_pwd);
  247.          }
  248.  
  249.       /* Test for update/backdate request */
  250.  
  251.       if (request[j] == '+' || request[j] == '-')
  252.          {
  253.          updtype = request[j++];
  254.          updreq = atol (&request[j]);
  255.          }
  256.       }      
  257.  
  258.    if (!request[0])                             /* Still any filename?  */
  259.       return (nfiles);                          /* If not, return df=0. */
  260.  
  261.    if (freq_abort(0L))                          /* Any reason to abort? */
  262.       return (-2);                              /* If so, return error. */
  263.  
  264.  
  265.    /*--------------------------------------------------------------------*/
  266.    /* Initialization(s)                                                  */
  267.    /*--------------------------------------------------------------------*/
  268.    i = 0;
  269.    sptr = NULL;
  270.  
  271.    (void) strupr (request);
  272.    status_line ("*%s %s (%s)", (updreq != 0L) ? msgtxt[M_UPDATE] : msgtxt[M_FILE], msgtxt[M_REQUEST], request);
  273.  
  274.    saved_nfiles = nfiles;
  275.  
  276.    /*--------------------------------------------------------------------*/
  277.    /* Reserved words                                                     */
  278.    /*--------------------------------------------------------------------*/
  279.    if (!strcmp (request, "FILES"))
  280.       {
  281.       if (CurrentFILES)
  282.          (void) strcpy (s, CurrentFILES);
  283.       else
  284.          {
  285.          s[0] = '\0';
  286.          sptr = msgtxt[M_NO_AVAIL];
  287.          }
  288.       goto avail;
  289.       }
  290.  
  291.    else if (!strcmp (request, "ABOUT"))
  292.       {
  293.       s[0] = '\0';
  294.       goto avail;
  295.       }
  296.  
  297.    (void) prep_match (request, their_wildcard);
  298.  
  299.    /*--------------------------------------------------------------------*/
  300.    /* See if the file is approved for transmission                       */
  301.    /*--------------------------------------------------------------------*/
  302.    if ((approved = fopen (CurrentOKFile, read_ascii)) == NULL)
  303.       {
  304.       (void) got_error (msgtxt[M_OPEN_MSG], CurrentOKFile);
  305.       goto err;
  306.       }
  307.  
  308.    while (!feof (approved))
  309.       {
  310.       do_dir = 0;
  311.  
  312.       /* If we were magic, set flag to cause exit if we don't do it again */
  313.       if (magic_state)
  314.          magic_state = 1;                       /* 1 means done if no @ */
  315.  
  316.       s[0] = required_pwd[0] = '\0';
  317.  
  318.       (void) fgets (s, 78, approved);
  319.  
  320.       for (i = 0; s[i]; i++)
  321.          if (s[i] == 0x09)
  322.             s[i] = ' ';
  323.          else if (s[i] < ' ')
  324.             s[i] = '\0';
  325.  
  326.       if (!s[0] || s[0] == ';')
  327.          continue;
  328.  
  329.       /*--------------------------------------------------------------*/
  330.       /* Check for transaction-level password                         */
  331.       /*--------------------------------------------------------------*/
  332.       for (i = 0; s[i]; i++)
  333.          {
  334.          if (s[i] == ' ')
  335.             {
  336.             s[i] = '\0';
  337.             if (s[i + 1] == '!')
  338.                {
  339.                (void) strncpy (required_pwd, s + i + 2, 8);
  340.                if (strlen (required_pwd) > 6)
  341.                   required_pwd[6] = '\0';
  342.  
  343.                after_pwd = skip_blanks (s + i + 1);
  344.                while (*after_pwd && (!isspace (*after_pwd)))
  345.                   ++after_pwd;
  346.  
  347.                if (*after_pwd)
  348.                   ++after_pwd;
  349.  
  350.                for (i = 0; required_pwd[i]; i++)
  351.                   if (required_pwd[i] <= ' ')
  352.                      required_pwd[i] = '\0';
  353.  
  354.                break;
  355.                }
  356.             else
  357.                {
  358.                after_pwd = skip_blanks (s + i + 1);
  359.                break;
  360.                }
  361.             }
  362.          else if (s[i] < ' ')
  363.             s[i] = '\0';
  364.          }
  365.  
  366.       if (!s[0])
  367.          continue;
  368.  
  369.       if (strchr ("@+$>",s[0]) != NULL)
  370.          {
  371.          /* Magic name or function */
  372.          if ((s[0] != '>') && stricmp (&s[1], request))
  373.             continue;
  374.  
  375.          /* Name matches, check password */
  376.          if (!(check_password ()))
  377.             {
  378.             failure_reason = 3;      /* Password doesn't match */
  379.             continue;                /* Go on                  */
  380.             }
  381.          
  382.          mfunc = 0;
  383.  
  384.          if (s[0] == '$')
  385.             {
  386.             (void) sprintf (s2, after_pwd, remote_addr.Net, remote_addr.Node);
  387.             mfunc = 1;
  388.             }
  389.  
  390.          if (s[0] == '+')
  391.             {
  392.             (void) sprintf (s, " %d %d %d", remote_addr.Zone, remote_addr.Net, remote_addr.Node);
  393.             (void) strcpy (s2, s1);
  394.             (void) strcat (s2, s);
  395.             mfunc = 2;
  396.             }
  397.  
  398.          if (mfunc)
  399.             {
  400.             run_prog (s2);
  401.             goto check_HLO;
  402.             }
  403.          
  404.          if (s[0] == '@')
  405.             {
  406.             (void) strcpy (s, after_pwd);
  407.             magic_state = 2;                    /* Will be reset up above */
  408.             }
  409.  
  410.          if (s[0] == '>')
  411.             {
  412.             strcpy (s, &(s[1]));
  413.             strcat (s, "\\*.*");
  414.             do_dir = 1;
  415.             }
  416.          }
  417.  
  418.       /*
  419.        * We're past the magic stuff here. So check for whether this is
  420.        * a new iteration of a magic loop that somehow didn't catch.
  421.        * If not, then check out the filespec we have on this line.
  422.        */
  423.  
  424.       if (magic_state == 1)
  425.          goto check_HLO;
  426.  
  427.       j = 1;
  428.  
  429.       if (Netmail_Session == 2)
  430.          SENDBYTE (NUL);
  431.  
  432.       if (!dfind (&dta, s, 0))
  433.          {
  434.          do
  435.             {
  436.             if (!(--j))                         /* If we've looped a bit  */
  437.                {
  438.                i = freq_abort (0L);
  439.                if (i)                           /* See if we want to quit */
  440.                   {
  441.                   if (i == 1)                   /* Yes, why? Carrier?     */
  442.                      goto finished;             /* uh-huh -- get out fast */
  443.                   else
  444.                      {
  445.                      failure_reason = i;        /* Not carrier, get reason*/
  446.                      goto make_RSP;             /* Make a .RSP file       */
  447.                      }
  448.                   }
  449.                j = 10;                          /* No, reset bounds       */
  450.                }
  451.  
  452.             if (!magic_state)                   /* If not "magic",        */
  453.                {
  454.                if (prep_match (dta.name, our_wildcard) < 0)
  455.                   continue;
  456.  
  457.                if (match (our_wildcard, their_wildcard))
  458.                   continue;
  459.  
  460.                /* File names match, check password now */
  461.  
  462.                if (!check_password ())
  463.                   {
  464.                   failure_reason = 3;      /* Password doesn't match */
  465.                   continue;                /* Go on                  */
  466.                   }
  467.                }
  468.  
  469.             /* Good password, get full path with wildcard from OKFILE */
  470.  
  471.             (void) strcpy (s2, s);
  472.  
  473.             /* Subtract the wild card file name, keep path */
  474.  
  475.             for (i = (int) strlen (s2); i; i--)
  476.                if (s2[i] == '\\')
  477.                   {
  478.                   s2[i + 1] = 0;
  479.                   break;
  480.                   }
  481.  
  482.             /* Then add in the exact name found */
  483.  
  484.             (void) strcat (s2, dta.name);
  485.  
  486.             /* Got full filename, now do file update validation */
  487.  
  488.             if (updtype && !stat (s2, &st))
  489.                {
  490.                if ((updtype == '+' && (st.st_atime <= updreq))
  491.                ||  (updtype == '-' && (st.st_atime >= updreq)))
  492.                   {
  493.                   failure_reason = 2;      /* No update available    */
  494.                   continue;                /* Go on                  */
  495.                   }
  496.                }
  497.  
  498.             i = freq_abort (dta.size);     /* Check file size        */
  499.             if (i)                         /* See if we want to quit */
  500.                {
  501.                if (i == 1)                 /* Yes, why? Carrier?     */
  502.                   goto finished;           /* uh-huh -- get out fast */
  503.                else
  504.                   {
  505.                   failure_reason = i;      /* Not carrier, get reason*/
  506.                   goto make_RSP;           /* Make a .RSP file       */
  507.                   }
  508.                }
  509.  
  510.             /* Everything is OK, send the file if we can */
  511.             CLEAR_INBOUND ();
  512.             if ((*callback) (s2))
  513.                {
  514.                ++nfiles;
  515.                freq_accum.bytes += dta.size;
  516.                ++freq_accum.files;
  517.                }
  518.             j = 1;                               /* Force abort test */
  519.             }
  520.          while (!dfind (&dta, s, 1));
  521.          }                                       /* if dfind */
  522.  
  523.       else status_line (msgtxt[M_OKFILE_ERR], s);  /* if not dfind */
  524.  
  525.       s[0] = '\0';
  526.       }                                          /* while not eof(approved) */
  527.  
  528.    if (saved_nfiles != nfiles)
  529.       failure_reason = 9;
  530.  
  531. make_RSP:
  532.  
  533.    s[0] = '\0';                                  /* Initialize string     */
  534.    if ((CurrentReqTemplate != NULL) && (dexists(CurrentReqTemplate)))
  535.       {
  536.       Make_Response(s1, failure_reason);         /* Build a response      */
  537.       (void) strcpy(s, s1);                             /* Copy it for xmission  */
  538.       }
  539.  
  540.    if ((!s[0]) && (failure_reason > 3))          /* if no .RSP file,      */
  541.       goto finished;                             /* give it up            */
  542.  
  543.    /*--------------------------------------------------------------------*/
  544.    /* File requested not found, send the system ABOUT file.              */
  545.    /*--------------------------------------------------------------------*/
  546. avail:
  547.  
  548.    if (!s[0])
  549.       {
  550.       if (CurrentAbout)
  551.          (void) strcpy (s, CurrentAbout);
  552.       else
  553.          {
  554.          if (tried_about)
  555.             {
  556.             sptr = msgtxt[M_NO_ABOUT];
  557.             goto err;
  558.             }
  559.          else
  560.             {
  561.             ++tried_about;
  562.             (void) strcpy (s1, request);
  563.             failure_reason = 1;        /* Didn't find what we wanted */
  564.             goto make_RSP;             /* Make a .RSP file       */
  565.             }
  566.          }
  567.       }
  568.  
  569.    if ((*callback) (s))
  570.          ++nfiles;
  571.  
  572.    goto finished;
  573.  
  574.    /*--------------------------------------------------------------------*/
  575.    /* See if we generated a .QLO file somehow, if so send listed files   */
  576.    /*--------------------------------------------------------------------*/
  577. check_HLO:
  578.  
  579.    (void) do_FLOfile ("Q", callback);
  580.  
  581.    /*--------------------------------------------------------------------*/
  582.    /* Maybe the magic request made a conventional .FLO file, try that too*/
  583.    /*--------------------------------------------------------------------*/
  584.  
  585.    *ext_flags = 'F';
  586.    (void) do_FLOfile (ext_flags, callback);
  587.    goto finished;
  588.  
  589.    /*--------------------------------------------------------------------*/
  590.    /* Error return                                                       */
  591.    /*--------------------------------------------------------------------*/
  592. err:
  593.    if (sptr)
  594.       status_line ("!%s %s %s: %s",
  595.          (updreq != 0L) ? msgtxt[M_UPDATE] : msgtxt[M_FILE],
  596.          msgtxt[M_REQUEST], &(msgtxt[M_ERROR][1]), sptr);
  597.  
  598. finished:
  599.    if (approved)
  600.       (void) fclose (approved);
  601.  
  602.    return (nfiles);
  603. }
  604.  
  605. static void run_prog (s)
  606. char *s;
  607. {
  608.    unsigned int saved_baud;
  609.  
  610.    status_line ("%s '%s'", msgtxt[M_EXECUTING], s);
  611.    if (fullscreen && un_attended)
  612.       {
  613.       screen_clear ();
  614.       }
  615.    scr_printf (&(msgtxt[M_EXECUTING][1]));
  616.    scr_printf (s);
  617.    scr_printf ("\r\n");
  618.    vfossil_cursor (1);
  619.    saved_baud = cur_baud;
  620.    b_spawn (s);
  621.     come_back();     /* CML */
  622.    vfossil_cursor (0);
  623.    if (fullscreen && un_attended)
  624.       {
  625.       screen_clear ();
  626.       sb_dirty ();
  627.       opening_banner ();
  628.       mailer_banner ();
  629.       }
  630.  
  631.    set_baud (saved_baud, 0);          /* Restore baud rate trashed by others */
  632. }
  633.  
  634. static int check_password ()
  635. {
  636.    if (required_pwd[0])
  637.       {
  638.       (void) fancy_str (required_pwd);
  639.       if ((stricmp (required_pwd, their_pwd)) &&
  640.           (stricmp (required_pwd, remote_password)))
  641.          {
  642.          status_line (msgtxt[M_FREQ_PW_ERR],
  643.                                required_pwd,
  644.                                their_pwd,
  645.                                remote_password
  646.                      );
  647.  
  648.          return (0);
  649.          }
  650.       }
  651.    return (1);
  652. }
  653.  
  654. static int freq_abort (file_size)
  655. long file_size;
  656. {
  657.    int w_event;
  658.  
  659.    if (!CARRIER)
  660.       {
  661.       status_line (msgtxt[M_CARRIER_REQUEST_ERR]);
  662.       return (1);
  663.       }
  664.  
  665.    if (freq_accum.files >= CurrentReqLim)
  666.       {
  667.       status_line (msgtxt[M_FREQ_LIMIT]);
  668.       return (4);
  669.       }
  670.  
  671.    if ((freq_accum.bytes + file_size) > CurrentByteLim)
  672.       {
  673.       status_line (msgtxt[M_BYTE_LIMIT]);
  674.       return (6);
  675.       }
  676.  
  677.    w_event = what_event ();
  678.    if ((w_event >= 0) && (w_event != cur_event))
  679.       {
  680.       if ((e_ptrs[w_event]->behavior & MAT_NOREQ) ||
  681.          ((w_event != cur_event) && (e_ptrs[w_event]->behavior & MAT_FORCED)))
  682.          {
  683.          status_line (msgtxt[M_EVENT_OVERRUN]);
  684.          return (5);
  685.          }
  686.       }
  687.  
  688.    return (0);
  689. }
  690.  
  691. static int what_event ()
  692. {
  693.    int cur_day;
  694.    int cur_hour;
  695.    int cur_minute;
  696.    int cur_mday;
  697.    int cur_mon;
  698.    int cur_year;
  699.    int junk;
  700.    int our_time;
  701.    int w_event;
  702.    int i;
  703.  
  704.    /* Get the current time in minutes */
  705.    dostime (&cur_hour, &cur_minute, &junk, &junk);
  706.    our_time = cur_hour * 60 + cur_minute;
  707.  
  708.    /* Get the current day of the week */
  709.    dosdate (&cur_mon, &cur_mday, &cur_year, &cur_day);
  710.  
  711.    cur_day = 1 << cur_day;
  712.  
  713.    w_event = -1;
  714.  
  715.    /* Go through the events from top to bottom */
  716.    for (i = 0; i < num_events; i++)
  717.       {
  718.       if (our_time >= e_ptrs[i]->minute)
  719.          {
  720.          if ((cur_day & e_ptrs[i]->days) &&
  721.      ((!e_ptrs[i]->day) || (e_ptrs[i]->day == (char)cur_mday)) &&
  722.      ((!e_ptrs[i]->month) || (e_ptrs[i]->month == (char)cur_mon)))
  723.             {
  724.             if (((our_time - e_ptrs[i]->minute) < e_ptrs[i]->length) ||
  725.             ((our_time == e_ptrs[i]->minute) && (e_ptrs[i]->length == 0)) ||
  726.                 ((e_ptrs[i]->behavior & MAT_FORCED) && (e_ptrs[i]->last_ran != cur_mday)))
  727.                {
  728.                /* Are we not supposed to force old events */
  729.                if (((our_time - e_ptrs[i]->minute) > e_ptrs[i]->length) && (noforce))
  730.                   {
  731.                   e_ptrs[i]->last_ran = cur_mday;
  732.                   continue;
  733.                   }
  734.  
  735.                if ((e_ptrs[i]->last_ran == cur_mday) &&
  736.                    (e_ptrs[i]->behavior & MAT_SKIP))
  737.                   {
  738.                   /* Don't do events that have been exited already */
  739.                   continue;
  740.                   }
  741.  
  742.                w_event = i;
  743.  
  744.                break;
  745.                }
  746.             }
  747.          }
  748.       }
  749.  
  750.    return (w_event);
  751. }
  752.