/*--------------------------------------------------------------------------*/ /* */ /* */ /* ------------ Bit-Bucket Software, Co. */ /* \ 10001101 / Writers and Distributors of */ /* \ 011110 / Freely Available Software. */ /* \ 1011 / */ /* ------ */ /* */ /* (C) Copyright 1987-90, 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.240. */ /* */ /* 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:132/491, 1:141/491 */ /* P.O. Box 460398 AlterNet 7:491/0 */ /* Aurora, CO 80046 BBS-Net 86:2030/1 */ /* Internet f491.n132.z1.fidonet.org */ /* */ /* Please feel free to contact us at any time to share your comments about */ /* our software and/or licensing policies. */ /* */ /*--------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #ifdef __TOS__ #include #else #include #include #include #include #endif #ifndef LATTICE #include #endif #ifdef LATTICE #undef min #else #include #endif #include "bink.h" #include "msgs.h" #include "sbuf.h" #include "com.h" #include "vfossil.h" #include "sched.h" #include "keybd.h" #include "zmodem.h" #include "session.h" #include "nodeproc.h" /* * Data (used to be in data.c but it is only ever used in here!) */ static struct FILEINFO dta_str = { 0 }; static char next_one[64]; static ADDR next_addr; /* Next address to call */ /*--------------------------------------------------------------------------*/ /* */ /* (C) Copyright 1990, Holger Schurig */ /* */ /* This module was written by Holger Schurig */ /* */ /* Zoomed Outbound Window */ /* */ /* Minor modifications for Atari ST by Steven Green */ /*--------------------------------------------------------------------------*/ static void zoom_window (REGIONP zoomwin, MAILP p) { int i,n; long l; char out_str[50]; char flagstr[7]; /* clear the inside of zoomed outbound */ zoomwin->sr0++; zoomwin->sr1--; zoomwin->sc0++; zoomwin->sc1--; sb_fillc (zoomwin, ' '); zoomwin->sr0--; zoomwin->sr1++; zoomwin->sc0--; zoomwin->sc1++; /* give it a header */ sb_move (zoomwin, 1, 2); sb_puts (zoomwin,"Node Domain Files Bytes Age Calls Bad Status Errors"); for(i = 2; i < (zoomwin->r1 - zoomwin->r0); i++) { if (p == NULL) break; sb_move (zoomwin, i, 2); sprintf (out_str, "%u:%u/%u", p->mail_addr.Zone, p->mail_addr.Net, p->mail_addr.Node); if(p->mail_addr.Point) sprintf(&out_str[strlen(out_str)], ".%u", p->mail_addr.Point); sb_puts (zoomwin, (unsigned char *) out_str); if (p->mail_addr.Domain != NULL) { sb_move (zoomwin, i, 18); sprintf (out_str, "%-15s", p->mail_addr.Domain); sb_puts (zoomwin, fancy_str(out_str)); } sb_move (zoomwin, i, 34); n = 0; if ( p->mailtypes & MAIL_HOLD ) flagstr[n++] = 'H'; if ( p->mailtypes & MAIL_NORMAL ) flagstr[n++] = 'N'; if ( p->mailtypes & MAIL_CRASH ) flagstr[n++] = 'C'; if ( p->mailtypes & MAIL_DIRECT ) flagstr[n++] = 'D'; if ( p->mailtypes & MAIL_REQUEST ) flagstr[n++] = 'R'; if (!(p->mailtypes & MAIL_WILLGO )) flagstr[n++] = '-'; flagstr[n] = '\0'; l = ((long) time (NULL)) - (p->oldest); n = (int) (l / 86400L); sprintf (out_str, "%-3u %7lu %3d %5u %3u %6s", p->files, p->size, (n > 999) ? 999 : n, p->calls, p->costcalls, flagstr); sb_puts (zoomwin, out_str); sb_move (zoomwin, i, 67); out_str[0] = '\0'; if (p->mailtypes & MAIL_UNKNOWN) sprintf (out_str, "Unknwn"); else if (p->mailtypes & MAIL_TOOBAD) sprintf (out_str, "NoConn"); else if (p->mailtypes & MAIL_TRIED) sprintf (out_str, "Tried"); sb_puts (zoomwin, out_str); p = p->next; } sb_show (); } static void extended_dodir(char *domain, int zone, REGIONP zoomwin) { MAILP p; ADDR tmp; int i, j; #ifdef ATARIST struct FILEINFO dta; #else struct find_t dta; #endif struct tm dt; time_t unixdt; struct stat statbuf; #ifdef IOS int oat; int opt,oft,ort; #endif int out, flo, req, bad; char *e1, *e2, *e3; FILE *fp; char fname[80]; char *fnameptr; tmp.Zone = zone; tmp.Net = tmp.Node = tmp.Point = 0; tmp.Domain = domain; (void) sprintf (next_one, "%s*.*", HoldAreaNameMunge(&tmp)); #ifdef DEBUG status_line(">extended_dodir(%s %d) => %s", domain ? domain : "", zone, next_one); #endif #ifdef ATARIST j = dfind(&dta, next_one, 0); for (; !j; j = dnext (&dta)) #else j = _dos_findfirst (next_one, _A_ARCH | _A_NORMAL, &dta); for (; !j; j = _dos_findnext (&dta)) #endif { e1 = strchr(dta.name, '.'); if(e1 != NULL) { e1 = e1+1; e2 = e1+1; e3 = e2+1; out = flo = req = bad = 0; #ifdef IOS oat = 0; opt = oft = ort = 0; if ( (*e2 == 'A') && (*e3 == 'T')) oat++; if ( (*e2 == 'P') && (*e3 == 'T')) opt++; if ( (*e2 == 'F') && (*e3 == 'T')) oft++; if ( (*e2 == 'R') && (*e3 == 'T')) ort++; #endif if ( (*e2 == 'U') && (*e3 == 'T')) out++; if ( (*e2 == 'L') && (*e3 == 'O')) flo++; if ((*e1 == 'R') && (*e2 == 'E') && (*e3 == 'Q')) req++; if ((*e1 == '$') && (*e2 == '$') ) bad++; #ifdef IOS if (out || flo || req || bad || oat || opt || oft || ort) #else if (out || flo || req || bad) #endif { /* Decode the address */ #ifdef IOS if(oat || opt || oft || ort || (bad && iosmode)) getaddress(dta.name, &tmp.Net, &tmp.Node, &tmp.Point); else #endif if(get2daddress(dta.name, &tmp) == FALSE) continue; /* Ignore invalid addresses */ /* Display where we're at */ { if (fullscreen) { char s[40]; sprintf(s, "%-30s", Pretty_Addr_Str(&tmp)); if(zoomwin) { sb_move(zoomwin, 2, 2); sb_puts(zoomwin, s); } else { sb_move(holdwin, 4, 2); sb_puts(holdwin, s); } sb_show(); } } /* Adresse suchen */ p = find_mail (&tmp); if (p == NULL) continue; } /* * If its not a $$ file * Find out more about it! */ #ifdef IOS #ifdef NEW if (out || flo || req || oat || opt || oft || ort) #else if (out || flo || req || oat) #endif #else if (out || flo || req) #endif { /* Filedatum setzen */ #ifdef ATARIST dt.tm_year = (int)(((dta.time >> 9) & 0x7f) + 80); dt.tm_mon = (int)(((dta.time >> 5) & 0xf) - 1); /* 0..11 */ dt.tm_mday = (int)(dta.time & 0x1f); /* 1..31 */ #else dt.tm_year = (dta.wr_date >> 9) + 80; dt.tm_mon = ((dta.wr_date >> 5) & 0xf) - 1; /* 0..11 */ dt.tm_mday = dta.wr_date &0x1f; /* 1..31 */ #endif dt.tm_hour = dt.tm_min = dt.tm_sec = 0; #if defined(__TURBOC__) && !defined(__TOS__) /* JCE 09.10.90 */ unixdt = time (&dt); #else unixdt = mktime (&dt); #endif p->oldest = min(unixdt, p->oldest); } /* NOT flow files */ #ifdef IOS if(out || req || oat || opt || ort) #else if (out || req) #endif { /* Filel„nge/Fileanzahl addieren */ (p->files)++; (p->size) += dta.size; } /* Flow files */ #ifdef IOS if(flo || oft) #else if(flo) #endif { /* indirekte Filel„nge/Fileanzahl addieren */ ; sprintf (fname, "%s%s", HoldAreaNameMunge (&(p->mail_addr)), dta.name); fp = fopen (fname, "r"); /* was "rb" */ if (fp != NULL) { while (!feof (fp)) { fname[0] = 0; if (fgets (fname, 79, fp) != NULL) { fnameptr = fname; for (i = 0; fnameptr[i]; i++) { if (fnameptr[i] <= ' ') { fnameptr[i] = '\0'; } } /* SWG: 22Aug91 Prevent error with ~:\ */ if( !fnameptr[0] || (fnameptr[0] == ';') || (fnameptr[0] == '~')) continue; if ((fnameptr[0] == TRUNC_AFTER) || (fnameptr[0] == SHOW_DELETE_AFTER)) { fnameptr++; } if (stat (fnameptr, &statbuf) == 0) { p->size += statbuf.st_size; p->files++; } /* bei MO?/WE? etc indirektes Filedatum ermitteln */ ; } } /* WHILE */ fclose(fp); } /* ?LO-File found */ } if (bad) { /* BadCalls hochz„hlen */ ; sprintf (fname, "%s%s", HoldAreaNameMunge (&(p->mail_addr)), dta.name); i = open (fname, O_BINARY|O_RDONLY); (void) read (i, &(p->calls), sizeof (p->calls)); (void) close (i); p->costcalls += *e3-'0'; p->calls += *e3-'0'; } } } } static void extended_xmit_reset (REGIONP zoomwin) { ADDR tmp; MAILP p; char *domain; int k, zone; p = mail_top; while (p != NULL) { p->calls = 0; p->costcalls = 0; p->files = 0; p->size = 0L; p->oldest = (long) time (NULL); p = p->next; } k = 0; domain = domain_name[0]; do { ADDRESS *ad; int count, count1; int ourzone[ALIAS_CNT]; /* record of our own zones */ int zonecnt; /* * Do our own zones first */ ad = alias; count = num_addrs; zonecnt = 0; while(count--) { if(!domain || (ad->ad.Domain == domain)) { /* Check we havnt already done it */ count1 = zonecnt; while(count1--) { if(ourzone[count1] == ad->ad.Zone) break; } if(count1 < 0) { extended_dodir(domain, ad->ad.Zone, zoomwin); ourzone[zonecnt++] = ad->ad.Zone; } } ad++; } if(!no_zones) { do { tmp.Zone = -1; tmp.Domain = domain; tmp.Net = tmp.Node = tmp.Point = 0; zone = nodefind(&tmp, 0); if(zone > 0) { /* Check we havnt already done it */ count = zonecnt; while(count--) { if(ourzone[count] == zone) break; } if(count < 0) extended_dodir(domain, zone, zoomwin); } } while(zone > 0); } domain = domain_name[++k]; } while (domain != NULL); } int Overlay_Do_Zoom (SAVEP rp, int x) { REGIONP zoomwin; MAILP p; long t_idle; int i,c; int height; /* is there something in the outbound ? */ if (mail_top == NULL) { status_line (msgtxt[M_NOTHING_IN_OUTBOUND_STATUS]); return (0); } /* is there a window */ if (rp != NULL) { zoomwin = rp->region; /* draw a box */ sb_fill (zoomwin, ' ', colors.hold); sb_box (zoomwin, boxtype, (colors.borders ? colors.borders : colors.hold)); /* give it a title */ sb_move (zoomwin, 0, 1); if (colors.headers) sb_wa(zoomwin, colors.headers, 30); sb_puts (zoomwin, " Zoomed Pending Outbound Mail "); /* do we need info ? */ if (!mail_top->files) { sb_move (zoomwin, 1, 2); sb_puts (zoomwin, "Please wait ..."); sb_show (); extended_xmit_reset (zoomwin); } p = mail_top; zoom_window (zoomwin, p); height = zoomwin->r1 - zoomwin->r0; t_idle = timerset(6000); while (!timeup (t_idle) && (PEEKBYTE () == -1)) { if (KEYPRESS ()) { t_idle = timerset(3000); c = (int) FOSSIL_CHAR (); if (c == PGUP) { for (i = 2; i < height; i++) { if (p->prev != NULL) p = p->prev; } } else if (c == PGDN) { for (i = 2; i < height; i++) { if (p->next != NULL) p = p->next; } } else if (c == UPAR) { if (p->prev != NULL) { p = p->prev; } } else if (c == DNAR) { if (p->next != NULL) { p = p->next; } } else if (c == HOME) { p = mail_top; } else if (c == END) { while (p->next != NULL) p = p->next; for (i = 2; i < height; i++) { if (p->prev != NULL) p = p->prev; } } else /* ALT-Z, Space, ESCape or Return terminates */ if (c == ALTZ) return (x); c &= 0x00ff; if ((c == 0x20) || (c == 0x1b) || (c == 0x0d)) return (x); if (!KEYPRESS ()) zoom_window (zoomwin, p); } } } /* return value is never checked, just use x so lint and -w3 don't get mad */ return (x); } /* * Find mail for an address in the MAILP list */ MAILP find_mail( ADDR *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 == alias[0].ad.Domain) && (address->Domain == NULL)))) break; p = p->next; } return (p); } /* * Fill in data into MAILP node * * uses dta_str, which is the DTA area for a recently found file * * returns 1 for an error or node already exists in list */ static int xmit_install (MAILP p, int zone, char *domain) { MAILP p1, p2; int rettype; ADDR tmp; #ifdef IOS char *s; #endif #ifdef IBMC char tnet[5], tnode[5]; #endif /* Interpret the net/node from the filename */ tmp.Zone = zone; /* Set up defaults */ tmp.Domain = domain; #ifdef IOS s = strchr(dta_str.name, '.'); if(s && (s[2] != 'U') && (s[3] == 'T')) getaddress(dta_str.name, &tmp.Net, &tmp.Node, &tmp.Point); else #endif if(get2daddress(dta_str.name, &tmp) == FALSE) return 1; p2 = find_mail (&tmp); if (p2 == NULL) { /* We didn't find it in what we have already */ p1 = p; p1->mail_addr.Zone = tmp.Zone; p1->mail_addr.Net = tmp.Net; p1->mail_addr.Node = tmp.Node; p1->mail_addr.Point = tmp.Point; p1->mail_addr.Domain = tmp.Domain; rettype = 0; } else { /* We found it, so we have to make sure the higher level routine knows */ p1 = p2; rettype = 1; } 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; } #ifdef IOS if(dta_str.name[10] == 'R') p1->mailtypes |= MAIL_REQUEST; #endif /* SWG: 11Jul91 : Speed up reading */ /* Avoid nodelist check if already processed this address! */ if(p2) { if(p1->mailtypes & MAIL_UNKNOWN) return rettype; } else { if (!nodefind (&(p1->mail_addr), 0)) { p1->mailtypes |= MAIL_UNKNOWN; return (rettype); } p1->realcost = newnodedes.RealCost; p1->nodeflags = newnodedes.NodeFlags; } /* REQUEST 03.08.1990 */ /* Don't call for "HOLD" stuff. */ if (dta_str.name[9] == 'H') { return (rettype); } /* Don't call for "REQ" stuff if not allowed */ #ifdef IOS if (!requests_ok && ((dta_str.name[9] == 'R') || (dta_str.name[10] == 'R'))) #else if ((dta_str.name[9] == 'R') && (!requests_ok)) #endif { return (rettype); } /* If there's no event, set mail to 'go' */ if (cur_event < 0) { p1->mailtypes |= MAIL_WILLGO; return (rettype); } /* if mail is direct, set mail to 'go' */ if (dta_str.name[9] == 'D') { p1->mailtypes |= MAIL_WILLGO; return (rettype); } /* REQUEST 22.08.1990 */ /* If it is not supposed to be outbound requests, go on */ if ((e_ptrs[cur_event]->behavior & MAT_NOOUTREQ) && #ifdef IOS ((dta_str.name[10] == 'R') || (dta_str.name[9] == 'R'))) #else (dta_str.name[9] == 'R')) #endif { 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); } /* ** Check for costs. If UseCallSlots is set, then take them instead */ if (usecallslots) { /* ** check if slot exits, don't call for CRASH mail waiting ** for other nodes if slot is not found */ s = strchr (e_ptrs[cur_event]->call_slot, (int)p1->realcost); if (!s || !*s) { /* ** no slot for node!! ** Did we have slots for this event ? ** Then don't call if mail is crash **/ if (e_ptrs[cur_event]->call_slot[0]) { if (dta_str.name[9] != 'C') { return (rettype); } else { if (!(e_ptrs[cur_event]->behavior & MAT_CM)) return (rettype); } } } } else { /* 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) p1->realcost > e_ptrs[cur_event]->node_cost) { return (rettype); } } else { if ((int) p1->realcost < -e_ptrs[cur_event]->node_cost) { return (rettype); } } } } /* Is this a non-mail window event? */ #ifndef ATARIST if (newnodelist && (!(e_ptrs[cur_event]->behavior & MAT_NOMAIL24))) #else if (!(e_ptrs[cur_event]->behavior & MAT_NOMAIL24)) #endif { /* If this guy can't handle crash, get out and try again */ if (!(p1->nodeflags & B_CM) && (!s || !*s)) { return (rettype); } } /* Is this a receive only event? */ if (e_ptrs[cur_event]->behavior & MAT_NOOUT) { return (rettype); } /* Is this a non-CM event? */ #ifndef ATARIST if (newnodelist && (e_ptrs[cur_event]->behavior & MAT_NOCM) && (p1->nodeflags & B_CM)) #else if((e_ptrs[cur_event]->behavior & MAT_NOCM) && (p1->nodeflags & B_CM)) #endif { return (rettype); } /* See if we spent too much calling him already */ if (bad_call (&(p1->mail_addr), BAD_STATUS)) { p1->mailtypes |= MAIL_TOOBAD; return (rettype); } p1->mailtypes |= MAIL_WILLGO; return (rettype); } void xmit_window( MAILP p1 ) { MAILP p; int i; char node_str[16]; /* for zz:nnnnn:nnnnn */ char domain_str[9]; /* for the domain or files/size/age */ char flag_str[7]; /* for the flags */ char size_str[6]; /* for Bytes, kBytes or MBytes */ char *res_str; int n; /* counter */ char j1[40]; if (!fullscreen) return; /* * SWG: Default to mail_top and set next_mail */ if(p1 == NULL) p1 = mail_top; #if 0 if(next_mail == NULL) next_mail = p1; #endif p = p1; sb_fillc (holdwin, ' '); if (p == NULL) { sb_move (holdwin, 3, 5); sb_puts (holdwin, (unsigned char *) msgtxt[M_NOTHING_IN_OUTBOUND]); return; } if (niceoutbound) { sb_move (holdwin, 1, 1); sb_puts (holdwin, "Node Files Size Age Status"); } else { sb_move (holdwin, 1, 2); sb_puts (holdwin, (unsigned char *) msgtxt[M_OUTBOUND_HEADER]); } for (i = 2; i < 6; i++) { if (p == NULL) break; sb_move (holdwin, i, 2); /* create formatted address */ sprintf (node_str, "%u:%u/%u", p->mail_addr.Zone, p->mail_addr.Net, p->mail_addr.Node); if(p->mail_addr.Point) sprintf(&node_str[strlen(node_str)], ".%u", p->mail_addr.Point); /* create formatted flags */ if (p->mailtypes & MAIL_UNKNOWN) sprintf (flag_str, "Unknwn"); else if (p->mailtypes & MAIL_TOOBAD) sprintf (flag_str, "NoConn"); else if (p->mailtypes & MAIL_TRIED) sprintf (flag_str, "Tried "); else { n = 0; if ( p->mailtypes & MAIL_HOLD ) flag_str[n++] = 'H'; if ( p->mailtypes & MAIL_NORMAL ) flag_str[n++] = 'N'; if ( p->mailtypes & MAIL_CRASH ) flag_str[n++] = 'C'; if ( p->mailtypes & MAIL_DIRECT ) flag_str[n++] = 'D'; if ( p->mailtypes & MAIL_REQUEST ) flag_str[n++] = 'R'; if (!(p->mailtypes & MAIL_WILLGO )) flag_str[n++] = '-'; flag_str[n] = '\0'; } if (niceoutbound) { /* create extra info */ if (p->size > 10238976L) sprintf (size_str, "%4ulM", (p->size+1048575L)/1048576L); else if (p->size > 9999) sprintf (size_str, "%4luk", (p->size+1023)/1024); else sprintf (size_str, "%4lu ", p->size); n = (int) ( ((long)time(NULL) - p->oldest) / 86400L ); sb_move (holdwin, i, 1); sprintf (j1, "%-12.12s%3u%6s%3u%7s", node_str, p->files, size_str, (n > 999) ? 999 : n, flag_str); } else { /* create formatted domain if any */ if(p->mail_addr.Domain == NULL) strcpy (domain_str, "FidoNet"); else { strncpy (domain_str, p->mail_addr.Domain, 8); res_str = strchr (domain_str, '.'); if (res_str != NULL) *res_str = '\0'; domain_str[8] = '\0'; } sb_move (holdwin, i, 2); sprintf (j1, "%-15s%-8s%6s", node_str, domain_str, flag_str); } sb_puts (holdwin, (unsigned char *) j1); p = p->next; } sb_show (); } /* * Sort the outbound mail */ static void xmit_sort (void) { MAILP p, p1, p2; do_ready ("Sorting"); p1 = mail_top; while (p1 != NULL) { p2 = p1->next; while (p2 != NULL) { if( (p2->mail_addr.Zone < p1->mail_addr.Zone ) || ( (p2->mail_addr.Zone == p1->mail_addr.Zone ) && ( (p2->mail_addr.Net < p1->mail_addr.Net ) || ( (p2->mail_addr.Net == p1->mail_addr.Net ) && ( (p2->mail_addr.Node < p1->mail_addr.Node ) || ( (p2->mail_addr.Node == p1->mail_addr.Node ) && (p2->mail_addr.Point < p1->mail_addr.Point) )))))) { /* p2 ausklinken */ p2->prev->next = p2->next; if (p2->next != NULL) p2->next->prev = p2->prev; /* p2 vor p1 einklinken */ p2->prev = p1->prev; if (p2->prev != NULL) p2->prev->next = p2; p2->next = p1; p1->prev = p2; /* korrigieren */ if (p1 == mail_top) mail_top = p2; p = p2; p2 = p1; p1 = p; } p2 = p2->next; } p1 = p1->next; } 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; } } } /* * Read mail from a directory */ static void do_dir(char *domain, int zone, MAILP *pp) { ADDR tmp; MAILP p = *pp; #if (!defined(OS_2) && !defined(LATTICE)) int j; #endif char *holdpath; #ifdef NEW struct stat buffer; #endif #ifdef NEW if(fullscreen) { char s[16]; sb_fillc (holdwin, ' '); if(domain) { sb_move(holdwin, 2, 4); sb_puts(holdwin, "Domain: "); sb_puts(holdwin, domain); } sb_move(holdwin, 3, 6); sb_puts(holdwin, "Zone: "); sprintf(s, "%d", zone); sb_puts(holdwin, s); sb_show(); } #endif tmp.Zone = zone; tmp.Net = tmp.Node = tmp.Point = 0; tmp.Domain = domain; holdpath = HoldAreaNameMunge(&tmp); #ifdef NEW /* Check if folder exists and create if neccessary */ strcpy(next_one, holdpath); next_one[strlen(next_one) -1] = 0; if(stat(next_one, &buffer)) { if(mkdir(next_one) == 0) status_line(msgtxt[M_CREATED_DIR], next_one); else { status_line(msgtxt[M_BAD_DIR], next_one); status_line(msgtxt[M_NO_CREATE_DIR]); return; } } #endif sprintf (next_one, "%s*.*", holdpath); #if (!defined(OS_2) && !defined(LATTICE)) j = 0; #endif #if defined(OS_2) if(!dir_findfirsta(next_one, _A_NORMAL, &dta_str)) #else if(!dfind(&dta_str, next_one, 0)) #endif do { char *ext = strchr(dta_str.name, '.'); if(ext) { ext++; #ifdef IOS if( ext[0] && ext[1] && ext[2] && (( strchr("APFRU", ext[1]) && (ext[2] == 'T') ) || ( (ext[1] == 'L') && (ext[2] == 'O') ) || ( (ext[0] == 'R') && (ext[1] == 'E') && (ext[2] == 'Q') ) ) ) #else if( ( (ext[1] == 'U') && (ext[2] == 'T') ) || ( (ext[1] == 'L') && (ext[2] == 'O') ) || ( (ext[0] == 'R') && (ext[1] == 'E') && (ext[2] == 'Q') ) ) #endif { /* We found a name, remember it */ 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, zone, domain)) { /* No good */ if (p->prev != NULL) { p = p->prev; free (p->next); p->next = NULL; } else { free (p); p = mail_top = NULL; } } } } #if (!defined(OS_2) && !defined(LATTICE)) ++j; #endif } #if defined(OS_2) while(!dir_findnexta(&dta_str)); #elif defined(LATTICE) while(!dnext(&dta_str)); /* got one */ #else while(!dfind(&dta_str, next_one, j)); #endif *pp = p; } /* * Reset the outbound mail structures */ void xmit_reset( void ) { MAILP p; int k, zone; char *domain; ADDR tmp; readhold_ctr = readhold_time; do_ready ("Reading"); /* First get rid of all the old junk */ p = mail_top; if (p != NULL) { while (p->next != NULL) /* Get to end of list */ p = p->next; while (p->prev != NULL) /* Work back through list freeing memory */ { p = p->prev; free (p->next); } if (p != NULL) free (p); } p = mail_top = NULL; k = 0; domain = domain_name[0]; /* For each Domain */ do { /* For each Zone */ ADDRESS *ad; int count, count1; int ourzone[ALIAS_CNT]; /* record of our own zones */ int zonecnt; lock_nodelist(TRUE); /* Keep nodelist file open */ /* * Do our own zones first */ ad = alias; count = num_addrs; zonecnt = 0; while(count--) { if(!domain || (ad->ad.Domain == domain)) { /* Check we havnt already done it */ count1 = zonecnt; while(count1--) { if(ourzone[count1] == ad->ad.Zone) break; } if(count1 < 0) { do_dir(domain, ad->ad.Zone, &p); ourzone[zonecnt++] = ad->ad.Zone; } } ad++; } if(!no_zones) { do { tmp.Zone = -1; tmp.Domain = domain; tmp.Net = tmp.Node = tmp.Point = 0; zone = nodefind(&tmp, 0); if(zone > 0) { /* Check we havnt already done it */ count = zonecnt; while(count--) { if(ourzone[count] == zone) break; } if(count < 0) do_dir(domain, zone, &p); } } while(zone > 0); } lock_nodelist(FALSE); /* Unlock nodelist */ domain = domain_name[++k]; } while (domain != NULL); next_mail = NULL; xmit_sort (); if (niceoutbound) extended_xmit_reset (NULL); xmit_window (mail_top); do_ready (msgtxt[M_READY_WAITING]); } int xmit_next( ADDR *xaddr ) { /* Set up the proper pointer */ if ((next_mail == NULL) || (next_mail->next == NULL)) 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), BAD_STATUS)) { next_mail->mailtypes |= MAIL_TOOBAD; } else { xaddr->Zone = next_mail->mail_addr.Zone; xaddr->Net = next_mail->mail_addr.Net; xaddr->Node = next_mail->mail_addr.Node; xaddr->Point = next_mail->mail_addr.Point; xaddr->Domain = next_mail->mail_addr.Domain; xmit_window (next_mail); return (1); } } next_mail = next_mail->next; } /* Read the disk again since we reached the end of the list */ #ifdef OS_2 xmit_reset (); #endif next_mail = mail_top; /* Try the new list and see what happens */ 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), BAD_STATUS)) { next_mail->mailtypes |= MAIL_TOOBAD; } else { xaddr->Zone = next_mail->mail_addr.Zone; xaddr->Net = next_mail->mail_addr.Net; xaddr->Node = next_mail->mail_addr.Node; xaddr->Point = next_mail->mail_addr.Point; xaddr->Domain = next_mail->mail_addr.Domain; xmit_window (next_mail); return (1); } } next_mail = next_mail->next; } /* Oh well, we tried */ xmit_window (mail_top); return (0); } /* * Handle Bad call files (*.$$?) * * baddr : Address * rwd : a flag: * 0 = BAD_STATUS = Get status for address (0=OK to call, 1=made too many calls) * 1 = BAD_CARRIER = Mark bad call with carrier * 2 = BAD_NOCARRIER = Mark bad call without carrier * 3 = BAD_STOPCALL = Mark as uncallable * -ve = BAD_REMOVE = Remove old bad files */ int bad_call( ADDR *baddr, int rwd ) { int res; int i, j; struct FILEINFO bad_dta; FILE *bad_wazoo; char *p; char *HoldName; char fname[80]; char fname1[80]; #ifdef DEBUG status_line(">update_$$?(%s,%d)", Pretty_Addr_Str(baddr), rwd); #endif HoldName = HoldAreaNameMunge(baddr); #ifdef IOS if(iosmode) sprintf (fname, "%s%s.$$?", HoldName, Addr36(baddr)); else #endif 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 */ #ifdef LATTICE while( i ? !dnext(&bad_dta) : !dfind(&bad_dta, fname, 0)) #else while (!dfind (&bad_dta, fname, i)) /* as long as we match */ #endif { 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 == 3) /* Mark as uncallable */ fname1[j] = '9'; if (res == -1) /* Did we have a file? */ { /* No, make one. */ if (rwd == BAD_NOCARRIER) /* No carrier */ res = open (fname, O_CREAT|O_WRONLY|O_BINARY, DEFAULT_MODE); else /* With carrier */ res = open (fname1, O_CREAT|O_WRONLY|O_BINARY, DEFAULT_MODE); i = rwd - 1; /* zero-based count */ write (res, &i, sizeof (int)); /* write it out */ close (res); /* close the file */ } else { /* There was a file */ /* * 2 = Unsuccessful, No carrier. Update contents of the file. */ if (rwd == BAD_NOCARRIER) { 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, DEFAULT_MODE); (void) write (i, (char *) &res, sizeof (int)); (void) close (i); } /* * 1 or 3 = Unsuccessful, Carrier. Update file name to reflect the * failure. */ else { (void) rename (fname, fname1); } } } else if (rwd == BAD_STATUS) { /* * 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); #ifdef IOS if(iosmode) sprintf (fname, "%s%s.Z", HoldName, Addr36(baddr)); else #endif sprintf (fname, "%s%s.Z", HoldName, Hex_Addr_Str (baddr)); if (dexists (fname)) { if ((bad_wazoo = fopen (fname, read_ascii)) == NULL) { (void) got_error (msgtxt[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, CurrentNetFiles); (void) strcat (fname1, p); (void) unlink (fname1); } (void) fclose (bad_wazoo); } (void) unlink (fname); } } return (0); } /* * Kill all BAD $$ files * * Return number of files killed */ static int kill_badzone(ADDR *ad) { int flag = 0; char *folder = HoldAreaNameMunge(ad); sprintf (next_one, "%s*.$$?", folder); #ifdef DEBUG status_line(">Deleting %s", next_one); #endif if(!dfind(&dta_str, next_one, 0)) { do { char s[FMSIZE]; sprintf(s, "%s%s", folder, dta_str.name); #ifdef DEBUG status_line(">Killing %s", s); #endif unlink(s); flag++; } while(!dnext(&dta_str)); } return flag; } void kill_bad( void ) { char *domain = domain_name[0]; int k = 0; int counter = 0; status_line(msgtxt[M_KILLING]); /* for each domain */ do { /* for each zone */ ADDRESS *ad; int count, count1; int ourzone[ALIAS_CNT]; /* record of our own zones */ int zonecnt; lock_nodelist(TRUE); /* keep nodelist file open */ /* * do our own zones first */ ad = alias; count = num_addrs; zonecnt = 0; while(count--) { if(!domain || (ad->ad.Domain == domain)) { /* check we havnt already done it */ count1 = zonecnt; while(count1--) { if(ourzone[count1] == ad->ad.Zone) break; } if(count1 < 0) { counter += kill_badzone(&ad->ad); ourzone[zonecnt++] = ad->ad.Zone; } } ad++; } if(!no_zones) { int zone; do { ADDR tmp; tmp.Zone = -1; tmp.Domain = domain; tmp.Net = tmp.Node = tmp.Point = 0; zone = nodefind(&tmp, 0); if(zone > 0) { /* check we havnt already done it */ count = zonecnt; while(count--) { if(ourzone[count] == zone) break; } if(count < 0) { tmp.Zone = zone; counter += kill_badzone(&tmp); } } } while(zone > 0); } lock_nodelist(FALSE); /* unlock nodelist */ domain = domain_name[++k]; } while (domain != NULL); #ifdef DEBUG status_line(">%d $$ files deleted", counter); #endif if(counter) set_up_outbound(); } void set_up_outbound( void ) { MAILP mp; xmit_reset (); /* and remember where we left off */ if (hist.next_net != 0) { next_addr.Zone = hist.next_zone; next_addr.Net = hist.next_net; next_addr.Node = hist.next_node; next_addr.Point = hist.next_point; if(hist.next_Domain[0]) next_addr.Domain = find_domain(hist.next_Domain); else 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 (mail_top); } } else { next_addr.Zone = next_addr.Net = next_addr.Node = next_addr.Point = 0; next_addr.Domain = NULL; xmit_window (mail_top); } } /* * functions */ static void minute (void); void minute () { if (! (--reinit_ctr)) { reinit_ctr = reinit_time; set_prior (4); mdm_init (modem_init); set_prior (2); screen_blank = 1; if (fullscreen) sb_show (); } if (! (--readhold_ctr)) { readhold_ctr = readhold_time; set_up_outbound (); more_mail = 1; } put_up_time (); list_next_event (); } /* * Pick a time between now and x seconds */ 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 ((long)i * 100)); } /*------------------------------------------------------------------- * The main unattended mailer function */ int unattended( void ) { MAILP mp; int i, m, j, tmp; long t, t1; /* used for the timeouts */ int done = 1; /* if we exit with this, get * out of BT */ FILE *tfile; char jbuf[60]; un_attended = 1; #if 0 clear_statusline (); #endif comm_bits = BITS_8; parity = NO_PARITY; stop_bits = STOP_1; set_prior(4); /* Always High */ MDM_ENABLE (lock_baud && (btypes[baud].rate_value >= lock_baud) ? max_baud.rate_mask : btypes[baud].rate_mask); set_prior(2); /* Regular */ if (fullscreen) { screen_clear (); sb_dirty (); } opening_banner (); if (fullscreen) { mailer_banner (); } if ((tfile = fopen ("BINKLEY.BAN", read_binary)) != NULL) { (void) fread (BBSwelcome, 1, 1000, tfile); (void) fclose (tfile); } else { BBSwelcome[0] = '\0'; } /* Initialize the random number generator */ i = (int) time (NULL); srand ((unsigned int) i); #ifdef ATARIST status_line ("+%s, %s [%s], %s %ld", msgtxt[M_BEGIN], xfer_id, compile_date, msgtxt[M_FREEMEM], Malloc(-1L)); #else status_line ("+%s, %s", msgtxt[M_BEGIN], xfer_id); #endif /*set_xy ("");*/ set_prior(4); /* Always High */ XON_DISABLE (); set_prior(2); /* Regular */ /* Turn off forced events */ if (noforce) { find_event (); noforce = 0; } if (redo_dynam) { for (i = 0; i < num_events; i++) { e_ptrs[i]->behavior &= ~MAT_SKIP; } redo_dynam = 0; } /* * See if we should exit before initializing the modem (and therefore * possibly letting a call sneak through) */ find_event (); do_ready (msgtxt[M_READY_INIT]); /* Make sure we have all necessary parameters and that the nodelist * index gets read in. If not, then we must exit right now. */ next_addr = alias[0].ad; /* Does our node exist (or our boss if we're a point */ next_addr.Point = 0; if(!net_params || !nodefind(&next_addr, 0)) if(alias[0].ad.Net != -1U) { status_line (msgtxt[M_MISCONFIGURED]); errl_exit (254); } /* Set up outbound mail */ list_next_event (); set_up_outbound (); if (!CARRIER) { set_prior(4); /* Always High */ mdm_init (modem_init); /* Reinitialize the modem */ set_prior(2); /* Regular */ } t1 = timerset ((long)next_minute ()); /* Set a 1 minute timer */ top_of_mail: un_attended = 1; i = 0; m = 1; /* As long as we don't press a key */ bad_char: more_mail = 1; while (!(KEYPRESS () || ctrlc_ctr)) { find_event (); /* Show that we are ready */ if (m) { if (fullscreen) { do_ready (msgtxt[M_READY_WAITING]); list_next_event (); } else { status_line (msgtxt[M_EVENT_WAITING], cur_event + 1); } t1 = timerset ((long)next_minute ()); /* Set a 1 minute timer */ } if (timeup (t1)) { minute (); t1 = timerset ((long)next_minute ()); /* Set a 1 minute timer */ } m = 0; if (cur_event >= 0) { i = (e_ptrs[cur_event]->behavior & MAT_OUTONLY); t = random_time (e_ptrs[cur_event]->wait_time); } else { i = 1; t = random_time (5); } /* variable 'i' will be TRUE if we are either manually dialing out * or if we are in an event where we do not want incoming stuff. */ while ((!timeup (t)) && (!KEYPRESS ()) && (m == 0) && !ctrlc_ctr) { find_event (); time_release (); if (timeup (t1)) { minute (); t1 = timerset ((long)next_minute ()); /* Set a 1 minute timer */ } /* If we want inbound, see if there is any. If we send anything, clean up afterwards ... */ if (!i) { m = handle_inbound_mail (); if (m) set_up_outbound (); } } if ((m) && (fullscreen)) { do_ready (msgtxt[M_READY_WAITING]); list_next_event (); } immed_call: find_event (); /* If we are not in an event, loop again */ if (cur_event < 0) { time_release (); continue; } /* If we have pressed a key, get out */ if (KEYPRESS () || ctrlc_ctr) break; /* See if we are supposed to do any mail */ if (cur_event >= 0) if (e_ptrs[cur_event]->behavior & MAT_NOOUT) { continue; } if (more_mail) { more_mail = xmit_next (&next_addr); if (more_mail) { /* save the next call in the list in case we exit */ if ((next_mail == NULL) || (next_mail->next == NULL)) mp = mail_top; else mp = next_mail->next; hist.next_zone = mp->mail_addr.Zone; hist.next_net = mp->mail_addr.Net; hist.next_node = mp->mail_addr.Node; hist.next_point = mp->mail_addr.Point; memset(hist.next_Domain, 0, sizeof(hist.next_Domain)); if(mp->mail_addr.Domain) strcpy(hist.next_Domain, mp->mail_addr.Domain); set_prior(4); /* Always High */ m = do_mail (&next_addr, 0); set_prior(2); /* Regular */ if(m == 1) /* Connected with carrier */ { if (!sent_mail) { /* We connected but the transfer didn't work */ bad_call (&next_addr, BAD_CARRIER); xmit_window (next_mail); } else { set_up_outbound(); } } else if (m == 2) /* Nothing happened */ { bad_call (&next_addr, BAD_NOCARRIER); } else if (m == -1) { status_line (msgtxt[M_INCOMING_CALL]); } } } if (!more_mail) { /* No more mail to do, was it dynamic? */ if (cur_event >= 0) if (e_ptrs[cur_event]->behavior & MAT_DYNAM) { if (!blank_on_key) screen_blank = 0; e_ptrs[cur_event]->behavior |= MAT_SKIP; status_line (":%s %s %d", msgtxt[M_END_OF], msgtxt[M_DYNAMIC_EVENT], cur_event + 1); goto top_of_mail; } } } /*----------------------------------------------------------------- * We get to here if a key is pressed * * If the code was laid out better and the labels and goto's were * converted into looping constructs this would be much easier to read. */ /* any key to unblank, SWG 24th June 1991 */ if(screen_blank && do_screen_blank) { if(KEYPRESS()) /* Clear the key */ FOSSIL_CHAR(); screen_blank = 0; /* Unblank the screen */ if(fullscreen) /* Redisplay the screen */ sb_show(); goto bad_char; } /* No key press should not exit! SWG 24th June 1991 */ if(ctrlc_ctr) { /* * Be serious, there had to be a key pressed or we wouldn't be here I * know it sounds silly, but ^C will sometimes do crap like this */ status_line (msgtxt[M_EXIT_REQUEST]); } else { /* No keypress available then continue, SWG 24th June 1991 */ if(!KEYPRESS()) goto bad_char; /* May as well be using Basic with all these goto's!!! */ i = (int) FOSSIL_CHAR (); #ifndef ATARIST if ((i & 0xff) == 0) { #endif switch (i) { case PF1: case PF2: case PF3: case PF4: case PF5: case PF6: case PF7: case PF8: case PF9: case PF10: j = (int) (((unsigned) i) >> 8); status_line (msgtxt[M_FUNCTION_KEY], (j - 0x3a) * 10); errl_exit ((j - 0x3a) * 10); break; /* ANSWER 24.05.1990 */ case ALTA: CLEAR_INBOUND (); mdm_cmd_string (ans_str, 0); /* transmit the answer */ m = handle_inbound_mail (); if (m) { /* If we sent out anything, make sure we reset stuff */ set_up_outbound (); } goto bad_char; case ALTB: screen_blank = 1; if (fullscreen) sb_show (); goto bad_char; case ALTC: tmp = hist.which_day; (void) memset (&hist, 0, sizeof (HISTORY)); hist.which_day = tmp; if (fullscreen) { do_today (); sb_show (); } goto bad_char; case ALTE: case CTRLM: /* Control M for ACS compatibility */ if (BBSreader != NULL) { vfossil_cursor (1); status_line (msgtxt[M_DISABLE_MODEM]); set_prior(4); /* Always High */ mdm_init (modem_busy); exit_DTR (); set_prior(2); /* Regular */ status_line (msgtxt[M_BEGIN_MESSAGE_READER]); vfossil_close (); b_spawn (BBSreader); vfossil_init (); if (fullscreen) { screen_clear (); sb_dirty (); opening_banner (); mailer_banner (); } status_line (msgtxt[M_END_MESSAGE_READER]); set_up_outbound (); m = 1; more_mail = 1; status_line (msgtxt[M_ENABLE_MODEM]); set_prior(4); /* Always High */ DTR_ON (); mdm_init (modem_init); set_prior(2); /* Regular */ goto top_of_mail; } else { set_xy (NULL); status_line (msgtxt[M_NO_MESSAGE_READER]); set_xy (NULL); m = 1; goto bad_char; } /* NICEOUTBOUND 09.09.1990 */ case ALTF: niceoutbound = 1-niceoutbound; if (niceoutbound) { xmit_reset (); } else { #if 0 next_mail = mail_top; #endif xmit_window (next_mail); } goto bad_char; /* Roland's flavour changer */ case CTRLC: case CTRLF: if (sb_popup (10, 10, 6, 60, Do_Change, 0)) status_line (msgtxt[M_NO_CHANGE]); else { set_up_outbound (); m = 1; more_mail = 1; } goto bad_char; case ALTG: /* ONEMORE 01.09.1990 */ if (sb_popup (10, 10, 6, 60, Do_Get, 0)) { status_line (msgtxt[M_NO_GET]); } else { set_up_outbound (); m = 1; more_mail = 1; } goto bad_char; case ALTI: /* FASTMODEM, REINIT 18.07.1990 */ mdm_hangup (); reinit_ctr = reinit_time; m = 1; goto bad_char; case ALTJ: status_line (msgtxt[M_SHELLING]); /* EXEC 18.07.1990 */ set_prior(4); mdm_init (modem_busy); exit_DTR (); set_prior(2); if (fullscreen) screen_clear (); vfossil_cursor (1); (void) cputs (msgtxt[M_TYPE_EXIT]); close_up (); change_prompt (); b_spawn (NULL); come_back (); m = 1; set_up_outbound (); set_prior(4); /* Always High */ DTR_ON (); mdm_init (modem_init); reinit_ctr = reinit_time; status_line (msgtxt[M_BINKLEY_BACK]); set_prior(2); /* Regular */ goto bad_char; case ALTK: if (sb_popup (10, 5, 4, 70, Do_Kill, 0)) { status_line (msgtxt[M_NO_KILL]); } else { set_up_outbound (); m = 1; more_mail = 1; } goto bad_char; case ALTY: next_addr = alias[0].ad; /* Poll ourself */ next_addr.Point = 0; /* Remove the point to get boss */ goto polling; /* ZOOM 27.08.1990 */ case ALTZ: if (sb_popup (1, 1, SB_ROWS-2, 78, Overlay_Do_Zoom, 0)) { } goto bad_char; case ALTM: status_line (msgtxt[M_POLL_MODE]); if (fullscreen) gotoxy (0, SB_ROWS - 2); vfossil_cursor (1); scr_printf ("\r\n"); clear_eol (); scr_printf (msgtxt[M_ENTER_NET_NODE]); m = get_number (jbuf); if (m) { m = find_address (jbuf, &next_addr); } if (fullscreen) { gotoxy (0, SB_ROWS - 1); clear_eol (); bottom_line (); vfossil_cursor (0); sb_show (); } if (m >= 1 && nodefind (&next_addr, 1)) { if (!next_addr.Zone) next_addr.Zone = found_zone; /* Warn user that it is not CM */ if ( (cur_event < 0 || (e_ptrs[cur_event]->behavior & MAT_NOCM)) && (!(newnodedes.NodeFlags & B_CM))) { int c; if (fullscreen) gotoxy (0, SB_ROWS - 2); vfossil_cursor (1); scr_printf ("\r\n"); clear_eol (); scr_printf ("WARNING: "); scr_printf(Pretty_Addr_Str(&next_addr)); scr_printf(" is not 24 Hours... poll anyway(Y/N)?"); while (!KEYPRESS ()) time_release (); c = FOSSIL_CHAR (); if (fullscreen) { gotoxy (0, SB_ROWS - 1); clear_eol (); bottom_line (); vfossil_cursor (0); sb_show (); } if(toupper(c) != 'Y') { status_line("#Poll aborted"); goto bad_char; } } polling: doing_poll = 1; if (fullscreen) { sb_move (filewin, 1, 2); sb_puts (filewin, (unsigned char *) msgtxt[M_CURRENTLY_POLLING]); sb_puts (filewin, (unsigned char *) Pretty_Addr_Str (&next_addr)); } set_prior(4); /* Always High */ if (do_mail (&next_addr, 1) == 1) { if(sent_mail) set_up_outbound(); else xmit_window (next_mail); } set_prior(2); /* Regular */ doing_poll = 0; } status_line (msgtxt[M_POLL_COMPLETED]); if (fullscreen) { clear_filetransfer (); } set_prior(4); /* Always High */ DTR_ON (); mdm_init (modem_init); set_prior(2); /* Regular */ m = 1; goto bad_char; /* OUTBOUND 23.10.1989 */ case ALTO: set_up_outbound (); m = 1; more_mail = 1; goto bad_char; case ALTQ: if (cur_event >= 0) e_ptrs[cur_event]->behavior |= MAT_SKIP; goto top_of_mail; case ALTR: for (j = 0; j < num_events; j++) { /* Don't redo forced events */ if (!(e_ptrs[j]->behavior & MAT_FORCED)) { e_ptrs[j]->last_ran = -1; e_ptrs[j]->behavior &= ~MAT_SKIP; } } goto top_of_mail; case ALTS: if (sb_popup (10, 5, 6, 70, Do_Send, 0)) { status_line (msgtxt[M_NO_SEND]); } else { set_up_outbound (); m = 1; more_mail = 1; } goto bad_char; case ALTT: #ifdef ATARIST case UNDO: #endif status_line (msgtxt[M_ENTER_TERMINAL_MODE]); b_init (); done = 0; /* We won't exit now */ goto mail_done; case ALTW: if (fullscreen) { screen_clear (); sb_dirty (); sb_show (); } goto bad_char; #if N_SHELLS < 10 case ALTF10: #endif #ifdef ATARIST case HELP: #endif mailer_help (); if (fullscreen) { screen_clear (); sb_dirty (); opening_banner (); mailer_banner (); } m = 1; goto bad_char; case ALTX: case CTRLQ: /* ^Q for ACS compatibility */ status_line (msgtxt[M_EXIT_REQUEST]); goto mail_done; case ALTF1: case ALTF2: case ALTF3: case ALTF4: case ALTF5: case ALTF6: case ALTF7: case ALTF8: case ALTF9: #if N_SHELLS >= 10 case ALTF10: #endif j = (int) (((unsigned) i) >> 8) - ((unsigned)ALTF1>>8); if (shells[j] != NULL) { /* GENERALEXEC 24.09.1989 */ exec_shell (++j); m = 1; goto top_of_mail; } status_line (msgtxt[M_NO_KEYBOARD_SHELL], j + 1); goto bad_char; case PGUP: if (next_mail == NULL) next_mail = mail_top; if (next_mail != NULL) { for (j = 0; j < 4; j++) { if (next_mail->prev != NULL) next_mail = next_mail->prev; } xmit_window (next_mail); } goto bad_char; case PGDN: if (next_mail == NULL) { next_mail = mail_top; } if (next_mail != NULL) { for (j = 0; j < 4; j++) { if (next_mail->next != NULL) next_mail = next_mail->next; } xmit_window (next_mail); } goto bad_char; case UPAR: if (next_mail == NULL) { next_mail = mail_top; } if (next_mail != NULL) { if (next_mail->prev != NULL) next_mail = next_mail->prev; xmit_window (next_mail); } goto bad_char; case DNAR: if (next_mail == NULL) { next_mail = mail_top; } if (next_mail != NULL) { if (next_mail->next != NULL) next_mail = next_mail->next; xmit_window (next_mail); } goto bad_char; case HOME: next_mail = mail_top; xmit_window (next_mail); goto bad_char; case END: if (next_mail == NULL) { next_mail = mail_top; } if (next_mail != NULL) { while (next_mail->next != NULL) { next_mail = next_mail->next; } } for (j = 0; j < 3; j++) { if (next_mail->prev != NULL) next_mail = next_mail->prev; } xmit_window (next_mail); goto bad_char; #ifndef ATARIST default: status_line (msgtxt[M_JUNK_CHARACTER]); m = 1; goto bad_char; } } else { switch (i & 0xff) { #endif case ESC: m = sb_popup(10,2, 3,74, do_shell, 0); goto bad_char; case 'C': case 'c': if (cur_event >= 0) if (e_ptrs[cur_event]->behavior & MAT_NOOUT) { status_line (msgtxt[M_NO_CALLS_NOW]); goto immed_call; } status_line (msgtxt[M_IMMEDIATE_CALL]); m = 0; more_mail = 1; goto immed_call; case '$': kill_bad(); goto bad_char; #ifndef ATARIST /* Put in same place as Alt-X */ case 3: status_line (msgtxt[M_EXIT_REQUEST]); goto mail_done; #endif case 0x20: m = 1; goto bad_char; default: status_line (msgtxt[M_JUNK_CHARACTER]); m = 1; goto bad_char; } #ifndef ATARIST } #endif } mail_done: write_sched (); status_line ("+%s, %s", msgtxt[M_END], xfer_id); un_attended = 0; if (fullscreen) { gotoxy (0, SB_ROWS); } set_prior(4); /* Always High */ XON_ENABLE (); set_prior(2); /* Regular */ return (done); }