home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* */
- /* ------------ 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 mail_stat (MAILP);
- int xmit_install (MAILP, ADDRP);
- MAILP xmit_find (MAILP, ADDRP);
- long netsize (MAILP);
- int any_mail (MAILP);
- void do_xmit_line (char *, MAILP);
- void xmit_sort (void);
- char *numdisp (long);
-
- #ifdef MILQ
- static char *HoldFmtStr = "%16.16s %4.4s %5.5s %c";
- static char *HoldNoSize = "%21.21s %5.5s %c";
- #else
- static char *HoldFmtStr = "%-16.16s %4.4s %5.5s %c";
- static char *HoldNoSize = "%-21.21s %5.5s %c";
- #endif
-
- void xmit_sameplace ()
- {
- MAILP p, p1;
-
- /* Find the guy we just gave mail to */
- p = find_mail (&remote_addr);
- remote_addr.Zone = remote_addr.Net = remote_addr.Node = remote_addr.Point = 0;
- remote_addr.Domain = NULL;
- if (p == NULL)
- {
- /* He is not there */
- return;
- }
-
- /* Save our current pointer */
- p1 = next_mail;
- if (p != next_mail)
- {
- /* If it is not the one we just gave mail to, save ptr and delete */
- next_mail = p;
- xmit_delete ();
- next_mail = p1;
- }
- else
- {
- /* It was the guy at the head of the list, so just delete him */
- xmit_delete ();
- }
-
- /* If we came in with a null, leave with a null */
- if (p1 == NULL)
- next_mail = NULL;
-
- return;
- }
-
- MAILP find_mail (ADDRP address)
- {
- MAILP p;
-
- p = mail_top;
- while (p != NULL)
- {
- if ((no_zones || (p->mail_addr.Zone == address->Zone)) &&
- (p->mail_addr.Net == address->Net) &&
- (p->mail_addr.Node == address->Node) &&
- (p->mail_addr.Point == address->Point) &&
- ((p->mail_addr.Domain == address->Domain) ||
- ((p->mail_addr.Domain == my_addr.Domain) &&
- (address->Domain == NULL))))
- break;
- p = p->next;
- }
-
- return (p);
- }
-
- int xmit_install (MAILP p, ADDRP addr)
- {
- MAILP p1, p2;
- int rettype;
- long sztemp;
-
- p2 = find_mail (addr);
-
- if (p2 == NULL)
- {
- /* We didn't find it in what we have already */
- p1 = p;
- p1->mail_addr = *addr;
- rettype = 0;
- }
- else
- {
- /* We found it, so we have to make sure the higher level routine knows */
- p1 = p2;
- rettype = 1;
- }
-
- /*
- * Get the size of the entry. If it's a FLO-type file,
- * call netsize to find out how big the stuff contained in it
- * actually is. If it's a packet, just take its size.
- *
- * Hold packets don't count.
- */
-
- if (!no_size)
- {
- sztemp = 0L;
-
- if (!strncmp (&(dta_str.name[10]), "LO", 2))
- p1->mailsize += (sztemp = netsize (p1));
-
- else
- if (!strncmp (&(dta_str.name[10]), "UT", 2))
- p1->mailsize += (sztemp = dta_str.size);
-
- if (dta_str.name[9] != 'H')
- p1->callsize += sztemp;
- }
-
- switch (dta_str.name[9])
- {
- case 'C': /* Crash */
- p1->mailtypes |= MAIL_CRASH;
- break;
-
- case 'H': /* Hold */
- p1->mailtypes |= MAIL_HOLD;
- break;
-
- case 'F': /* Normal */
- case 'O':
- p1->mailtypes |= MAIL_NORMAL;
- break;
-
- case 'D': /* Direct */
- p1->mailtypes |= MAIL_DIRECT;
- break;
-
- case 'R': /* Request */
- p1->mailtypes |= MAIL_REQUEST;
- break;
- }
-
- if (!nodefind (&(p1->mail_addr), 0))
- {
- p1->mailtypes |= MAIL_UNKNOWN;
- return (rettype);
- }
-
- /* Don't call for "HOLD" or "REQ" stuff. */
- if ((dta_str.name[9] == 'H') || (dta_str.name[9] == 'R'))
- {
- return (rettype);
- }
-
- /* If there's no event, set mail to 'go' */
- if (cur_event < 0)
- {
- p1->mailtypes &= ~MAIL_QSMALL;
- p1->mailtypes |= MAIL_WILLGO;
- return (rettype);
- }
-
- /* If it is a crash only event and we have crashmail, set it to go */
-
- if (e_ptrs[cur_event].behavior & MAT_HIPRICM)
- {
- if ((dta_str.name[9] == 'C') && (newnodedes.NodeFlags & B_CM))
- {
- p1->mailtypes &= ~MAIL_QSMALL;
- p1->mailtypes |= MAIL_WILLGO;
- return (rettype);
- }
- }
-
- /* If it is a crash only event and this wasn't crash, return */
- if ((dta_str.name[9] != 'C') && (e_ptrs[cur_event].behavior & MAT_CM))
- {
- return (rettype);
- }
-
- /* Is this a local only event? */
- if (e_ptrs[cur_event].behavior & MAT_LOCAL)
- {
- /*
- * If this is supposed to be only local, then get out if it isn't
- */
- if (e_ptrs[cur_event].node_cost >= 0)
- {
- if ((int) newnodedes.RealCost > e_ptrs[cur_event].node_cost)
- {
- return (rettype);
- }
- }
- else
- {
- if ((int) newnodedes.RealCost < -(e_ptrs[cur_event].node_cost))
- {
- return (rettype);
- }
- }
- }
-
- /* Is this a non-mail window event? */
- if ((newnodelist || version7) &&
- (!(e_ptrs[cur_event].behavior & MAT_NOMAIL24)))
- {
- /* If this guy can't handle crash, get out and try again */
- if (!(newnodedes.NodeFlags & B_CM))
- {
- return (rettype);
- }
- }
-
- /* Is this a receive only event? */
- if (e_ptrs[cur_event].behavior & MAT_NOOUT)
- {
- return (rettype);
- }
-
- /* Is this a non-CM event? */
- if ((newnodelist || version7) &&
- (e_ptrs[cur_event].behavior & MAT_NOCM) &&
- (newnodedes.NodeFlags & B_CM))
- {
- return (rettype);
- }
-
- /* See if we spent too much calling him already */
- if (bad_call (&(p1->mail_addr), 0))
- {
- p1->mailtypes |= MAIL_TOOBAD;
- return (rettype);
- }
-
- /* See if we have enough mail to send */
- if (!no_size && e_ptrs[cur_event].mailqsize > p1->callsize)
- {
- p1->mailtypes |= MAIL_QSMALL;
- return(rettype);
- }
-
- p1->mailtypes &= ~MAIL_QSMALL;
- p1->mailtypes |= MAIL_WILLGO;
-
- return (rettype);
- }
-
- char mail_stat (MAILP p)
- {
- if (p->mailtypes & MAIL_UNKNOWN)
- return ('!');
- if (p->mailtypes & MAIL_TOOBAD)
- return ('x');
- if (p->mailtypes & MAIL_TRIED)
- return ('#');
- if (p->mailtypes & MAIL_WILLGO)
- return ('*');
- if (p->mailtypes & MAIL_QSMALL)
- return ('<');
- return ('-');
- }
-
- char *mail_status_chars (unsigned int);
-
- char msc[10];
-
- char *mail_status_chars (unsigned int p)
- {
- char *q;
-
- q = msc;
-
- if (p & MAIL_CRASH )
- *q++ = 'C';
- if (p & MAIL_HOLD )
- *q++ = 'H';
- if (p & MAIL_DIRECT )
- *q++ = 'D';
- if (p & MAIL_NORMAL )
- *q++ = 'N';
- if (p & MAIL_REQUEST)
- *q++ = 'R';
- *q++ = '\0';
-
- return (msc);
- }
-
- void xmit_window (MAILP p1)
- {
- MAILP p;
- int i;
- char j1[32];
- char *jPtr;
-
- #ifdef MILQ
- RECT Rect;
- int Width;
- #endif
-
- if (!fullscreen)
- return;
-
- p = p1;
-
- sb_fillc (hold_hWnd, ' ');
- jPtr = j1;
- #ifdef MILQ
- GetClientRect( hold_hWnd, &Rect );
- SB_ROW_HOLD = Rect.bottom + 2;
- if ( 30 > ( Width = Rect.right - Rect.left ) )
- jPtr += 30 - Width;
- #endif
-
- if (p == NULL)
- {
- sb_move (hold_hWnd, 3, 5);
- SendMessage( hold_hWnd, WM_COMMAND, GD_MODE, 0L );
- SendMessage( hold_hWnd, WM_COMMAND, GD_CLR, 0L );
- sb_puts( hold_Init, MSG_TXT(M_NOTHING_IN_OUTBOUND) );
- return;
- }
-
- SendMessage( hold_hWnd, WM_COMMAND, GD_MODE, 1L );
- SendMessage( hold_hWnd, WM_COMMAND, GD_CLR, 0L );
-
- #ifdef MILQ
- if ( hold_hWnd == GetFocus() )
- SendMessage( node_hWnd, WM_COMMAND, GD_PND, (long)&p->mail_addr );
- #endif
-
- strcpy( j1, MSG_TXT(M_OUTBOUND_HEADER) );
- sb_move (hold_hWnd, 1, 2);
- sb_puts( hold_Hdr, jPtr);
- for (i = 2; i < SB_ROW_HOLD; i++)
- {
- if (p == NULL)
- break;
-
- do_xmit_line (j1, p);
-
- sb_move (hold_hWnd, i, 2);
- sb_puts( HoldWndDtl(i), jPtr);
- p = p->next;
- }
-
- p = mail_top;
-
- for (; i < SB_ROW_HOLD; i++)
- {
- if ((p == p1) || (p == NULL))
- break;
-
- do_xmit_line (j1, p);
-
- sb_move (hold_hWnd, i, 2);
- sb_puts( HoldWndDtl(i), jPtr);
- p = p->next;
- }
- SendMessage( hold_hWnd, WM_COMMAND, GD_CLR, (long)i );
- sb_show ();
- }
-
- void do_xmit_line (char *line, MAILP p)
- {
- if (no_size)
- {
- (void) sprintf (line, HoldNoSize,
- Full_Addr_Str (&(p->mail_addr)),
- mail_status_chars (p->mailtypes),
- mail_stat (p));
- }
- else
- {
- (void) sprintf (line, HoldFmtStr,
- Full_Addr_Str (&(p->mail_addr)),
- numdisp (p->mailsize),
- mail_status_chars (p->mailtypes),
- mail_stat (p));
- }
- }
-
-
- void xmit_sort ()
- {
- MAILP p, p1, p2;
-
- p = mail_top;
-
- /* Find the first that is sendable */
- while (p != NULL)
- {
- if ((p->mailtypes & MAIL_WILLGO) &&
- (!(p->mailtypes & MAIL_TOOBAD)) &&
- (!(p->mailtypes & MAIL_UNKNOWN)))
- break;
- p = p->next;
- }
-
- if (p == NULL)
- return;
-
- /* Put the first sendable one on top */
- if (p != mail_top)
- {
- p->prev->next = p->next;
- if (p->next != NULL)
- p->next->prev = p->prev;
- p->prev = NULL;
- p->next = mail_top;
- mail_top->prev = p;
- mail_top = p;
- }
-
- p1 = p;
- p = p1->next;
- while (p != NULL)
- {
- if ((p->mailtypes & MAIL_WILLGO) &&
- (!(p->mailtypes & MAIL_TOOBAD)) &&
- (!(p->mailtypes & MAIL_UNKNOWN)))
- {
- if (p->prev == p1)
- {
- p1 = p;
- p = p->next;
- continue;
- }
- p2 = p->next;
- p->prev->next = p->next;
- if (p->next != NULL)
- p->next->prev = p->prev;
- p->next = p1->next;
- if (p1->next != NULL)
- p1->next->prev = p;
- p->prev = p1;
- p1->next = p;
- p1 = p;
- p = p2;
- }
- else
- {
- p = p->next;
- }
- }
- }
-
- void xmit_reset ()
- {
- MAILP p;
- int j, k, done, zone;
- char *q, *s;
- char *domain;
- char *HoldName;
- char pointspec[128];
- ADDR tmp;
- struct FILEINFO zone_dir;
- struct FILEINFO pnt_dir;
- long longzone;
-
- /* First get rid of all the old junk */
- p = mail_top;
- if (p != NULL)
- {
- while (p->next != NULL)
- p = p->next;
- while (p->prev != NULL)
- {
- p = p->prev;
- free (p->next);
- }
- if (p != NULL)
- free (p);
- }
-
- p = mail_top = NULL;
-
- /*
- * Initialize domain to scan. Choose (of course) the
- * domain of our primary address.
- *
- * This domain is special in that its outbound is hold_area.
- * All the other domains use their abbreviation as the name
- * of their outbounds.
- */
-
-
- k = 0;
- domain = domain_name[0];
- (void) strcpy (pointspec, hold_area);
- q = &(pointspec[strlen (pointspec)]) - 1;
- do
- {
- /*
- * Initialize scan of zones in this domain. Using findfirst/findnext,
- * get all the matching directories.
- */
- (void) strcpy (q, ".*");
- j = 0;
- while (!dfind (&zone_dir, pointspec, j))
- {
- j = 1; /* Flip findfirst/findnext to findnext */
- /*
- * We have a match on the outbound spec. Make sure it's a directory.
- *
- * Then:
- *
- * 1) If no extension, we may only use it if this is alias 0
- * 2) If an extension, it must be a 3-digit hex number
- *
- * If the extension passes one of these tests, get to work!
- */
- if (!(zone_dir.attr & FA_SUBDIR))
- continue;
-
- q = strchr (zone_dir.name, '.');
- if (q == NULL)
- {
- if (k != 0 && !no_zones)
- continue;
- zone = (int) alias[0].Zone;
- }
- else
- {
- if (no_zones)
- continue;
- s = ++q;
- longzone = strtol (q, &q, 16);
- if ((s + 3) != q)
- continue;
- zone = (int) longzone;
- }
- /*
- * OK. We have a domain, an outbound directory, and a zone.
- * That means there's an outbound to scan.
- *
- * Start by scanning the nodes.
- */
- tmp.Zone = zone;
- tmp.Domain = domain;
- tmp.Net = tmp.Node = tmp.Point = 0;
- p = xmit_find (p, &tmp);
- /*
- * Now we do the points contained in this outbound.
- *
- */
- if (pvtnet <= 0)
- {
- HoldName = HoldAreaNameMunge (&tmp);
- (void) sprintf (pointspec, "%s*.PNT", HoldName);
- j = 0;
- done = 0;
-
- while (!done)
- {
- /* See if we have any more at this level */
- if (dfind (&pnt_dir, pointspec, j++))
- {
- /* No more at this level, so go to next level */
- done = 1;
- }
- else
- {
- if (sscanf (pnt_dir.name, "%04x%04x.", &(tmp.Net), &(tmp.Node)) != 2)
- continue;
- tmp.Point = 1;
- p = xmit_find (p, &tmp);
-
- } /* got one */
- } /* while (!done) */
- }
- } /* while !dfind (...) to get outbounds */
- /*
- * See if there are any more domains. If so, set up the right name
- * for the outbound, so we can find 'em.
- */
- if ((domain = domain_name[++k]) != NULL)
- {
- *domain_loc = '\0';
- (void) strcpy (pointspec, domain_area);
- q = &(pointspec[strlen (pointspec)]);
- s = domain_abbrev[k];
- if (s != NULL)
- while (*s)
- *q++ = *s++;
- }
- } while (domain != NULL);
- next_mail = NULL;
- xmit_sort ();
- xmit_window (mail_top);
- next_rescan = (long) time (NULL) + 600L; /* At least 10 min to next scan */
- }
-
- MAILP xmit_find (MAILP p, ADDRP address)
- {
- int j;
- char next_one [127];
- char *HoldName;
- ADDR tmp;
-
- tmp = *address;
-
- HoldName = HoldAreaNameMunge (address);
-
- if (address->Point != 0)
- {
- (void) sprintf (next_one, "%s%04x%04x.PNT\\*.*",
- HoldName, address->Net, address->Node);
- tmp.Point = 0;
- }
- else
- {
- (void) sprintf (next_one, "%s*.*", HoldName);
- tmp.Net = 0;
- tmp.Node = 0;
- tmp.Point = 0;
- }
-
- j = 0;
-
- while (!dfind (&dta_str, next_one, j))
- {
- j = 1;
-
- /* We have a match. Was it a .FLO file or a .OUT file? */
- if (strncmp (&(dta_str.name[10]), "LO", 2) == 0)
- {
- /* FLO, DLO, CLO and HLO are the only ones! */
- if (strchr ("FDCH", dta_str.name[9]) == NULL)
- continue;
- }
- else
- if (strncmp (&(dta_str.name[10]), "UT", 2) == 0)
- {
- /* OUT, DUT, CUT and HUT are the only ones! */
- if (strchr ("ODCH", dta_str.name[9]) == NULL)
- continue;
- }
- else
- if (strncmp (&(dta_str.name[9]), "REQ", 3) != 0)
- continue;
-
-
- /* We found a name, remember it */
- if (address->Point != 0)
- {
- if (sscanf (dta_str.name, "%08x.", &(tmp.Point)) != 1)
- continue;
- }
- else if (sscanf (dta_str.name, "%04x%04x.", &(tmp.Net), &(tmp.Node)) != 2)
- continue;
-
- if (p == NULL)
- {
- p = mail_top = (MAILP) calloc (sizeof (MAIL), 1);
- }
- else
- {
- p->next = (MAILP) calloc (sizeof (MAIL), 1);
- p->next->prev = p;
- p = p->next;
- }
-
- if (xmit_install (p, &tmp))
- {
- /* No good */
- if (p->prev != NULL)
- {
- p = p->prev;
- free (p->next);
- p->next = NULL;
- }
- else
- {
- free (p);
- p = mail_top = NULL;
- }
- }
-
- } /* while (!done) */
- return (p);
- }
-
- int xmit_next (ADDRP xaddr)
- {
- int i, j;
-
- for (i = 0; i < 2; i++)
- {
- /* Set up the proper pointer */
- if ((next_mail == NULL) || (next_mail->next == NULL))
- {
- if (next_rescan < (long) time (NULL))
- xmit_reset ();
- next_mail = mail_top;
- }
- else
- {
- next_mail = next_mail->next;
- }
-
- /* Loop through till we find something we can send */
- while (next_mail != NULL)
- {
- if ((next_mail->mailtypes & MAIL_WILLGO) &&
- (!(next_mail->mailtypes & MAIL_UNKNOWN)) &&
- (!(next_mail->mailtypes & MAIL_TOOBAD)))
- {
- if (bad_call (&(next_mail->mail_addr), 0))
- {
- next_mail->mailtypes |= MAIL_TOOBAD;
- }
- else
- {
- /* If multitasking, check for mail before calling */
- if ((TaskNumber != 0) && ((j = any_mail (next_mail)) <= 0))
- {
- if (j == 0)
- xmit_delete ();
- else next_mail = next_mail->next;
- continue;
- }
- *xaddr = next_mail->mail_addr;
- xmit_window (next_mail);
- return (1);
- }
- }
- next_mail = next_mail->next;
- }
- }
- /* Oh well, we tried */
- xmit_window (mail_top);
- return (0);
- }
-
- void xmit_delete ()
- {
- MAILP p;
-
- if (next_mail == NULL)
- return;
-
- if (any_mail (next_mail) != 0)
- {
- status_line (MSG_TXT(M_STILL_HAVE_MAIL), Full_Addr_Str (&(next_mail->mail_addr)));
- /* We still have something for him */
- next_mail->mailtypes &= ~MAIL_WILLGO;
- next_mail->mailtypes |= MAIL_TRIED;
- return;
- }
-
- if (next_mail != mail_top)
- {
- p = next_mail->next;
- next_mail = next_mail->prev;
- free (next_mail->next);
- next_mail->next = p;
- if (p != NULL)
- p->prev = next_mail;
- xmit_window (next_mail);
- }
- else
- {
- mail_top = mail_top->next;
- free (next_mail);
- if (mail_top != NULL)
- mail_top->prev = NULL;
- xmit_window (mail_top);
- next_mail = NULL;
- }
- }
-
- int bad_call (ADDRP baddr, int rwd)
- {
- int res;
- int i, j;
- struct FILEINFO bad_dta;
- FILE *bad_wazoo;
- char *p;
- char *HoldName;
-
- char fname[128];
- char fname1[128];
-
- HoldName = HoldAreaNameMunge(baddr);
- (void) sprintf (fname, "%s%s.$$?", HoldName, Hex_Addr_Str (baddr));
- j = (int) strlen (fname) - 1; /* Point at ? */
- res = -1; /* Initialize to fail */
-
- i = 0; /* This says findfirst */
- while (!dfind (&bad_dta, fname, i)) /* as long as we match */
- {
- if (isdigit (bad_dta.name[11])) /* is there a digit? */
- {
- fname[j] = bad_dta.name[11]; /* Yes, copy to fname */
- res = fname[j] - '0'; /* Save it for testing */
- break; /* Get out of while */
- }
- else i = 1; /* Else use findnext */
- }
-
- if (res == -1) /* Successful search? */
- {
- fname[j] = '0'; /* No, base digit = 0 */
- }
-
- if (rwd > 0)
- {
- /* Writing a bad call */
-
- /* First create a filename that is one higher than what we've got */
- (void) strcpy (fname1, fname);
- fname1[j]++;
- if (fname1[j] > '9')
- fname1[j] = '9';
-
- if (res == -1) /* Did we have a file? */
- { /* No, make one. */
- if (rwd == 2) /* No carrier */
- res = open (fname, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
- else /* With carrier */
- res = open (fname1, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
- i = rwd - 1; /* zero-based count */
- (void) write (res, (char *) &i, sizeof (int)); /* write it out */
- (void) close (res); /* close the file */
- }
- else
- { /* There was a file */
-
- /*
- * 2 = Unsuccessful, No carrier. Update contents of the file.
- */
-
- if (rwd == 2)
- {
- i = open (fname, O_RDONLY|O_BINARY);
- (void) read (i, (char *) &res, sizeof (int));
- (void) close (i);
-
- ++res;
-
- i = open (fname, O_CREAT|O_WRONLY|O_BINARY, S_IREAD|S_IWRITE);
- (void) write (i, (char *) &res, sizeof (int));
- (void) close (i);
- }
-
- /*
- * 1 = Unsuccessful, Carrier. Update file name to reflect the
- * failure.
- */
-
- else
- {
- (void) rename (fname, fname1);
- }
- }
- }
- else if (rwd == 0)
- {
-
- /*
- * 0 = We are reading a bad call status
- */
-
- /* Is it automatically ok (no .$$ file there) ? */
- if (res == -1)
- return (0);
-
- /* Were there too many connects with carrier? */
- if (res >= max_connects)
- return (1);
-
- /* Ok, check for connects without carrier */
- res = 0;
- i = open (fname, O_RDONLY|O_BINARY);
- (void) read (i, (char *) &res, sizeof (int));
- (void) close (i);
- return (res >= max_noconnects);
- }
- else
- {
-
- /*
- * -1 = Cleanup of bad call status. This happens in two steps:
- * a) delete 'netnode.$$?' in hold area;
- * b) if a 'netnode.Z' file exists in hold area,
- * 1) delete all BADWAZOO.xxx files listed in the .Z file;
- * 2) delete the 'netnode.z' file.
- */
-
- if (res != -1)
- {
- (void) unlink (fname);
- }
-
- if (!mail_finished)
- return (0);
-
- (void) sprintf (fname, "%s%s.Z", HoldName, Hex_Addr_Str (baddr));
- if (dexists (fname))
- {
- if ((bad_wazoo = fopen (fname, read_ascii)) == NULL)
- {
- (void) got_error (MSG_TXT(M_OPEN_MSG), fname);
- }
- else
- {
- while (!feof (bad_wazoo))
- {
- e_input[0] = '\0';
- if (!fgets (e_input, 64, bad_wazoo))
- break;
- /* Point to BADWAZOO.xxx */
- p = strchr (e_input, ' ') + 1;
- /* Then just past it and terminate */
- p = strchr (p, ' ');
- *p = '\0';
- /* Back to where we were */
- p = strchr (e_input, ' ') + 1;
-
- /* Build file name and delete file */
- (void) strcpy (fname1, CURRENT.sc_Inbound);
- (void) strcat (fname1, p);
- (void) unlink (fname1);
- }
- (void) fclose (bad_wazoo);
- }
- (void) unlink (fname);
- }
- }
- return (0);
- }
-
- void set_up_outbound ()
- {
- MAILP mp;
-
- xmit_reset ();
-
- /* and remember where we left off */
- if (hist.next_addr.Net != 0)
- {
- next_addr = hist.next_addr;
- next_addr.Domain = NULL;
- mp = find_mail (&next_addr);
- if ((mp == NULL) || (mp->prev == NULL))
- {
- next_mail = NULL;
- xmit_window (mail_top);
- }
- else
- {
- next_mail = mp->prev;
- xmit_window (next_mail);
- }
- }
- else
- {
- next_addr.Zone = 0;
- next_addr.Net = 0;
- next_addr.Node = 0;
- next_addr.Point = 0;
- next_addr.Domain = NULL;
- xmit_window (mail_top);
- }
- }
- /*
- * Calculate size of mail queued for outbound.
- * Used to determine whether or not we have enough
- * mail to merit an outbound call.
- *
- * The original version of this code was donated by Henry Clark.
- */
-
- long netsize (MAILP p)
- {
- struct stat stbuf;
- char net_path[127];
- char *ptr;
- FILE *temp;
- long accum = 0L;
- char *q;
-
- /* Append the ARCmail file name to the path line */
- (void) sprintf (net_path, "%s%s.%s",
- HoldAreaNameMunge(&(p->mail_addr)),
- Hex_Addr_Str (&(p->mail_addr)),
- &dta_str.name[9]);
-
- temp = share_fopen (net_path, "rb", DENY_WRITE);
-
- if (temp == (FILE *)NULL)
- return (accum);
-
- while (!feof (temp))
- {
- /*
- * Make sure of a nice zero there if we're at an undetected EOF.
- * Then try to read a line from the file.
- */
- net_path[0] = '\0';
- (void) fgets (net_path, 79, temp);
- /*
- * Clean up anything we don't want to see (blanks, tabs, CR, etc)
- */
- for (q = ptr = net_path; *q; q++)
- if (*q <= ' ')
- *q = '\0';
- /*
- * File disposition commands should be skipped over to get to
- * actual filenames.
- */
- if ((*ptr == TRUNC_AFTER) ||
- (*ptr == DELETE_AFTER) ||
- (*ptr == SHOW_DELETE_AFTER) ||
- (*ptr == NOTHING_AFTER))
- ptr++;
- /*
- * Now -- if what's left starts with a semicolon, it's a comment.
- * If it starts with a tilde, the file has already been sent. If
- * what we see is a zero, there's nothing on the line. In any one
- * of these cases, we should skip this line.
- */
- if ((*ptr == '\0') ||
- (*ptr == ';') ||
- (*ptr == '~'))
- continue;
- /*
- * Get the file size by doing a stat call. If it's not there
- * then we obviously need not add any size in.
- */
- if (stat (ptr, &stbuf)) /* file exist? */
- continue;
- else accum += stbuf.st_size;
- }
- (void) fclose (temp);
- return (accum);
- }
-
- /*
- * Figure out if there's any mail for the specified node.
- * Used to determine if we need to actually make a call.
- *
- * Returns 0 for no mail at all
- * 1 for non-hold mail
- * -1 for hold mail only
- *
- * I can't remember who was the first to demand this. I've been
- * pummelled for a while and there's almost certainly been a loss
- * of grey matter.
- */
-
- int any_mail (MAILP node)
- {
- struct FILEINFO dta;
- char next_one [127];
- int ret = 0;
-
- (void) sprintf (next_one, "%s%s.*",
- HoldAreaNameMunge(&(node->mail_addr)),
- Hex_Addr_Str (&(node->mail_addr)));
-
- if (dfind (&dta, next_one, 0))
- return (0);
-
- do
- {
- #ifndef JACK_DECKER
- if (dta.name[9] == 'H')
- {
- ret = -1;
- continue;
- }
- #endif
- if (!strncmp (&(dta.name[10]), "LO", 2))
- return (1);
-
- if (!strncmp (&(dta.name[10]), "UT", 2))
- return (1);
- } while (!dfind (&dta, next_one, 1));
-
- return (ret);
- }
-
- /*
- * Create a small character string for mailsize.
- */
-
- static char e_shit[6];
- static char *descriptor = "bKMG";
-
- char *numdisp (long number)
- {
- int i = 0;
- char tempstr[6];
- long quotient, oldq;
- int intq;
-
- oldq = 0L;
- quotient = number;
-
- while (quotient >= 1024L)
- {
- oldq = quotient;
- quotient = oldq / 1024L;
- i++;
- }
-
- intq = (int) quotient;
-
- /*
- * If more than 999 but less than 1024, it's a big fraction of
- * the next power of 1024. Get top two significant digits
- * (so 1023 would come out .99K, for example)
- */
-
-
- if (intq > 999)
- {
- intq = (intq * 25) / 256; /* 100/1024 */
- (void) sprintf (e_shit, ".%2d%c", intq, descriptor[++i]);
- }
- /*
- * If less than 10 and not small units, then get some decimal
- * places (e.g. 1.2M)
- */
-
- else if ((intq < 10) && (i != 0))
- {
- intq = (int) ((oldq * 5L) / 512L); /* 10/1024 */
- (void) sprintf (tempstr, "%02d", intq);
- (void) sprintf (e_shit, "%c.%c%c", tempstr[0], tempstr[1], descriptor[i]);
- }
- /*
- * Simple case. Just do it.
- */
-
- else (void) sprintf (e_shit, "%3d%c", intq, descriptor[i]);
-
- return (e_shit);
- }
-
-