home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * MBFWD.C - 1/31/89 - Autoforwarding.
- *
- * The target port mode is set to idle if not connected,
- * set to remote if connected. It is set to disconnect or timeout
- * by getdat(), but this is checked and fixed up in getln().
- *
- * All port input is through getln().
- * All file input is through nxtin().
- */
-
- #include "mb.h"
-
- #define deepmax 5 /* Max nesting depth of indirection in fwd.mb */
-
- #define fw_one 0x01 /* Forward to only one MailBox, given in fcall*/
- #define fw_anytime 0x02 /* Ignore the times in the "G" item */
- #define fw_abort 0x04 /* Abort forwarding as soon as possible */
- #define fw_tried 0x08 /* Attempted to forward to this MailBox */
- #define fw_tiout 0x10 /* Forward timeout flag */
- #define fw_forced 0x20 /* Forced forward flag */
- #define fw_pass 0x40 /* Bypass forward sub file */
-
- char *script; /* Pointer to where the connect script is */
-
- byte fopts; /* Options, see defines above. */
- char fwdtyp;
- char *fwdfile; /* The file name of fwd.mb root file */
- FILE *ifl[deepmax]; /* File variables for fwd.mb */
- short deep; /* Current depth within fwd.mb */
- char path[80]; /* "G" item saved here, for logging */
- char fcall[10]; /* Call of the MailBox to forward to */
-
- /*
- * YF command: change the name of the forwarding root file.
- */
-
- newfwd()
- {
- if (*port->fld[1])
- {
- free(fwdfile);
- fwdfile = strdup(port->fld[1]);
- }
- sprintf(tmp->scr, "is %s\n", fwdfile);
- outstr(tmp->scr);
- }
-
- /*
- * Add a call to the list of BBS that have messages to be forwarded to them.
- */
-
- addbfwd(cp)
- char *cp;
- {
- register short i;
- register char *lp;
-
- for (i = 0, lp = bfwd; i < bfwdn; i++, lp += ln_call)
- if (matchn(cp, lp, ln_call)) return;
-
- if (bfwdn < bfwdm) { strncpy(lp, cp, ln_call); bfwdn++; }
- }
-
- /*
- * Add a call to the list of users that have unread messges.
- */
-
- addufwd(cp)
- char *cp;
- {
- register short i;
- register char *lp;
-
- for (i = 0, lp = ufwd; i < ufwdn; i++, lp += ln_call)
- if (matchn(cp, lp, ln_call)) return;
-
- if (ufwdn < ufwdm) { strncpy(lp, cp, ln_call); ufwdn++; }
- }
-
- /*
- * Check if a call has a message to be forwarded to it.
- */
-
- findfwd(cp, lp, n)
- char *cp, *lp;
- short n;
- {
- register short i;
-
- for (i = 0; i < n; i++, lp += ln_call) if (wcm(cp, lp)) return true;
- return false;
- }
-
- /*
- * Add the info from one message header to the lists of calls
- * of stations that have messages to be forwarded to them.
- *
- * ufwd - Calls to put in beacon line.
- * bfwd - Calls that have message TO or AT.
- */
-
- addfwd()
- {
- register short i;
- char *p, hcall[6];
-
- if (!(port->mmhs->stat & (m_busy | m_kill | m_read | m_fwd | m_hold)))
- {
- if (*port->mmhs->bbs is ' ')
- {
- addufwd(port->mmhs->to);
- addbfwd(port->mmhs->to);
- }
- else
- {
- if (port->mmhs->ext is 1)
- {
- for (i = 0; i < port->mmhs->count; i++) if (port->mmhs->flag[i])
- addbfwd(port->mmhs->call[i]);
- }
- else
- {
- if (matchn(port->mmhs->bbs, cport->user->call, ln_call))
- addufwd(port->mmhs->to);
- else addbfwd(port->mmhs->bbs);
- if (port->mmhs->ext is 2)
- {
- p = port->mmhs->call[0];
- while((p = strchr(p, '.')) isnt NULL)
- {
- p++;
- fill(hcall, ' ', ln_call);
- pcall(hcall, p);
- addbfwd(hcall);
- }
- }
- }
- }
- }
- }
-
- /*
- * Build the two lists of calls of stations that have
- * messages to be forwarded to them.
- */
-
- bldfwd()
- {
- register word h;
-
- ufwdn = 0;
- bfwdn = 0;
- read_rec(mfl, 0, (char *)mfhs);
- for (h = mfhs->last; h; h--)
- {
- read_rec(mfl, h, (char *)port->mmhs);
- if (!(port->mmhs->stat & (m_busy | m_kill | m_read | m_fwd | m_hold)))
- addfwd();
- }
- }
-
- /*
- * Return true if the current time is within
- * the time window for forwarding to this MailBox.
- */
-
- chktime()
- {
- register short c, en, st;
-
- if (fopts & fw_anytime) return true;
- curtim();
- st = 10 * (int)(cport->line[2] - '0') + (int)(cport->line[3] - '0');
- en = 10 * (int)(cport->line[4] - '0') + (int)(cport->line[5] - '0');
- c = 10 * (int)(l_time[0] - '0') + (int)(l_time[1] - '0');
- if (st <= en) return ((c >= st) and (c <= en));
- return ((c >= st) or (c <= en));
- }
-
- /*
- * Check if it is ok to forward using this list.
- * Return a pointer to the port to use for forwarding, or NULL.
- */
-
- PORTS *chkfwd()
- {
- register PORTS *p;
-
- if (fopts & fw_one)
- if (!match (fcall, cport->fld[1])) { passlst(); return NULL; }
- if (!chktime()) { passlst(); return NULL; }
- if ((p = findport(cport->opt2)) is NULL) { passlst(); return NULL; }
- if (!(p->flags & p_dofwd)) { passlst(); return NULL; }
- if (fopts & fw_abort) { passlst(); return NULL; }
- p->mode = idle;
- return p;
- }
-
- /*
- * Check if a disconnect happened.
- */
-
- chkdis()
- {
- if (instat()) if (getdat()) if (isdis(port->line))
- { cmdtnc(); port->mode = idle; return true; }
- if (port->flags & p_trans) if (!isdcd())
- { cmdtnc(); port->mode = idle; return true; }
- return false;
- }
-
- /*
- * Read the next input line from FWD.MB,
- * or from a file referenced from FWD.MB.
- * Return NULL if no more lines to read.
- */
-
- char *nxtin(p)
- char *p;
- {
- register char *st, i;
-
- while (deep >= 0)
- {
- i = 1;
- if ((st = fgets(p, 80, ifl[deep])) is NULL)
- {
- fclose(ifl[deep]);
- deep--;
- }
- else
- {
- if (*p isnt '@') return st;
- if (fopts & fw_pass) return st;
- if (*(p+1) is ' ')
- {
- if (!chktime()) return st;
- i = 6;
- }
- if (deep < (deepmax - 1))
- {
- strupr(p);
- remnl(p);
- deep++;
- if ((ifl[deep] = fopen(p + i, "r")) is NULL) deep--;
- }
- }
- }
- return NULL;
- }
-
- /*
- * Do some DOS commands.
- */
-
-
- dofdos()
- {
- register PORTS *p;
-
- if ((p = findport(cport->opt2)) is NULL) { passlst(); return; }
- if (strlen(cport->fld[0]) > 3) if (!chktime()) { passlst(); return; }
- if (fopts)
- if (!((fopts & fw_one) and (match(fcall, cport->fld[1]))))
- { passlst(); return; }
-
- /*
- * Just in case, flush whatever might be currently open.
- */
-
- clnuser();
- clnmsg();
- clnlog();
-
- while (nxtin(cport->line) isnt NULL)
- {
- if (iseof(cport->line)) return;
- remnl(cport->line);
- printf("\nRunning: %s\n", cport->line);
- if (system(cport->line)) perror("Error");
- }
- }
-
- /*
- * The entry to fowarding.
- */
-
- fwd()
- {
- register PORTS *p;
-
- /*
- * If no fwd.mb file, then do nothing.
- */
-
- deep = 0;
- if ((ifl[deep] = fopen(fwdfile, "r")) is NULL) return;
-
- bldfwd();
-
- script = tmp->scr;
- *script = '\0';
-
- while(nxtin(cport->line) isnt NULL)
- {
- bidok = false;
- hidok = false;
- ioport(cport);
- strupr(cport->line);
- parse();
- fwdtyp = cport->opt1;
- switch (fwdtyp)
- {
- case 'E':
- passlst();
- script = tmp->scr;
- *script = '\0';
- break;
- case 'D':
- case 'F':
- case 'G':
- case 'H':
- if ((p = chkfwd()) isnt NULL)
- {
- fopts clrbit fw_tried;
- /*
- * Save tail of list header for logging.
- */
- strcpy(path, cport->line + 6);
- remnl(path);
- script = tmp->scr;
- if (!*script)
- {
- *script = 'C';
- strcpy(script + 1, cport->line + 6);
- *(script + strlen(script) + 1) = '\0';
- }
- dofwd(p);
- dorev(p);
- distnc();
- p->mode = idle;
- ioport(cport);
- }
- script = tmp->scr;
- *script = '\0';
- break;
-
- case 'P':
- dopar();
- break;
-
- case '!':
- dofdos();
- break;
-
- case 'C':
- case 'R':
- case 'S':
- strcpy(script, cport->line);
- script += (strlen(cport->line) + 1);
- *script = '\0';
- break;
-
- default: break;
- }
- }
-
- /*
- * Put us back on the port we were on when we got here.
- */
-
- ioport(cport);
- bidok = false;
- hidok = false;
- }
-
- /*
- * A and AI commands.
- */
-
- all_fwd()
- {
- byte pflg;
- port->opt1 = 'X';
- putcomd( port->opt1, port->opt2 );
-
- pflg = getp_flag();
- putc_flag (pflg);
- port->mode = logout;
- }
-
- /*
- * X and XI commands.
- */
-
- sfwd()
- {
- register PORTS *p;
-
- /*
- * If remote sysop did the command, just remember it for later.
- */
-
- if (port->mode & sysop) { savecmd(); return; }
-
- /*
- * Set up parameters for fwd()
- */
-
- fopts = fw_forced;
- for (p = porthd; p isnt NULL; p = p->next)
- {
- p->ec = p->ecuser;
- p->flags setbit p_dofwd;
- }
-
- if (cport->flds is 2)
- {
- fopts setbit fw_one;
- strncpy (fcall, cport->fld[1], ln_callp);
- }
-
- if (cport->opt2 is 'I') fopts setbit fw_anytime;
-
- fwd();
-
- /*
- * Reset the port flags.
- */
-
- for (p = porthd; p isnt NULL; p = p->next)
- {
- p->ec = p->ecmon;
- p->flags clrbit p_dofwd;
- }
- }
-
- /*
- * Automatic forwarding.
- * Called once each minute when the MailBox is idle.
- */
-
- afwd(curmin)
- int curmin;
- {
- register PORTS *p;
- register short anyfwd;
-
- /*
- * Mark the ports that should forward at this minute.
- */
-
- fopts = 0;
- anyfwd = false;
- for (p = porthd; p isnt NULL; p = p->next) if (p->fwdmin is curmin)
- {
- p->flags setbit p_dofwd;
- p->ec = p->ecuser;
- anyfwd = true;
- }
-
- /*
- * If any ports forward at this minute, do the forwarding.
- */
-
- if (anyfwd)
- {
- setbusy();
- alloff(); /* Turn off connects and monitoring */
- if (s_flag & s_dv) begin_lock();
- readmsg();
- readusr();
-
- /*
- * Write out mon and calls heard files
- */
- clsmon();
-
- /*
- * Once a day, do wp and stale
- */
- if (!matchn(ufhs->wpdate, l_date, ln_date))
- {
- port->opt1 = '\0';
- port->flds = 1;
- dwuser();
- stale();
- strncpy(ufhs->wpdate, l_date, ln_date);
- write_rec(ufl, 0, (char *)ufhs);
- }
- if (s_flag & s_dv) end_lock();
-
- /*
- * Check and see if the mailfile should be compressed
- */
- if (s_param & s_unt)
- if (!matchn(mfhs->date, l_date, ln_date))
- if (unt_hr <= (10 *(l_time[0] - '0') + (l_time[1] - '0')))
- {
- port->opt2 = 'A';
- setunt();
- }
-
- fwd();
- clnlog();
- setfwd();
- clsmsg();
- clsusr();
- allon(); /* Turn on monitoring and connects */
- clrbusy();
- }
-
- /*
- * Reset the port flags.
- */
-
- for (p = porthd; p isnt NULL; p = p->next)
- {
- p->ec = p->ecmon;
- p->flags clrbit p_dofwd;
- }
- }
-
- /*
- * Reverse forwarding.
- * Accept messages from the remote MailBox after forwarding to it.
- */
-
- dorev(p)
- PORTS *p;
- {
- ioport(p);
-
- if (fwdtyp is 'G') return;
- if (fwdtyp is 'D') return;
-
- if (p->mode & idle)
- {
- if (fwdtyp is 'F') return;
- if (fwdtyp is 'H') if (fopts & fw_tried) return;
- cmb();
- if (p->mode & idle) return;
- }
-
- pcall(fcall, path + 2);
- rduser(fcall, p->user);
- log ('M', 'F', 'R', path); /* Log start of reverse forward */
-
- if (p->tmode)
- {
- cmdtnc();
- trantnc();
- }
-
- while(true)
- {
- outstr("F>\n");
- getln();
- if (p->mode & idle) return;
- parse();
-
- if (p->opt1 isnt 'S') return;
- {
- sndmsg();
- if (p->mode & gone) return;
- addfwd();
- }
- }
- }
-
- /*
- * F> command: do reverse forward to logged user.
- */
-
- fwdcmd()
- {
- register PORTS *p;
- register short ok;
-
- /*
- * If no fwd.mb file, then do nothing.
- */
-
- p = port;
- deep = 0;
- if ((ifl[deep] = fopen(fwdfile, "r")) is NULL) { p->mode = forced; return; }
-
- ioport(cport);
-
- /*
- * Find the users E, F, G, or H list in the fwd.mb file.
- */
-
- ok = false;
- while(!ok and (nxtin(cport->line) isnt NULL))
- {
- strupr(cport->line);
- parse();
- fwdtyp = cport->opt1;
-
- switch(fwdtyp)
- {
- case 'D' :
- case 'E' :
- case 'F' :
- case 'G' :
- case 'H' :
- pcall(fcall, cport->fld[1]);
- ok = matchn(fcall, p->user->call, ln_call);
-
- if (!ok) passlst();
- break;
-
- case '!' :
- case 'P' :
- passlst();
- break;
-
- default : ; /* 'C', 'R', 'S' */
- }
- }
-
- ioport(p);
-
- if (ok)
- {
- log ('M', 'F', 'S', nullstr); /* Log start of forwarding */
- bldfwd();
- remnl(cport->line);
- strcpy( path, cport->line+6 );
- dofwd(p);
- log ('M', 'F', 'E', nullstr); /* Log end of forwarding */
- }
-
- while (deep >= 0) { fclose(ifl[deep]); deep--; }
- if(p->mode is idle) return;
- outstr("*** Done.\n");
- }
-
- /*
- * Pass a sublist in the forwarding file.
- */
-
- passlst()
- {
- fopts setbit fw_pass;
- while (true)
- {
- if (nxtin(cport->line) is NULL) {fopts clrbit fw_pass; return;}
- if (iseof(cport->line)) {fopts clrbit fw_pass; return;}
- }
- }
-
- /*
- * Set tnc parameters.
- */
-
- dopar()
- {
- register PORTS *p;
-
- if ((p = findport(cport->opt2)) is NULL) { passlst(); return; }
-
- if (strlen(cport->fld[0]) > 3) if (!chktime()) { passlst(); return; }
-
- ioport(p);
- while (nxtin(cport->line) isnt NULL)
- {
- if (iseof(cport->line)) { ioport(cport); return; }
- onetnc(cport->line);
- }
- ioport(cport);
- }
-
- /*
- * Get a line from the current port.
- * Handle disconnect, timeout, and ^F.
- */
-
- getln()
- {
- while (!getdat());
- if (port->mode & forced) fopts setbit fw_abort;
- if (port->mode & gone) { distnc(); port->mode = idle; }
- }
-
- /*
- * Eat the remote MailBox prompt.
- */
-
- eat()
- {
- register char c;
-
- if (fwdtyp is 'D') c = ':'; else c = '>';
- while(true) {
- getln();
- if (!(port->mode & remote)) return;
- if (port->line[0] is '[') isbid();
- if ((port->mode & remote) and (port->line[strlen(port->line) - 2] is c)) {
- return;
- }
- }
- }
-
- /*
- * Connect to a remote Mailox.
- * Port mode idle at entry.
- * On return, port mode is remote if the connect worked, else idle.
- */
-
- cmb()
- {
- port->flags setbit p_dotmr;
- port->mode = remote;
-
- /*
- * Execute the connect script.
- */
-
- while(*script)
- {
- switch (*script++)
- {
- case 'C' :
- contnc(script);
- if (port->mode & idle) return;
- if (port->dev is p_tnc) do
- {
- getln();
- if (port->mode & idle) return;
- }
- while (!iscon(port->line));
- break;
-
- case 'S' :
- outstr(script);
- break;
-
- case 'R' :
- getln();
- if (port->mode & idle) return;
- strupr(port->line);
- if (*script isnt '!')
- if (!search(port->line, script, strlen(script)-1))
- { distnc(); port->mode = idle; return; }
- break;
-
- default: ;
- }
- while(*script++); /* Move to next script line */
- }
-
- /*
- * In theory, now connected to MailBox. Eat login messge.
- */
-
- eat();
- if (!(port->mode & remote)) return;
- if (bidok) {
- outstr("[CBBS-6.0-H$]\n");
- eat();
- }
- }
-
- /*
- * Forward whatever messages go to this MailBox.
- */
-
- dofwd(p)
- PORTS *p;
- {
- register char *st;
-
- st = nxtin(cport->line);
- while (!iseof(cport->line) and (st isnt NULL))
- {
- ioport(cport);
- parse();
- ioport(p);
- pcall (tcall, cport->fld[0]);
-
- if (findfwd(tcall, bfwd, bfwdn))
- {
- fmsg();
- if (fopts & fw_tried) if (p->mode & idle)
- {
- p->mmhs->stat clrbit m_busy;
- wt_mmhs();
- passlst();
- return;
- }
- }
-
- st = nxtin(cport->line);
- }
- }
-
- /*
- * Send the message text.
- */
-
- xmtmsg()
- {
- register FILE *fl;
-
- sprintf(port->line, "%s%u", msgdir, port->mmhs->number);
- if ((fl = fopen(port->line, "r")) is NULL) nofile(port->line); else
- {
- fseek(fl, (long)RECSIZE, 0);
- while(fgets(tmp->scr, scrmax, fl) isnt NULL)
- {
- if (chkdis()) { fclose(fl); return false; }
- outstr(tmp->scr);
- }
- fclose (fl);
- }
- if (fwdtyp is 'D')
- {
- outstr(".\n");
- outstr("y\n");
- }
- else
- {
- outchar (cpmeof);
- outchar ('\n');
- }
- return true;
- }
-
- /*
- * Forward all messages TO or AT tcall
- * to the MailBox we are connected to.
- */
-
- fmsg()
- {
- char *a, *b, *c;
- char hcall[6];
- register PORTS *p;
- register word h;
- register short i, ok, kill, extnr, kok, hasit;
-
- hasit = true; /* just initialize it to something */
-
- p = port;
- for (h = mfhs->last; h; h--)
- {
- if (s_flag & s_dv) begin_lock();
- read_rec(mfl, h, (char *)p->mmhs);
-
- ok = (!(p->mmhs->stat & (m_kill | m_read | m_fwd | m_hold | m_busy)));
- /*
- * Decide whether to forward this one.
- */
- if (ok)
- {
- if (p->mmhs->ext is 1)
- {
- ok = false;
- for (i = 0; !ok and (i < p->mmhs->count); i++) if (p->mmhs->flag[i])
- if (wcm(tcall, p->mmhs->call[i])) { ok = true; extnr = i; }
- }
- else if (*p->mmhs->bbs isnt ' ')
- {
- ok = wcm(tcall, p->mmhs->bbs);
- if (!ok) if (p->mmhs->ext is 2)
- {
- c = p->mmhs->call[0];
- while(!ok and ((c=strchr(c, '.')) isnt NULL))
- {
- c++;
- fill(hcall, ' ', ln_call);
- pcall(hcall, c);
- ok = wcm(tcall, hcall);
- }
- }
- }
- else ok = wcm(tcall, p->mmhs->to);
- }
-
- if (ok)
- {
- p->mmhs->stat setbit m_busy;
- wt_mmhs();
- }
- if (s_flag & s_dv) end_lock();
-
- /*
- * If we DO forward this one, forward this one.
- */
- if (ok)
- {
- if (fopts & fw_tiout) { wait (p->ftime); fopts clrbit fw_tiout; }
- fopts setbit fw_tried;
- if (p->mode & idle) cmb();
- if (p->mode & idle) return;
-
- if (fwdtyp is 'D') prtx("mail $G\n");
-
- if (*p->mmhs->bbs is ' ') prtx("S$B $G < $P");
- else if((hidok)and(p->mmhs->ext is 2)) prtx("S$B $G @ $h < $P");
- else prtx("S$B $G @ $A < $P");
-
- if (bidok) if (*p->mmhs->bid isnt ' ') {
- outstr(" $");
- a = p->line;
- b = p->mmhs->bid;
- unbl(a, b, ln_bid);
- outstr(p->line);
- }
- outchar('\n');
- getln(); if (p->mode & idle) return;
- if (bidok)
- {
- if(*p->line < ' ') { getln(); if(p->mode & idle) return; }
- switch(*p->line)
- {
- case 'O': hasit = false;
- outstr(p->mmhs->title);
- outchar('\n'); break;
- case 'N': hasit = true; break;
- default : p->mmhs->stat clrbit m_busy;
- wt_mmhs();
- return;
- }
- }
- else
- {
- hasit = false; /* you'll want to send msg */
- outstr(p->mmhs->title); outchar('\n');
- if (fwdtyp isnt 'D')
- {
- getln(); if (p->mode & idle) return;
- }
- }
- if (!hasit)
- {
- curtim();
- if (port->dev is p_tnc) prtx(mm[4]);
- if (!xmtmsg()) { fopts setbit fw_tiout; return;}
- }
- eat(); if (p->mode & idle){ fopts setbit fw_tiout; return; }
- /*
- * The message actually forwarded.
- * Kill it, mark it, or whatever.
- */
- sprintf(p->line, "%u %s", p->mmhs->number, path);
- log ('M', 'F', ' ', p->line);
-
- kill = false;
- kok = false;
- /*
- * If cc: list exists, mark this call as forwarded.
- */
- if (p->mmhs->ext is 1)
- {
- p->mmhs->flag[extnr] = false;
- for (i = 0; i < p->mmhs->count; i++) if (p->mmhs->flag[i]) kok = true;
- }
-
- if (!kok)
- {
- if ((p->mmhs->type is 'F') or (p->mmhs->type is 'B'))
- kill = s_param & s_fkill;
- else kill = s_param & s_kill;
- }
-
- if (kill) p->mmhs->stat setbit m_kill;
- else
- if (!kok) p->mmhs->stat setbit m_fwd;
- p->mmhs->stat clrbit m_busy;
- write_rec(mfl, p->mmhs->rn, (char *)p->mmhs);
- makehdr2();
- }
- }
- }