home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HAM Radio 3
/
hamradioversion3.0examsandprograms1992.iso
/
packet
/
n17jsrc
/
forward.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-15
|
25KB
|
870 lines
/* Some of the code in this file was originally based on the following file:
* gateway.c : Paul Healy, EI9GL, 900818
*
* Rewrote forwarding mechanism to use "X-Forwarded-To" paradigm instead of
* "X-BBS-To", added timer support, etc. Anders Klemets, SM0RGV, 901009.
*/
/* Mods by G1EMM */
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "global.h"
#include "config.h"
#include "bm.h"
#include "mailbox.h"
#include "smtp.h"
#include "cmdparse.h"
#include "proc.h"
#include "socket.h"
#include "timer.h"
#include "usock.h"
#include "netuser.h"
#include "ax25.h"
#include "netrom.h"
#include "nr4.h"
#include "files.h"
#define ISPROMPT(s) (strlen(s) > 1 && s[strlen(s)-2] == '>')
static struct timer fwdtimer;
static char *findident __ARGS((char *str, int n, char *result));
static void sendmsg __ARGS((struct mbx *m,int msgn));
static char *mbxtime __ARGS((char *line));
static int fwdinit __ARGS((struct mbx *m));
static char *fwdanybbs __ARGS((struct mbx *m));
static int timeok __ARGS((char *line));
static void fwdtick __ARGS((void *v));
static int isconnbbs __ARGS((struct mbx *m));
static void startfwd __ARGS((int a,void *v1,void *v2));
static int openconn __ARGS((int argc,char *argv[],void *p));
static int sendmsgtobbs __ARGS((struct mbx *m,int msgn,char *dest,int bulletin));
static int makecl __ARGS((struct mbx *m,int msgn,char *dest,char *line,char *subj,int bulletin));
static char *grabtext __ARGS((char *from,char *to,int marker));
/***************************************************************************
findident copies the 'n'th alphanumeric sequence from 'str' to result.
It returns a ptr to result. It returns "\0" for missing identifier etc.
Uses isalnum macro to decide on alphanumeric/non-alnum status.
*/
static char *
findident(str, n, result)
char *str, *result;
int n;
{
int count; /* current identifier */
count = 0;
*result = '\0';
while ( (count<n) && (*str!='\0') ) { /* Process alnum or non alnum seq */
while ( (*str!='\0') && (!isalnum(*str)) ) /* Get rid of ';:.@%"# etc */
str++;
if ( (str!='\0') && isalnum(*str) ) { /* this is an alnum seq */
count++;
while ( (*str!='\0') && (isalnum(*str) || (*str=='_')) )
if (count==n)
*result++ = *str++;
else str++;
if (count==n)
*result = '\0';
}
}
return result;
}
/**************************************************************************/
static void
sendmsg(m,msgn)
struct mbx *m;
int msgn;
{
char buf[LINELEN], tb[LINELEN], *cp;
int len, rec = 0;
long cnt;
fseek(m->mfile,m->mbox[msgn].start,0);
cnt = m->mbox[msgn].size;
/* If the data part of the message starts with "R:" the RFC-822
* headers will not be forwarded. Instead we will add an R:
* line of our own.
*/
for(;;) {
if(fgets(buf,sizeof(buf),m->mfile) == NULLCHAR)
break;
cnt -= strlen(buf);
if(rec == 1) { /* look at the line following Received: */
++rec;
if((cp = strchr(buf,';')) != NULLCHAR){
strcpy(tb,cp+1); /* get the date of receipt */
++rec;
}
}
/* The first Received: line is the one that we have added */
if(!rec && htype(buf) == RECEIVED)
++rec;
if(*buf == '\n') {
if(rec == 3 && cnt > 1) {
fread(buf,1,2,m->mfile);
cnt -= 2;
if(strncmp(buf,"R:",2) == 0) {
pax25(buf,Mycall);
if((cp = strchr(buf,'-')) != NULLCHAR)
*cp = '\0'; /* remove SSID */
usprintf(m->user,"R:%s @%s %s (%s)\nR:",
mbxtime(tb),buf,Hostname,Version);
break;
}
}
/* Start over, forwarding the RFC-822 headers */
fseek(m->mfile,m->mbox[msgn].start,0);
cnt = m->mbox[msgn].size;
rec = 0;
break;
}
}
while(rec != 3) { /* Forward the RFC-822 headers */
if(fgets(buf,sizeof(buf),m->mfile) == NULLCHAR)
break;
cnt -= strlen(buf);
switch(htype(buf)) {
case XFORWARD: /* Do not forward the "X-Forwarded-To:" lines */
case STATUS: /* Don't forward the "Status:" line either */
break;
default:
/* Don't forward the "From " line either - make it ">From " G1EMM */
if(strlen(buf) >= 5 && strncmp(buf,"From ",5) == 0) {
cp = strdup(buf);
strcpy(buf,">");
strcat(buf,cp);
free(cp);
}
usputs(m->user,buf);
}
if(*buf == '\n') /* last header line */
break;
}
do { /* the rest of the message is treated below */
len = min(cnt,sizeof(buf)-1);
if(fread(buf,1,len,m->mfile) != len)
break;
cnt -= len;
buf[len] = '\0';
usputs(m->user,buf);
} while(cnt);
}
/* Parse a line for date and time in Arpanet format
* (Day, day Month year hh:mm:ss Zone) and return it in mailbox format
* (yymmdd/hhmmz)
*/
static char *
mbxtime(line)
char *line;
{
extern char *Months[];
static char buf[12];
char *cp;
int i, day;
cp = line;
while(isspace(*cp)) /* skip initial blanks */
++cp;
if(*cp == '\0')
return NULLCHAR;
if(strlen(cp) < 22)
return NULLCHAR;
cp += 5;
day = atoi(cp);
if(*(++cp) != ' ')
++cp;
++cp;
for(i=0; i < 12; ++i)
if(strnicmp(Months[i],cp,3) == 0)
break;
if(i == 12)
return NULLCHAR;
sprintf(buf,"%02d%02d%02d/%02d%02d%c",atoi(cp + 4),++i,day,atoi(cp + 7),
atoi(cp + 10), (strnicmp(cp + 16,"GMT",3) &&
strnicmp(cp + 16,"UTC",3)) ? ' ' : 'z');
return buf;
}
static char *
grabtext(from, to, marker)
char *from, *to;
int marker;
{
while (*from!=marker)
*to++ = *from++;
*to = '\0';
return from+1;
}
/* Makes a command line and returns -1 if the message cannot be sent. */
static int
makecl(m, msgn, dest, line, subj, bulletin)
struct mbx *m;
int msgn; /* Message number */
char *dest; /* Destination address to use instead of To: line */
char *line, *subj; /* Buffers to keep command line and subject */
int bulletin; /* True if message is in public message area */
{
char bid[LINELEN], to[LINELEN], atbbs[LINELEN], from[LINELEN],
buf[LINELEN], *cp;
if(m->mfile == NULLFILE)
return -1;
if(!bulletin && (m->mbox[msgn].status & BM_READ))
return -1; /* the message was already read */
fseek(m->mfile,m->mbox[msgn].start,0);
*bid = *to = *atbbs = *from = '\0';
if(subj != NULLCHAR)
*subj = '\0';
m->stype = bulletin ? 'B' : 'P'; /* default to SB or SP */
while (fgets(buf,sizeof(buf),m->mfile)) {
if (buf[0] == '\n')
break; /* envelope finished */
switch (htype(buf)) {
case TO:
/* The following code tries to parse "To: " lines where the
* address looks like any of the following: "to@atbbs",
* "<to@atbbs>", "<to%atbbs@host>" and with possible spaces
* surrounding the '<>' characters.
*/
if((cp = getaddress(buf,0)) == NULLCHAR)
break;
strcpy(to,cp);
if((cp = strchr(to,'%')) != NULLCHAR) { /* look for a '%' */
strcpy(atbbs,cp + 1);
*cp = '\0'; /* "to" ends at the '%' character */
}
else { /* no '%' but maybe a '@'? */
if((cp = strchr(to,'@')) != NULLCHAR) {
strcpy(atbbs,cp + 1);
*cp = '\0'; /* "to" ends at the '@' character */
}
}
if(*atbbs != '\0') /* either '%' or '@' found */
/* cut "atbbs" at the first '@' character */
for(cp = atbbs; *cp != '\0'; ++cp)
if(*cp == '@') {
*cp = '\0';
break;
}
/* "to" or "atbbs" should not be more than 6 characters (ALEN).
* If "to" is too long, it might simply be because the area name
* is longer than 6 characters, but it might also be because
* the address on the To: line is in an obscure format that we
* failed to parse (eg '!' character notation.)
*/
if(strlen(to) > ALEN) {
/* Play safe and set "to" and "atbbs" to the area name */
strcpy(to,m->area);
strcpy(atbbs,m->area);
}
if(*atbbs == '\0')
strcpy(atbbs,to);
to[ALEN] = '\0';
/* Only if the BBS supports "hierarchical routing designators"
* is the atbbs field allowd to be longer than 6 characters and
* have dots in it.
*/
if((m->sid & MBX_HIER_SID) == 0) {
atbbs[ALEN] = '\0'; /* 6 character limit */
if((cp = strchr(atbbs,'.')) != NULLCHAR)
*cp = '\0'; /* cut "atbbs" at first dot */
}
break;
case MSGID:
/* The following code distinguishes between two different types
* of Message-IDs: <abcde@callsign.bbs> and <abcde@host.domain>.
* The first type is converted to $abcde and the second to
* $abcde_host.domain. This preserves compability with BBSes.
*/
if((cp = getname(buf)) == NULLCHAR)
break;
bid[0] = '$';
strcpy(&bid[1],cp);
cp = strchr(bid,'@');
/* A trailing ".bbs" indicates that the Message-ID was generated
* from a BBS style message, and not a RFC-822 message.
*/
if(cp != NULLCHAR && stricmp(&bid[strlen(bid) - 4], ".bbs") == 0)
*cp = '\0';
else
*cp = '_';
bid[13] = '\0'; /* BIDs should be no longer than 13 bytes */
break;
case SUBJECT:
if(subj != NULLCHAR)
(void) grabtext(buf+9, subj, '\n');
break;
case FROM:
if((cp = getaddress(buf,0)) != NULLCHAR) {
findident(cp, 1, from); /* cp points to from@domain */
from[ALEN] = '\0'; /* 6 character limit */
}
break;
case XFORWARD:
if((cp = getaddress(buf,0)) == NULLCHAR)
break;
if(stricmp(m->name,cp) == 0)
/* This message has already been forwarded, abort */
return -1;
break;
case BBSTYPE:
m->stype = buf[16];
break;
default:
break;
}
}
/* Check for an invalid RFC-822 header */
if((to[0] == '\0' && ((dest != NULLCHAR && *dest == '\0') ||
dest == NULLCHAR)) || from[0] == '\0')
return -1;
if(line != NULLCHAR) {
if(dest != NULLCHAR && *dest != '\0'){
/* strip off hierarchical routing designators from the predefined
* destination address if they are not supported
*/
if((m->sid & MBX_HIER_SID) == 0 && (cp = strchr(dest,'.')) !=
NULLCHAR)
*cp = '\0';
sprintf(line, "S%c %s < %s ", m->stype, dest, from);
}
else
sprintf(line, "S%c %s @ %s < %s ", m->stype, to, atbbs, from);
if(bulletin & (m->sid & MBX_SID))
strcat(line,bid);
strcat(line,"\n");
}
return 0;
}
static int /* 0 = ok, -1 = problem so disc */
sendmsgtobbs(m, msgn, dest, bulletin)
struct mbx *m;
int msgn;
char *dest; /* Optional destination address to override To: line */
int bulletin;
{
int result = -1;
char line[64], subj[256];
if(makecl(m, msgn, dest, line, subj, bulletin) == -1)
return 0; /* do not forward this particular message */
tputs(line); /* Send mail offer to bbs */
rip(line);
usflush(m->user);
if (recvline (m->user, m->line, MBXLINE) != -1 ) {
if (m->line[0] == 'O' || m->line[0] == 'o' || (m->sid & MBX_SID) == 0) {
/* Got 'OK' or any line if the bbs is unsofisticated */
tprintf("%s\n", subj);
sendmsg(m,msgn); /* send the message */
tputs("/EX\n"); /* was 0x1a */
usflush(m->user);
/* get F> for a good deliver */
while (recvline (m->user, m->line, MBXLINE) != -1 )
if (ISPROMPT(m->line)) {
log(m->user,"MBOX bbs mail sent: %s ", line);
if(bulletin)
m->mbox[msgn].status |= BM_FORWARDED;
else
m->mbox[msgn].status |= BM_DELETE;
m->change = 1;
result = 0;
break;
}
}
else { /* OK response not received from bbs */
if (m->line[0] == 'N' || m->line[0] == 'n') { /* 'NO' respone */
log(m->user,"MBOX bbs mail refused: %s\n %s",line,m->line);
/* Mark refused message as forwarded if it is a bulletin.
* The message was probably a duplicate. Non-bulletin
* messages are sent without BID, so they cannot be dected
* as duplicates. The reason why it was refused is probably
* because the address was invalid. Retry later.
*/
if(bulletin){
m->mbox[msgn].status |= BM_FORWARDED;
m->change = 1;
}
}
/* should get a F> here */
while (recvline (m->user, m->line, MBXLINE) != -1 )
if (ISPROMPT(m->line)) {
result = 0;
break;
}
}
} /* OK or NO here */
return result;
}
/* This is the main entry point for reverse forwarding. It is also used
* for normal, "forward", forwarding.
*/
int
dorevfwd(argc,argv,p)
int argc;
char *argv[];
void *p;
{
char oldarea[64], *cp;
struct mbx *m;
int i, bulletin, err = 0;
m = (struct mbx *)p;
log(m->user,"MBOX forwarding mail to: %s ", m->name);
/* indicate we are doing reverse forwarding, if we are not already
* doing normal forwarding.
*/
if(m->state != MBX_FORWARD)
m->state = MBX_REVFWD;
if(fwdinit(m) != -1) {
strcpy(oldarea,m->area);
while(!err && fgets(m->line,MBXLINE,m->tfile) != NULLCHAR) {
if(*m->line == '-') /* end of record reached */
break;
rip(m->line); /* adds extra null at end */
cp = strchr(m->line,' '); /* remove trailing blanks */
if(cp != NULLCHAR)
*cp = '\0';
if((cp = strchr(m->line,'\t')) != NULLCHAR)
*cp = '\0';
if(*m->line == '\0' || *m->line == '.')
continue;
changearea(m,m->line);
bulletin = isarea(m->line); /* public area */
/* get the optional destination field, cp will point
* at null byte if it is missing.
*/
cp = &m->line[strlen(m->line)] + 1;
while(*cp != '\0' && isspace(*cp)) /* strip blanks */
++cp;
cp = strdup(cp);
for(i=1; i<=m->nmsgs; i++)
if(sendmsgtobbs(m, i, cp, bulletin) == -1) {
err = 1; /* abort */
break;
}
free(cp);
}
fclose(m->tfile);
m->tfile = NULLFILE;
if(*oldarea != '\0')
changearea(m,oldarea);
}
if(m->state == MBX_FORWARD)
return 0;
tprintf("*** Done\n");
if((m->sid & MBX_RLI_SID)) /* disconnect if it is a W0RLI bbs */
return domboxbye(0,NULL,m);
return 0;
}
/* Read the forward file for a record for the connected BBS. If found,
* return 1 if this is the right time to forward, m->tfile is left pointing
* at the first message area to be forwarded.
*/
static int
fwdinit(m)
struct mbx *m;
{
char host[80];
int start = 1;
if((m->tfile = fopen(Forwardfile,READ_TEXT)) == NULLFILE)
return -1;
while(fgets(m->line,MBXLINE,m->tfile) != NULLCHAR) {
if(*m->line == '\n')
continue;
/* lines starting with '-' separate the forwarding records */
if(*m->line == '-') {
start = 1;
continue;
}
if(start) {
start = 0;
/* get the name of this forwarding record */
findident(m->line,1,host);
if(stricmp(m->name,host) == 0) {
if(!timeok(m->line))
break;
/* eat the connect command line */
fgets(m->line,MBXLINE,m->tfile);
return 0;
}
}
}
fclose(m->tfile);
m->tfile = NULLFILE;
return -1;
}
/* Read the forward file for a record for the connected BBS. If found,
* determine if this is the right time to forward, and return the command
* line to establish a forwarding connection. m->tfile is left pointing
* at the first message area to be forwarded.
*/
static char *
fwdanybbs(m)
struct mbx *m;
{
char host[80];
int start = 1;
if(m->tfile == NULLFILE && (m->tfile = fopen(Forwardfile,READ_TEXT))
== NULLFILE)
return NULLCHAR;
while(fgets(m->line,MBXLINE,m->tfile) != NULLCHAR) {
if(*m->line == '\n')
continue;
/* lines starting with '-' separate the forwarding records */
if(*m->line == '-') {
start = 1;
continue;
}
if(start) {
start = 0;
/* get the name of this forwarding record */
findident(m->line,1,host);
strcpy(m->name,host);
if(!timeok(m->line))
continue; /* too late or too early */
/* get the connect command line */
fgets(m->line,MBXLINE,m->tfile);
return strdup(m->line);
}
}
fclose(m->tfile);
m->tfile = NULLFILE;
return NULLCHAR;
}
/* get any groups of four digits that specify the begin and ending hours of
* forwarding. Returns 1 if forwarding may take place.
*/
static int
timeok(line)
char *line;
{
char hours[80], *now;
long t;
int t1, t2, pos = 2;
findident(line,pos++,hours);
if(*hours == '\0')
return 1; /* no digits default to 0023, ie. anytime */
time(&t);
now = ctime(&t) + 11;
*(now + 2) = '\0';
while(*hours != '\0') {
t1 = (*hours - '0') * 10 + (*(hours+1) - '0');
t2 = (*(hours+2) - '0') * 10 + (*(hours+3) - '0');
if(atoi(now) >= t1 && atoi(now) <= t2)
return 1; /* right in time */
findident(line,pos++,hours); /* get next group if any */
}
return 0; /* too early or too late */
}
int
dombtimer(argc,argv,p)
int argc;
char *argv[];
void *p;
{
if(argc < 2){
tprintf("Forwarding timer: %lu/%lu\n",
read_timer(&fwdtimer)/1000L,
dur_timer(&fwdtimer)/1000L);
return 0;
}
fwdtimer.func = (void (*)())fwdtick;/* what to call on timeout */
fwdtimer.arg = NULL; /* dummy value */
set_timer(&fwdtimer,atol(argv[1])*1000L); /* set timer duration */
start_timer(&fwdtimer); /* and fire it up */
return 0;
}
int
dombkick(argc,argv,p)
int argc;
char *argv[];
void *p;
{
fwdtick(NULL);
return 0;
}
/* called when the forward timer expires or explicitly by dombkick() */
static void
fwdtick(v)
void *v;
{
char *cc, *cp;
struct mbx *m;
int i, bulletin, skip = 0;
if(Mtrace)
tprintf("mailbox: forward started\n");
/* restart the timer */
start_timer(&fwdtimer);
if((m = newmbx()) == NULLMBX){
if(Mtrace)
tprintf("mailbox: unable to start new maibox\n");
return;
}
m->user = Curproc->output;
m->state = MBX_TRYING;
while((cc = fwdanybbs(m)) != NULLCHAR) {
if(isconnbbs(m)) /* already connected to this BBS, skip it */
skip = 1;
while(fgets(m->line,MBXLINE,m->tfile) != NULLCHAR) {
if(*m->line == '-') { /* end of record reached */
skip = 0;
break;
}
if((cp = strchr(m->line,' ')) != NULLCHAR)
*cp = '\0';
if((cp = strchr(m->line,'\t')) != NULLCHAR)
*cp = '\0';
if(skip || *m->line == '\0' || *m->line == '.')
continue;
rip(m->line);
changearea(m,m->line);
bulletin = isarea(m->line); /* public area */
/* check if there are any messages in this area
* that need to be forwarded.
*/
for(i=1; i<=m->nmsgs; i++)
if(makecl(m, i, NULLCHAR, NULLCHAR, NULLCHAR,
bulletin) == 0) {
if(Mtrace)
tprintf("mailbox: forwarding to %s\n"
,m->name);
newproc("Mbox forwarding", 2048,
startfwd, 0, (void *)cc,
(void *)strdup(m->name),0);
skip = 1;
cc = NULLCHAR;
break;
}
}
free(cc);
}
exitbbs(m);
}
/* returns 1 if m->name matches the name of another connected mailbox. */
static int
isconnbbs(m)
struct mbx *m;
{
int i;
for(i = 0; i < NUMMBX; ++i)
if(Mbox[i] != NULLMBX && Mbox[i] != m &&
stricmp(m->name,Mbox[i]->name) == 0)
return 1;
return 0;
}
/* possible commands on the command line in the forwarding file */
static struct cmds cfwdcmds[] = {
"tcp", openconn, 0, 0, NULLCHAR,
"telnet", openconn, 0, 0, NULLCHAR,
#ifdef AX25
"ax25", openconn, 0, 0, NULLCHAR,
"connect", openconn, 0, 0, NULLCHAR,
#endif
#ifdef NETROM
"netrom", openconn, 0, 0, NULLCHAR,
#endif
NULLCHAR
};
/* this function is called whenever the forwarding timer expires */
static void
startfwd(a,v1,v2)
int a;
void *v1, *v2;
{
struct mbx *m;
char *cc;
cc = (char *) v1;
if((m = newmbx()) == NULLMBX) {
free(cc);
free((char *)v2);
return;
}
strcpy(m->name,(char *)v2);
free((char *)v2);
m->state = MBX_TRYING;
/* open the connection, m->user will be the new socket */
if(cmdparse(cfwdcmds,cc,(void *)m) == -1) {
free(cc);
exitbbs(m);
if(Mtrace)
tprintf("mailbox: unknown forwarding protocol\n");
return;
}
free(cc);
m->state = MBX_FORWARD;
sockowner(m->user,Curproc);
close_s(Curproc->output);
close_s(Curproc->input);
/* m->user will be closed automatically when this process exits */
Curproc->output = Curproc->input = m->user;
/* We'll do our own flushing right before we read input */
setflush(m->user,-1);
if(fwdinit(m) == -1) {
/* it is probably not the right time to forward anymore */
exitbbs(m);
return;
}
/* read the connect script. Lines starting with a dot will be sent
* to the remote BBS.
*/
while(fgets(m->line,MBXLINE,m->tfile) != NULLCHAR)
if(*m->line == '.')
tputs(m->line + 1);
else
break;
usflush(m->user);
fclose(m->tfile);
m->tfile = NULLFILE;
/* read the initial output from the bbs, looking for the SID */
for(;;) {
if(recvline(m->user,m->line,MBXLINE) == -1) {
exitbbs(m);
return;
}
if(ISPROMPT(m->line))
break;
if(*m->line == '[') { /* parse the SID */
rip(m->line);
mbx_parse(m);
continue;
}
}
/* Now sync the two ends as telnet password messes them up */
if(socklen(m->user,0)) /* discard any remaining input */
recv_mbuf(m->user,NULL,0,NULLCHAR,0);
/* send our SID if the peer announced its SID */
if(m->sid & MBX_SID) {
tputs("[NET-H$]\n");
usflush(m->user);
for(;;) {
if(recvline(m->user,m->line,MBXLINE) == -1) {
exitbbs(m);
return;
}
if(ISPROMPT(m->line))
break;
}
}
/* start the actual forwarding */
dorevfwd(0,NULL,(void *)m);
/* ask for reverse forwarding or just disconnect */
if(((m->sid & MBX_SID) && tputs("F>\n") == -1) ||
(m->sid & MBX_SID) == 0) {
exitbbs(m);
close_s(Curproc->output);
return;
}
usflush(m->user);
/* parse the commands that are are received during reverse
* forwarding.
*/
while(recvline(m->user,m->line,MBXLINE) > 0) {
rip(m->line);
if(mbx_parse(m) == 2) /* got the "*** Done" command */
break;
tputs("F>\n");
usflush(m->user);
}
exitbbs(m);
close_s(Curproc->output);
}
/* open a network connection based upon information in the cc line.
* m->user is set to the socket number.
*/
static int
openconn(argc,argv,p)
int argc;
char *argv[];
void *p;
{
struct mbx *m;
char sock[MAXSOCKSIZE], *np, alias[AXBUF];
union sp sp;
int len;
m = (struct mbx *)p;
sp.p = sock;
if(argc < 2)
return -1;
switch(*argv[0]) {
case 't':
sp.in->sin_family = AF_INET;
if((sp.in->sin_addr.s_addr = resolve(argv[1])) == 0)
return -1;
/* get the optional port number */
if(argc > 2)
sp.in->sin_port = atoi(argv[2]);
else
sp.in->sin_port = IPPORT_TELNET;
if((m->user = socket(AF_INET,SOCK_STREAM,0)) == -1)
return -1;
len = sizeof(*sp.in);
break;
#ifdef AX25
case 'a':
case 'c': /* allow 'c' for 'connect' as well */
if(argc < 3)
return -1;
sp.ax->sax_family = AF_AX25;
strncpy(sp.ax->iface,argv[1],ILEN); /* the interface name */
setcall(sp.ax->ax25_addr,argv[2]); /* the remote callsign */
/* no digipeaters for now, use the "ax25 route add" command */
if((m->user = socket(AF_AX25,SOCK_STREAM,0)) == -1)
return -1;
len = sizeof(*sp.ax);
break;
#endif /* AX25 */
#ifdef NETROM
case 'n':
sp.nr->nr_family = AF_NETROM;
len = sizeof(*sp.nr);
if((m->user = socket(AF_NETROM,SOCK_SEQPACKET,0)) == -1)
return -1;
memcpy(sp.nr->nr_addr.user,Nr4user,AXALEN);
memcpy(sp.nr->nr_addr.node,Mycall,AXALEN);
bind(m->user,sp.p,len);
/* See if the requested destination could be an alias, and
* use it if it is. Otherwise assume it is an AX.25
* address.
*/
if (putalias(alias,argv[1],0) != -1 &&
(np = find_nralias(alias)) != NULLCHAR) {
memcpy(sp.nr->nr_addr.user,np,AXALEN) ;
memcpy(sp.nr->nr_addr.node,np,AXALEN) ;
}
else { /* parse ax25 callsign */
/* Only the user callsign of the remote station is never
* used by NET/ROM, but it is needed for the psocket() call.
*/
setcall(sp.nr->nr_addr.user,argv[1]);
setcall(sp.nr->nr_addr.node,argv[1]);
}
break;
#endif /* NETROM */
default:
return -1;
}
sockmode(m->user,SOCK_ASCII);
if(connect(m->user,sp.p,len) == -1) {
log(m->user,"MBOX forward failed: %s errno %d",
sockerr(m->user),errno);
close_s(m->user);
return -1;
}
return m->user;
}