home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / OSKBox.lzh / MAILBOX / CC / forward.c < prev    next >
Text File  |  1993-04-25  |  22KB  |  1,075 lines

  1.  
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <direct.h>
  5. #include <setjmp.h>
  6. #include <signal.h>
  7. #include <modes.h>
  8. #include <errno.h>
  9. #include "mailbox.h"
  10.  
  11.  
  12. #define MAXPATHS 6            /* maximum number of paths to mailbox */
  13. #define MAXCALLS 4000            /* maximum number of calls to be forwarded */
  14. #define TIMEOUT (5 * 60)    /* maximum # of seconds to wait for response */
  15. #define MAXBOX 30                /* maximum number of mailboxes */
  16. #define ALARM ((1 << 31) + 60 * 256)
  17.  
  18. struct userstruct user;
  19. char paths[MAXPATHS][80];
  20. char fwdcalls[MAXCALLS][7];
  21. int path_count = 0;
  22. int call_count = 0;
  23. int tnc_in, tnc_out, ctl_in, ctl_out;
  24. jmp_buf disconnected;
  25. int signalman(), quit = 0, interrupt = 0;
  26. int start_fwd, sec;
  27. char *priority = "*";
  28. int bigmail;
  29. char *fwdfile[MAXBOX];
  30. int fwdsize[MAXBOX];
  31. int cmpcall();
  32. int bid_flag, ok_flag, hflag, debugflag;
  33. int norev_flag, suck_flag;
  34. extern struct dist_list *distboxes;
  35. char *maildir = "MAIL/";
  36. int maxtime;    /* maximum # of seconds to forward */
  37.  
  38. main (argc, argv)
  39. char *argv[];
  40. {
  41.     int i;
  42.     char *cp;
  43.     char *port;
  44.  
  45.     while (--argc > 0 && (++argv)[0][0]=='-') {
  46.         cp = argv[0] + 1;
  47.         while (*cp) switch (*cp++) {
  48.  
  49.     case 'r':
  50.             norev_flag++;
  51.             continue;
  52.  
  53.     case 's':
  54.             suck_flag++;
  55.             continue;
  56.  
  57.     case 'd':
  58.             debugflag++;
  59.             continue;
  60.  
  61.     case 'm':
  62.             maxtime = atoi (cp) * 60;
  63.             while (isdigit (*cp)) cp++;
  64.             continue;
  65.             
  66.     case 'b':
  67.             bigmail = atoi (cp) * 60;
  68.             while (isdigit (*cp)) cp++;
  69.             continue;
  70.             
  71.     case 'p':
  72.             priority = cp;
  73.             while (*cp) cp++;
  74.             continue;
  75.             
  76.     case '?':
  77.             printf ("\n");
  78.             printf ("forward -- forward messages to packet BBS(s)\n");
  79.             printf ("\n");
  80.             printf ("form:  forward [options] <port> <bbs> ...\n");
  81.             printf ("\n");
  82.             printf ("options are as follows:\n");
  83.             printf ("\n");
  84.             printf ("  -r       inhibit reverse forward prompt\n");
  85.             printf ("  -s       only force a reverse forward prompt (suck)\n");
  86.             printf ("  -m<num>  set the maximum connect time to <num> minutes\n");
  87.             printf ("  -b<num>  set the maximum message size to <num> bytes\n");
  88.             printf ("  -p<str>  set the priority string:\n");
  89.             printf ("             '*' = any message\n");
  90.             printf ("             'P' = any non-bulletin message\n");
  91.             printf ("             'x' = any message of type 'x'\n");
  92.             exit (0);
  93.  
  94.     default:
  95.             fprintf(stderr, "Unknown flag\n");
  96.             continue;
  97.  
  98.             }
  99.         }
  100.     if (argc<=0) {
  101.                 fprintf (stderr, "Insufficient arguments\n");
  102.                 exit(0);
  103.         }
  104.     port = *argv++;  argc--;
  105.     upper (port);
  106.     if (!argc) {
  107.         printf ("No port supplied.\n");
  108.         exit (0);
  109.         }
  110.     if (argc > MAXBOX) {
  111.         printf ("Too many mailboxes.\n");
  112.         exit (0);
  113.         }
  114. for (i = 0; i < argc; i++) printf ("%d: %s\n", i, argv[i]);
  115.     chdir (HOME);
  116.     strcpy (user.uscall, "AUTOFW");
  117.     user.usopt = ISSUPER;
  118.     intercept (signalman);
  119.     read_dist_list ();
  120.     read_fwd_files (argc, argv);
  121.     if (suck_flag)
  122.         for (i = 0; i < argc; i++)
  123.             suck (argv[i], port, fwdfile[i], fwdsize[i]);
  124.     else
  125.         for ( ; *priority; priority++)
  126.             for (i = 0; i < argc; i++) {
  127.                 if (*argv[i] != '*')
  128.                     if (forward (argv[i], port, fwdfile[i], fwdsize[i]) < 0)
  129.                         *argv[i] = '*';    /* error in forwarding, don't retry */
  130.                 if (quit) {
  131.                     printf ("quitting!\n");
  132.                     break;
  133.                     }
  134.                 }
  135.     }
  136.  
  137. pass_prior (head)
  138. struct msg_header *head;
  139. {
  140.     if (*priority == '*')
  141.         return 1;
  142.     if (toupper (*priority) == 'P' && !bulletin (head))
  143.         return 1;
  144.     if (toupper (*priority) == head->mhtype)
  145.         return 1;
  146.     return 0;
  147.     }
  148.  
  149. find_call (target)
  150. char *target;
  151. {
  152.     int i, p1, p2, comp;
  153.  
  154.     p1 = 0;  p2 = call_count-1;
  155.     if (debugflag)
  156.         printf ("find_call (%s)\n", target);
  157.     while (p1 <= p2) {
  158.         i = p1 + ((p2 - p1) >> 1);
  159.         comp = cmpcall (target, fwdcalls[i]);
  160.         if (debugflag)
  161.             printf ("  %d %d %d %s %d\n", p1, i, p2, fwdcalls[i], comp);
  162.         if (comp < 0)
  163.             p2 = i-1;
  164.         else if (comp > 0)
  165.             p1 = i+1;
  166.         else
  167.             break;
  168.         }
  169.     if (comp != 0) {
  170.         return -1;
  171.         }
  172.     while (i > 0 && cmpcall (target, fwdcalls[i-1]) == 0)
  173.         i--;
  174.     return (i);
  175.     }
  176.  
  177. test (head, mbox)
  178. struct msg_header *head;
  179. char *mbox;
  180. {
  181.     int i;
  182.     char *target;
  183.     struct dist_list *dp;
  184.     char bbs[7];
  185.  
  186.     if (!pass_prior (head)) {
  187.         return 0;
  188.         }
  189.     scanaddr (head->mhbbs, bbs, 7);
  190.     target = (*(head->mhbbs)) ? bbs : head->mhto;
  191.     if (debugflag)
  192.         {
  193.         printf ("test %d\n", head->mhnr);
  194.         printf ("target='%s'\n", target);
  195.         }
  196.     if ((i = find_call (target)) != -1)
  197.         for ( ; i < call_count && cmpcall (target, fwdcalls[i]) == 0; i++)
  198.             if (_cmpnam (target, fwdcalls[i], strlen (fwdcalls[i])) == 0)
  199.                 goto found;
  200.     if (/* !bulletin (head) && */ *(head->mhbbs)) {
  201.         char *p, hfield[7];
  202.         int len;
  203.         p = head->mhbbs + scanaddr (head->mhbbs, hfield, 7);
  204.         while (len = scanaddr (p, hfield, 7)) {
  205.             if (debugflag)
  206.                 printf ("  hfield '%s'\n", hfield);
  207.             p += len;
  208.             if ((i = find_call (hfield)) != -1) {
  209.                 for (dp = distboxes; dp; dp = dp->dlnext)
  210.                     if (strcmp (hfield, dp->dlname) == 0) break;
  211.                 if (dp) continue;
  212.                 for ( ; i < call_count && cmpcall (hfield, fwdcalls[i]) == 0; i++)
  213.                     if (_cmpnam (hfield, fwdcalls[i], strlen (fwdcalls[i])) == 0)
  214.                         goto found;
  215.                 }
  216.             }
  217.         }
  218.     return 0;
  219. found:
  220.     for (dp = distboxes; dp; dp = dp->dlnext)
  221.         if (strcmp (bbs, dp->dlname) == 0) break;
  222.     if (dp) {
  223.         char w[10];
  224.  
  225.         strcpy (w, mbox);
  226.         upper (w);
  227.         get_ssid (w);
  228.         for (i = 0; i < dp->dlcount; i++)
  229.             if (strcmp (w, dp->dlbbs[i]) == 0) break;
  230.         if ((1 << i) & head->mhdist)
  231.             return 0;
  232.         }
  233.     if (bigmail && head->mhsize > bigmail) {
  234.         return 0;
  235.         }
  236.     return 1;
  237.     }
  238.  
  239. forward (mbox, port, file, size)
  240. char *mbox, *port, *file;
  241. int size;
  242. {
  243.     struct msg_header *head;
  244.     int i, flag;
  245.     char str[20], path[90];
  246.     
  247.     read_fwd_file (mbox, file, size);
  248.     flag = 0;
  249.     open_mail ();
  250.     while ((head = next_mail (is_nforwarded, 0)) != NULL)
  251.         if (test (head, mbox)) {
  252.             flag = 1;
  253.             break;
  254.             }
  255.     if (!flag) {
  256.         close_mail ();
  257.         return 0;
  258.         }
  259.     if (!open_channel (port)) {
  260.         close_mail ();
  261.         return -1;
  262.         }
  263.         
  264.     if (strcmp (port, "T7") == 0)
  265.         write_path (ctl_out, "W32\n");
  266.  
  267.     flag = 0;
  268.     if (setjmp (disconnected)) {
  269.         flag = 1;
  270.         goto exit;
  271.         }
  272.     bid_flag = ok_flag = hflag = 0;
  273.     if (connect (mbox, path)) {
  274.         reset_mail (0);
  275.         get_prompt ();
  276.         if (ok_flag) {
  277.             sprintf (str, "%s\n", SID);
  278.             write_path (tnc_out, str);
  279.             get_prompt ();
  280.             }
  281.         start_fwd = tick();
  282.         while ((head = next_mail (is_nforwarded, 0)) != NULL && !quit)
  283.             {
  284.             if (test (head, mbox, port, path))
  285.                 if (!send_msg (head, mbox, port, path))
  286.                     flag = 1;
  287.             if (maxtime && (tick() - start_fwd) / sec > maxtime)
  288.                 {
  289.                 flag = 1;
  290.                 break;
  291.                 }
  292.             }
  293.         if (!flag && !quit && ok_flag && !norev_flag) {
  294.             if (setjmp (disconnected)) {
  295.                 strcpy (user.uscall, "AUTOFW");
  296.                 goto exit;
  297.                 }
  298.             reverse (mbox);
  299.             strcpy (user.uscall, "AUTOFW");
  300.             }
  301.         disconnect ();
  302.         }
  303.     else
  304.         flag = 1;
  305. exit:
  306.     close_channel (port);
  307.     close_mail (0);
  308.     return ((flag) ? -1 : 1);
  309.     }
  310.  
  311. suck (mbox, port, file, size)
  312. char *mbox, *port, *file;
  313. int size;
  314. {
  315.     struct msg_header *head;
  316.     int i, flag;
  317.     char str[20], path[90];
  318.     
  319.     read_fwd_file (mbox, file, size);
  320.     open_mail ();
  321.     if (!open_channel (port)) {
  322.         close_mail ();
  323.         return -1;
  324.         }
  325.     bid_flag = ok_flag = 0;
  326.     if (connect (mbox, path)) {
  327.         if (setjmp (disconnected)) {
  328.             strcpy (user.uscall, "AUTOFW");
  329.             goto exit;
  330.             }
  331.         get_prompt ();
  332.         if (ok_flag) {
  333.             sprintf (str, "%s\n", SID);
  334.             write_path (tnc_out, str);
  335.             get_prompt ();
  336.             }
  337.         reverse (mbox);
  338.         disconnect ();
  339.         }
  340. exit:
  341.     close_channel (port);
  342.     close_mail (0);
  343.     return (1);
  344.     }
  345.  
  346. send_msg (head, mbox, port, path)
  347. struct msg_header *head;
  348. char *mbox, *port, *path;
  349. {
  350.     char str[256], name[32], *p;
  351.     int f, len;
  352.     int time, date, tick;
  353.     short day;
  354.     struct fildes buffer;
  355.     struct dist_list *dp;
  356.     char bbs[7];
  357.  
  358. printf ("send_msg #%d\n", head->mhnr);
  359.     if ((f = open_msg (head)) < 0)
  360.         return 0;
  361.     p = str;
  362.     p += sprintf (p, "S%c %s", head->mhtype, head->mhto);
  363.     scanaddr (head->mhbbs, bbs, 7);
  364.     if (*(head->mhbbs)) 
  365.         if (hflag)
  366.             p+= sprintf (p, " @ %s", head->mhbbs);
  367.         else
  368.             p+= sprintf (p, " @ %s", bbs);
  369.     p += sprintf (p, " < %s", head->mhfrom);
  370.     if (head->mhbid[0] && bid_flag && head->mhtype != 'T')
  371.         p += sprintf (p, " $%s", head->mhbid);
  372.     p += sprintf (p, "\n");
  373.     write_path (tnc_out, str);
  374.     if (ok_flag) {
  375.         get_line (str);
  376.         p = str + scanword (str, name, 32);
  377.         if (strcmp (name, "OK") != 0) {
  378.             close (f);
  379.             get_prompt ();
  380.             log ("r %d %s %s", head->mhnr, mbox, p);
  381.             goto sent;
  382.             }
  383.         }
  384.     write_path (tnc_out, head->mhtit);
  385.     write_path (tnc_out, "\n");
  386.     if (!ok_flag) {
  387.         get_line (str);
  388.         get_line (str);
  389.         }
  390.     ztime (&head->mhtime, &head->mhdate, &day);
  391.     sprintf (str, "R:%02d%02d%02d/%02d%02dz @:%s.%s %s #:%d Z:%s\n",
  392.         (head->mhdate >> 16) % 100,
  393.         (head->mhdate >> 8) & 0xff,
  394.         head->mhdate & 0xff,
  395.         (head->mhtime >> 16) & 0xff,
  396.         (head->mhtime >> 8) & 0xff,
  397.         MYCALL, MYHADDR, MYQTH,
  398.         head->mhnr,
  399.         MYZIP);
  400.     write_path (tnc_out, str);
  401.     while ((len = read (f, str, 256)) > 0)
  402.         write (tnc_out, str, len);
  403.     close (f);
  404.     write_path (tnc_out, "\032\n");
  405.     get_prompt ();
  406.     log ("f %d %s %s", head->mhnr, port, path);
  407.  
  408. sent:
  409.     strcpy (str, mbox);
  410.     get_ssid (str);
  411.     reset_mail ();
  412.     head = next_mail (is_num, head->mhnr);
  413.     checkoff (head, "");
  414.     if (!checkoff (head, str))
  415.         if (bulletin (head))
  416.             head->mhstat = 'F';
  417.         else
  418.             head->mhstat = 'X';
  419.     update_mail ();
  420.     return 1;
  421.     }
  422.  
  423. get_prompt ()
  424. {
  425.     char str[256];
  426.     char *f1, *f2, *f3, *f4, *p;
  427.  
  428. printf ("get_prompt\n");
  429.     while (1) {
  430.         get_line (str);
  431.         if (str[strlen (str) - 1] == '>')
  432.             return;
  433.         else if ((f1 = strchr (str, '[')) == str && (f2 = strrchr (f1, ']')) &&
  434.                (f3 = strchr (f1, '-')) && f3 < f2 && (f4 = strrchr (f1, '-')) &&
  435.                f4 > f3) {
  436.             ok_flag = 1;
  437.             for (p = f4 + 1; p < f2; p++)
  438.                 switch (*p) {
  439.     case '$':    bid_flag++;  break;
  440.     case 'H':    hflag++;  break;
  441.     default:        break;
  442.                     }
  443.             }
  444.         else if ((f1 = strchr (str, '[')) == str && (f2 = strchr (f1, ']'))) {
  445.             *(f1+4) = '\0';
  446.             if (strcmp (f1+1, "MBL" == 0))
  447.                 ok_flag = bid_flag = 1;
  448.             }
  449.         }
  450.     }
  451.  
  452. reverse (mbox)
  453. {
  454.     char str[100], *p, w[40], mcall[9];
  455.     struct msg_header *head;
  456.     int date, time, tick;
  457.     short day;
  458.     int f;
  459.     int fromflag, makebid;
  460.     char type, to[7], from[7], bbs[39], bid[13];
  461.  
  462.     strcpy (mcall, mbox);
  463.     get_ssid (mcall);
  464.     strcpy (user.uscall, mcall);
  465.     while (1) {
  466.         write_path (tnc_out, "F>\n");
  467.         get_line (str);
  468.         if (toupper (*str) != 'S') {
  469.             disconnect ();
  470.             return;
  471.             }
  472.         fromflag = 0;
  473.         makebid = 0;
  474.         bbs[0] = '\0';
  475.         bid[0] = '\0';
  476.         p = str;
  477.         p += scanword (p, w, 40);
  478.         type = (isalpha (w[1])) ? toupper (w[1]) : ' ';
  479.         strcpy (from, mcall);
  480.         p += scanword (p, w, 40);
  481.         if (! *w)
  482.             disconnect ();    /* no addressee */
  483.         upper (w);
  484.         get_ssid (w);
  485.         strncpy (to, w, 7);
  486.         p += scanword (p, w, 40);
  487. again:
  488.         while (*w) {
  489.             if (*w == '@') {
  490.                 p += scanword (p, w, 40);
  491.                 if (*w) {
  492.                     upper (w);
  493.                     get_ssid (w);
  494.                     strncpy (bbs, w, 39);
  495.                     p += scanword (p, w, 40);
  496.                     goto again;
  497.                     }
  498.                 }
  499.             else if (*w == '<') {
  500.                 p += scanword (p, w, 40);
  501.                 if (*w) {
  502.                     upper (w);
  503.                     get_ssid (w);
  504.                     if ((user.usopt & ISBBS) || (user.usopt & ISSUPER))
  505.                         strncpy (from, w, 7);
  506.                     p += scanword (p, w, 40);
  507.                     fromflag++;
  508.                     goto again;
  509.                     }
  510.                 }
  511.             else if (*w == '$') {
  512.                 if (strlen (w) == 1) {
  513.                     p += scanword (p, w, 40);
  514.                     if (!*w)
  515.                         makebid++;
  516.                     }
  517.                 else
  518.                     strcpy (w, w+1);
  519.                 if (*w) {
  520.                     upper (w);
  521.                     strncpy (bid, w, 13);
  522.                     p += scanword (p, w, 40);
  523.                     goto again;
  524.                     }
  525.                 }
  526.             }
  527.         if (type == 'T') {
  528.             bid[0] = '\0';
  529.             makebid = 0;
  530.             }
  531.         if (bid[0] && (head = find_bid (bid))) {
  532.             write_path (tnc_out, "NO - duplicate BID\n");
  533.             checkoff (head, mcall);
  534.             continue;
  535.             }
  536.         if ((head = new_mail (0)) == NULL) {
  537.             write_path (tnc_out, "WAIT - mail system is full\n");
  538.             continue;
  539.             }
  540.         head->mhtype = type;
  541.         strcpy (head->mhfrom, from);
  542.         strcpy (head->mhto, to);
  543.         strcpy (head->mhbbs, bbs);
  544.         strcpy (head->mhbid, bid);
  545.         if (ok_flag)
  546.             sprintf (str, "OK %d\n", head->mhnr);
  547.         else
  548.             sprintf (str, "Enter title of message:\n");
  549.         write_path (tnc_out, str);
  550.         get_line (str);
  551.         strncpy (head->mhtit, str, 81);
  552.         strcpy (w, maildir);
  553.         header_to_name (head, w + strlen (maildir));
  554.         if ((f = create (w, S_IWRITE, S_IREAD+S_IWRITE)) == -1) {
  555.             sprintf (str, "Error %d creating message file %s.\n", errno, w);
  556.             write_path (tnc_out, str);
  557.             continue;
  558.             }
  559.         if (!ok_flag) {
  560.             sprintf (str, "Enter the message, ^Z to end.  It will be number %d\n",
  561.                 head->mhnr);
  562.             write_path (tnc_out, str);
  563.             }
  564.         if (getfile (f))
  565.             write (f, "\n", 1);
  566.         head->mhsize = _gs_size (f);
  567.         close (f);
  568.         header_to_name (head, w);
  569.         head->mhstat = 'N';
  570.         if (makebid && !head->mhbid[0])
  571.             sprintf (head->mhbid, "%d_%s", head->mhnr, MYCALL);
  572.         checkoff (head, mcall);
  573.         update_mail ();
  574.         log_send (head, fromflag);
  575.  
  576.         strcpy (w, "msgproc -q -b ");
  577.         sprintf (w + strlen (w), "%d", head->mhnr);
  578.         system (w);
  579.         
  580.         }
  581.     }
  582.  
  583. getfile (f)
  584. {
  585.     char line[300], *p;
  586.     int len, alarm, time = 0;
  587.  
  588.     time = tick ();
  589.     while (1) {
  590.         if (_gs_rdy (ctl_in) > 0)
  591.             check_status ();
  592.         if ((len = _gs_rdy (tnc_in)) > 0) {
  593.             time = tick ();
  594.             alarm = alm_set (SIGINT, ALARM);
  595.             len = read (tnc_in, line, (len > 256) ? 256 : len);
  596.             alm_delete (alarm);
  597.             for (p = line; p - line < len; p++)
  598.                 if (*p == '\032') {
  599.                     write (f, line, p-line);
  600.                     goto exit;
  601.                     }
  602.             write (f, line, len);
  603.             }
  604.         else
  605.             sleep (3);
  606.         if ((tick() - time) / sec > TIMEOUT) {
  607. printf ("TIMEOUT\n");
  608.             write_path (ctl_out, "D\n");
  609.             time = tick ();
  610.             }
  611.         }
  612. exit:
  613.     return (p-line);
  614.     }
  615.  
  616. get_line (str)
  617. char *str;
  618. {
  619.     int len;
  620.     int time = 0;
  621.     int status_disp, data_disp, data_send, data_ack, tries, state;
  622.  
  623.     time = tick ();
  624.     data_send = data_ack = -1;
  625.     while (1) {
  626.         if (data_send || data_ack) {
  627.             write_path (ctl_out, "L\n");
  628.             do read_path (ctl_in, str, 80); while (str[0] == '(');
  629. printf ("status %s\n", str);
  630.             scan_status (str, &status_disp, &data_disp, &data_send, 
  631.                                     &data_ack, &tries, &state);
  632.             if (state == 0 || quit)
  633.                 longjmp (disconnected, 2);
  634.             if (data_send || data_ack)
  635.                 time = tick ();
  636.             }
  637.         else if (_gs_rdy (ctl_in) > 0)
  638.             check_status ();
  639.         if (_gs_rdy (tnc_in) > 0) {
  640.             read_path (tnc_in, str, 256);
  641. printf ("get_line: '%s'\n", str);
  642.             return;
  643.             }
  644.         sleep (3);
  645.         if ((tick() - time) / sec > TIMEOUT) {
  646. printf ("TIMEOUT\n");
  647.             write_path (ctl_out, "D\n");
  648.             time = tick ();
  649.             }
  650.         }
  651.     }
  652.  
  653. disconnect ()
  654. {
  655. printf ("disconnect\n");
  656.     write_path (ctl_out, "D\n");
  657.     while (!check_disconnect ())
  658.         ;
  659.     }
  660.  
  661. check_status ()
  662. {
  663.     if (check_disconnect ())
  664.         longjmp (disconnected, 1);
  665.     }
  666.  
  667. check_disconnect ()
  668. {
  669.     char str[80];
  670.     char *p, w[20];
  671.     int len;
  672.  
  673.     read_path (ctl_in, str, 80);
  674. printf ("%s\n", str);
  675.     p = str;
  676.     p += scanword (p, w, 20);
  677.     if (strcmp (w, "CHANNEL") == 0) {
  678.         p += scanword (p, w, 20);
  679.         if (strcmp (w, "NOT") == 0) {
  680.             p += scanword (p, w, 20);
  681.             return (strcmp (w, "CONNECTED") == 0);
  682.             }
  683.         else
  684.             return 0;
  685.         }
  686.     p += scanword (p, w, 20);
  687.     if (strcmp (w, "LINK") == 0) {
  688.         p += scanword (p, w, 20);
  689.         if (strcmp (w, "FAILURE") != 0)
  690.             return 0;
  691.         }
  692.     else if (strcmp (w, "DISCONNECTED") != 0)
  693.         return 0;
  694.     return 1;
  695.     }
  696.  
  697. connect (mbox, path)
  698. char *mbox, *path;
  699. {
  700.     int i;
  701.     char str[90];
  702.  
  703.     if (path_count == 0) {
  704.         strcpy (path, mbox);
  705.         return (try_connect (mbox) == 1);
  706.         }
  707.     else
  708.         for (i = 0; i < path_count; i++) {
  709.             sprintf (str, "%s %s", mbox, paths[i]);
  710.             switch (try_connect (str)) {
  711.         case 0:    break;
  712.         case 1:    strcpy (path, str);
  713.                 return 1;
  714.         case -1:return 0;
  715.                 }
  716.             }
  717.     return 0;
  718.     }
  719.  
  720. try_connect (fpath)
  721. char *fpath;
  722. {
  723.     char str[95], w[20], *p;
  724.     int len;
  725.     int tries = 0;
  726.  
  727. printf ("try_connect %s\n", fpath);
  728.     for (p = fpath; *p; p++)
  729.         if (*p == '*') break;
  730.     if (*p)
  731.         return (netrom (fpath));
  732. again:    sprintf (str, "C %s\n", fpath);
  733.     write_path (ctl_out, str);
  734.     read_path (ctl_in, str, 95);
  735. printf ("%s\n", str);
  736.     p = str + scanword (str, w, 20);
  737.     p += scanword (p, w, 20);
  738.     if (strcmp (w, "CONNECTED") == 0)
  739.         return 1;
  740.     else if (strcmp (w, "BUSY") == 0 || strcmp (w, "STATION") == 0) {
  741. /*
  742.         scanword (fpath, w, 20);  if (strcmp (w, "W0RLI") == 0) return -1;
  743.         if (++tries > 4) return -1;
  744.         sleep (60);
  745.         goto again;
  746. */
  747.         return -1;
  748.         }
  749.     else
  750.         return 0;
  751.     }
  752.  
  753. netrom (fpath)
  754. char *fpath;
  755. {
  756.     char w[20], digis[10][12], str[95], str2[256], *p;
  757.     int i, j, k, dcount, tries;
  758.  
  759. printf ("netrom %s\n", fpath);
  760.     p = fpath;
  761.     p += scanword (p, w, 10);
  762.     dcount = 0;
  763.     do {
  764.         p += scanword (p, digis[dcount], 12);
  765.         } while (digis[dcount++][0]);
  766.     strcpy (digis[dcount-1], w);
  767.     for (i = 0; i < dcount-1; i++)
  768.         if (digis[i][0] == '*') break;
  769.     sprintf (str, "C %s", (digis[i][0] == '*') ? digis[i] + 1 : digis[i]);
  770.     for (j = 0; j < i; j++) {
  771.         strcat (str, " ");
  772.         if (digis[j][0] == '*')
  773.             strcat (str, digis[j] + 1);
  774.         else
  775.             strcat (str, digis[j]);
  776.         }
  777.     strcat (str, "\n");
  778.     write_path (ctl_out, str);
  779.     read_path (ctl_in, str, 95);
  780. printf ("  %s\n", str);
  781.     p = str + scanword (str, w, 20);
  782.     p += scanword (p, w, 20);
  783.     if (strcmp (w, "CONNECTED") != 0)
  784.         return 0;
  785.     i++;
  786.     while (i < dcount) {
  787.         for (j = i; j < dcount-1; j++)
  788.             if (digis[j][0] == '*') break;
  789.         sprintf (str, "C %s", (digis[j][0] == '*') ? digis[j] + 1 : digis[j]);
  790.         for (k = i; k < j; k++) {
  791.             strcat (str, " ");
  792.             if (digis[k][0] == '*')
  793.                 strcat (str, digis[k] + 1);
  794.             else
  795.                 strcat (str, digis[k]);
  796.             }
  797.         if (strcmp (str, "C ") == 0)
  798.             strcpy (str, "BBS");
  799.         strcat (str, "\n");
  800.         tries = 0;
  801. again:    write_path (tnc_out, str);
  802.         get_line (str2);
  803.         p = str2 + scanword (str2, w, 20);
  804.         p += scanword (p, w, 20);
  805.         if (strcmp (w, "Busy") == 0) {
  806. /*
  807.             if (strcmp (digis[dcount-1], "W0RLI") == 0) {disconnect(); return -1;}
  808.             if (++tries > 4) {
  809.                 disconnect ();
  810.                 return -1;
  811.                 }
  812.             sleep (60);
  813.             goto again;
  814. */
  815.             disconnect (); return -1;
  816.             }
  817.         else if (strcmp (w, "Connected") != 0) {
  818.             disconnect ();
  819.             return 0;
  820.             }
  821.         i = j + 1;
  822.         if (i == dcount - 1 && strcmp (digis[j], "*") == 0)
  823.             break;
  824.         }
  825.     return 1;
  826.     }
  827.  
  828. open_channel (port)
  829. char *port;
  830. {
  831.     int hostcmd;
  832.     int i, pid;
  833.     char str[40];
  834.  
  835.     strcpy (str, "/pipe/command.");
  836.     strcat (str, port);
  837.     if ((hostcmd = open (str, 2)) < 0)
  838.         return (0);
  839.     pid = getpid ();
  840.     sprintf (str, "o%d\n", pid);
  841.     write_path (hostcmd, str);
  842.     close (hostcmd);
  843.     sprintf (str, "/pipe/data_in.%d", pid);
  844.     for (i = 0; i < 10; i++) {
  845.         if ((tnc_in = open (str, 3)) != -1) break;
  846.         sleep (1);
  847.         }
  848.     if (tnc_in == -1)
  849.         return (0);
  850.     sprintf (str, "/pipe/data_out.%d", pid);
  851.     tnc_out = open (str, 3);
  852.     sprintf (str, "/pipe/ctl_in.%d", pid);
  853.     ctl_in = open (str, 3);
  854.     sprintf (str, "/pipe/ctl_out.%d", pid);
  855.     ctl_out = open (str, 3);
  856.     return (1);
  857.     }
  858.  
  859. close_channel (port)
  860. char *port;
  861. {
  862.     int hostcmd;
  863.     int i, j, pid;
  864.     char str[40];
  865.  
  866.     strcpy (str, "/pipe/command.");
  867.     strcat (str, port);
  868.     if ((hostcmd = open (str, 2)) < 0)
  869.         return (0);
  870.     pid = getpid ();
  871.     sprintf (str, "c%d\n", pid);
  872.     write_path (hostcmd, str);
  873.     close (hostcmd);
  874.     sleep (5);
  875.     drain (tnc_in);
  876.     drain (tnc_out);
  877.     drain (ctl_in);
  878.     drain (ctl_out);
  879.     close (tnc_in);
  880.     close (tnc_out);
  881.     close (ctl_in);
  882.     close (ctl_out);
  883.     sprintf (str, "/pipe/data_in.%d", pid);
  884.     for (i = 0; i < 10; i++) {
  885.         if (access (str, 0) == -1) break;
  886.         sleep (1);
  887.         }
  888.     if (i == 10) return 0;
  889.     return (1);
  890.     }
  891.  
  892. drain (path)
  893. {
  894.     int i, j;
  895.     char c;
  896.  
  897.     while ((i = _gs_rdy (path)) > 0) {
  898.         for (j = 0; j < i; j++)
  899.             read (path, &c, 1);
  900.         sleep (1);
  901.         }
  902.     }
  903.  
  904. write_path (path, str)
  905. char *str;
  906. {
  907.     write (path, str, strlen (str));
  908. if (path == tnc_out) writeln (1, str, strlen (str));
  909.     }
  910.  
  911. read_path (path, str, len)
  912. char *str;
  913. {
  914.     int i;
  915.     i = readln (path, str, len);
  916.     if (i)
  917.         str[i-1] = '\0';
  918.     return i;
  919.     }
  920.  
  921. read_fwd_file (mbox, file, size)
  922. char *mbox, *file;
  923. {
  924.     char str[80], w[7], *p, *p2;
  925.     int i, f, len;
  926.  
  927. printf ("read_fwd_file %s\n", mbox);
  928.     path_count = call_count = 0;
  929.     strcpy (str, mbox);
  930.     get_ssid (str);
  931.     strcpy (fwdcalls[call_count++], str);
  932.     for (p2 = file; p2 < file + size; p2 += strlen (p2) + 1) {
  933.         strcpy (str, p2);
  934.         p = str + scanword (str, w, 7);
  935.         if (strcmp (w, "VIA") == 0) {
  936.             while (isspace (*p))
  937.                 p++;
  938.             if (path_count < MAXPATHS)
  939.                 strcpy (paths[path_count++], p);
  940.             }
  941.         else if (*w && *w != '@' && *w != ';') {
  942.             get_ssid (w);
  943.             if (call_count < MAXCALLS)
  944.                 strcpy (fwdcalls[call_count++], w);
  945.             }
  946.         }
  947.     qsort (fwdcalls, call_count, 7, cmpcall);
  948.     if (debugflag)
  949.         for (i = 0; i < call_count; i++) printf ("  call %s\n", fwdcalls[i]);
  950.     }
  951.  
  952. read_fwd_files (argc, argv)
  953. char *argv[];
  954. {
  955.     char str[80], w[7], *p;
  956.     int i, f, len;
  957.     char *mbox;
  958.  
  959.     for (i = 0; i < argc; i++) {
  960.         mbox = argv[i];
  961.         if (debugflag)
  962.             printf ("processing %s\n", mbox);
  963.         upper (mbox);
  964.         strcpy (str, mbox);
  965.         for (p = str; *p; p++)
  966.             if (*p == '-')
  967.                 *p = '_';
  968.         strcat (str, ".fwd");
  969.         fwdfile[i] = (char *)malloc (1);
  970.         fwdsize[i] = read_file (str, &fwdfile[i], 0);
  971.         }
  972.     return (1);
  973.     }
  974.  
  975. read_file (name, pptr, size)
  976. char *name, **pptr;
  977. {
  978.     int f, fsize, tsize;
  979.     char *fptr, *p, line[80];
  980.     
  981.     if (debugflag)
  982.         printf ("read_file (%s, %x(%x), %d)\n", name, pptr, *pptr, size);
  983.     if (*name == '/')
  984.         strcpy (line, name);
  985.     else
  986.         sprintf (line, "%s/%s", FWDIR, name);
  987.     if ((f = open (line, 1)) < 0)
  988.         return (size);
  989.     fsize = _gs_size (f);
  990.     fptr = (char *)malloc (size + fsize);
  991.     if (debugflag)
  992.         printf ("  new ptr=%x size=%d\n", fptr, size);
  993.     if (size) movmem (*pptr, fptr, size);
  994.     read (f, fptr + size, fsize);
  995.     close (f);
  996.     for (p = fptr + size; p - fptr < size + fsize; p++) {
  997.         *p = toupper (*p);
  998.         if (*p == '\n')
  999.             *p = '\0';
  1000.         }
  1001.     free (*pptr);
  1002.     *pptr = fptr;
  1003.     tsize = size + fsize;
  1004.     for (p = fptr + size; p - fptr < size + fsize; p += strlen (p) + 1) {
  1005.         if (*p == '@') {
  1006.             strcpy (line, p+1);
  1007.             tsize = read_file (line, pptr, tsize);
  1008.             p = *pptr + (p - fptr);
  1009.             fptr = *pptr;
  1010.             }
  1011.         }
  1012.     return (tsize);
  1013.     }
  1014.     
  1015. signalman (signal)
  1016. {
  1017.     switch (signal) {
  1018. case SIGQUIT:
  1019.         quit = 1;
  1020.         break;
  1021. case SIGINT:
  1022.         interrupt = 1;
  1023.         break;
  1024. default:
  1025.         break;
  1026.         
  1027.         }
  1028.     }
  1029.  
  1030. tick ()
  1031. {
  1032.     int time, date, i_tick;
  1033.     short day;
  1034.  
  1035.     _sysdate (3, &time, &date, &day, &i_tick);
  1036.     sec = i_tick >> 16;
  1037.     return (time * sec + (i_tick & 0xFFFF));
  1038.     }
  1039.  
  1040. scan_status (s, a, b, c, d, x, f)
  1041. char *s;
  1042. int *a, *b, *c, *d, *x, *f;
  1043. {
  1044.     char *p, w[20];
  1045.  
  1046.     p = s;
  1047.     p += scanword (p, w, 20);
  1048.     *a = atoi (w);
  1049.     p += scanword (p, w, 20);
  1050.     *b = atoi (w);
  1051.     p += scanword (p, w, 20);
  1052.     *c = atoi (w);
  1053.     p += scanword (p, w, 20);
  1054.     *d = atoi (w);
  1055.     p += scanword (p, w, 20);
  1056.     *x = atoi (w);
  1057.     p += scanword (p, w, 20);
  1058.     *f = atoi (w);
  1059.     }
  1060.  
  1061. cmpcall (c1, c2)
  1062. register char *c1, *c2;
  1063. {
  1064.     while (*c1 == *c2) {
  1065.         if (*c1 == '\0') return 0;
  1066.         c1++;
  1067.         c2++;
  1068.         }
  1069.     if (*c1 == '?' || *c1 == '*' || *c2 == '?' || *c2 == '*')
  1070.         return 0;
  1071.     else
  1072.         return (*c1 - *c2);
  1073.     }
  1074.  
  1075.