/* cat > ./ax_mbx.c << '\Rogue\Monster\' */ #include #include #include #include "global.h" #include "mbuf.h" #include "ax25.h" #include "timer.h" #include "iface.h" #include "lapb.h" #include "ax_mbx.h" #include "cmdparse.h" static char mbbanner[] = "Welcome to the %s TCP/IP Mailbox\r" ; static char mbmenu[] = "(C)hat, (S)end, (B)ye > " ; void mbx_incom(axp,cnt) register struct ax25_cb *axp ; int16 cnt ; { struct mbx *m ; struct mbuf *bp, *recv_ax25() ; char *cp ; extern char hostname[] ; void mbx_rx(), mbx_state() ; extern char *index() ; if ((m = (struct mbx *)calloc(1,sizeof(struct mbx))) == NULLMBX) { disc_ax25(axp) ; /* no memory! */ return ; } m->state = MBX_CMD ; /* start in command state */ m->ax25_cb = axp ; pax25(m->name,&axp->addr.dest) ; cp = index(m->name,'-') ; if (cp != NULLCHAR) /* get rid of SSID */ *cp = '\0' ; m->lp = m->line ; /* point line pointer at buffer */ axp->r_upcall = mbx_rx ; axp->s_upcall = mbx_state ; axp->user = (char *)m ; /* The following is necessary because we didn't know we had a */ /* "real" ax25 connection until a data packet came in. We */ /* can't be spitting banners out at every station who connects, */ /* since they might be a net/rom or IP station. Sorry. */ bp = recv_ax25(axp,cnt) ; /* get the initial input */ free_p(bp) ; /* and throw it away to avoid confusion */ /* Now say hi */ if ((bp = alloc_mbuf(strlen(hostname) + strlen(mbbanner) + 2)) == NULLBUF) { disc_ax25(axp) ; /* mbx_state will fix stuff up */ return ; } *bp->data = PID_FIRST | PID_LAST | PID_NO_L3 ; /* pid */ bp->cnt = sprintf(bp->data+1,mbbanner,hostname) + 1 ; send_ax25(axp,bp) ; /* send greeting message */ (void)mbx_msg(axp, mbmenu) ; /* send initial menu prompt */ } /* mbx_rx collects lines, and calls mbx_line when they are complete. */ /* If the lines get too long, it arbitrarily breaks them. */ void mbx_rx(axp,cnt) struct ax25_cb *axp ; int16 cnt ; { struct mbuf *bp, *recv_ax25() ; struct mbx *m ; char c ; int mbx_line() ; m = (struct mbx *)axp->user ; if ((bp = recv_ax25(axp,cnt)) == NULLBUF) return ; while (pullup(&bp,&c,1) == 1) { if (c == '\r') { *m->lp = '\0' ; /* null terminate */ if (mbx_line(m) == -1) { /* call the line processor */ free_p(bp) ; /* toss the rest */ break ; /* get out - we're obsolete */ } m->lp = m->line ; /* reset the pointer */ } else if ((m->lp - m->line) == (MBXLINE - 1)) { *m->lp++ = c ; *m->lp = '\0' ; if (mbx_line(m) == -1) { free_p(bp) ; break ; } m->lp = m->line ; } else *m->lp++ = c ; } } void mbx_state(axp,old,new) struct ax25_cb *axp ; int old, new ; { struct mbx *m ; void free_mbx() ; m = (struct mbx *)axp->user ; /* dummy for now ... */ if (new == DISCONNECTED) { axp->user = NULLCHAR ; free_mbx(m) ; } } static void free_mbx(m) struct mbx *m ; { if (m->to != NULLCHAR) free(m->to) ; if (m->tfile != NULLFILE) fclose(m->tfile) ; free(m) ; } static mbx_line(m) struct mbx *m ; { void ax_session() ; char *host ; extern char hostname[] ; char fullfrom[80] ; if (m->state == MBX_CMD) { switch (tolower(m->line[0])) { case 'b': /* bye - bye */ disc_ax25(m->ax25_cb) ; return -1 ; /* tell line processor to quit */ break ; case 'c': /* chat */ m->ax25_cb->user = NULLCHAR ; ax_session(m->ax25_cb,0) ; /* make it a chat session */ free_mbx(m) ; return -1 ; break ; case 's': if (mbx_to(m) == -1) { mbx_msg(m->ax25_cb, "Bad address - try 'S name' or 'S name@host'\r") ; mbx_msg(m->ax25_cb,mbmenu) ; } else { m->state = MBX_SUBJ ; mbx_msg(m->ax25_cb,"Subject: ") ; } break ; default: mbx_msg(m->ax25_cb,"Huh?\r") ; mbx_msg(m->ax25_cb,mbmenu) ; } return 0 ; } else if (m->state == MBX_SUBJ) { if (mbx_data(m) == -1) { mbx_msg(m->ax25_cb,"Can't create temp file for mail\r") ; mbx_msg(m->ax25_cb,mbmenu) ; free(m->to) ; m->to = NULLCHAR ; m->state = MBX_CMD ; return 0 ; } m->state = MBX_DATA ; mbx_msg(m->ax25_cb, "Enter message. Terminate with '.' alone in first column:\r") ; return 0 ; } else if (m->state == MBX_DATA) { if (m->line[0] == '.' && m->line[1] == '\0') { if ((host = index(m->to,'@')) == NULLCHAR) host = hostname ; /* use our hostname */ else host++ ; /* use the host part of address */ /* make up full from name for work file */ sprintf(fullfrom,"%s@%s",m->name,hostname) ; fseek(m->tfile,0L,0) ; /* reset to beginning */ if (queuejob((void *)0,m->tfile,host,m->to,fullfrom) != 0) mbx_msg(m->ax25_cb, "Couldn't queue message for delivery\r") ; free(m->to) ; m->to = NULLCHAR ; fclose(m->tfile) ; m->tfile = NULLFILE ; m->state = MBX_CMD ; mbx_msg(m->ax25_cb, mbmenu) ; return 0 ; } /* not done yet! */ fprintf(m->tfile,"%s\n",m->line) ; return 0 ; } } /* send text msg to ax.25 session axp */ static mbx_msg(axp,msg) struct ax25_cb *axp ; char msg[] ; { int len ; struct mbuf *bp ; len = strlen(msg) ; if ((bp = alloc_mbuf(len+1)) == NULLBUF) { disc_ax25(axp) ; return -1 ; } bp->cnt = len + 1 ; *bp->data = PID_FIRST | PID_LAST | PID_NO_L3 ; memcpy(bp->data+1, msg, len) ; send_ax25(axp,bp) ; return 0 ; } /* Prepare the addressee. If the address is bad, return -1, otherwise * return 0 */ static mbx_to(m) struct mbx *m ; { register char *cp, *cp1 ; cp = m->line ; while (!isspace(*cp)) /* skip the Send command */ if (*cp == '\0') /* also stop for NULLs */ break ; else cp++ ; /* try next character ... */ if (*cp == '\0') /* no address here */ return -1 ; while (isspace(*cp)) /* now skip the white space */ if (*cp == '\0') break ; else cp++ ; if (*cp == '\0') /* no address here */ return -1 ; cp1 = cp ; while (!isspace(*cp1)) /* now find end of arg */ if (*cp1 == '\0') break ; else cp1++ ; *cp1 = '\0' ; /* null terminate the arg */ /* if (checkaddress(cp) == 0) */ /* see how this address looks */ /* return -1 ; */ /* oops */ if ((m->to = malloc(strlen(cp) + 1)) == NULLCHAR) return -1 ; /* no room for address */ strcpy(m->to,cp) ; /* copy address */ return 0 ; } /* This opens the data file and writes the mail header into it. * Returns 0 if OK, and -1 if not. */ static mbx_data(m) struct mbx *m ; { long t, time(); /* DG2KK: was: time_t */ char *ptime() ; extern char hostname[] ; extern FILE *tmpfile(); extern long get_msgid() ; if ((m->tfile = tmpfile()) == NULLFILE) return -1 ; time(&t) ; fprintf(m->tfile,"Date: %s",ptime(&t)) ; fprintf(m->tfile,"Message-Id: <%ld@%s>\n",get_msgid(),hostname) ; fprintf(m->tfile,"From: %s@%s\n",m->name,hostname) ; fprintf(m->tfile,"To: %s\n",m->to) ; fprintf(m->tfile,"Subject: %s\n\n",m->line) ; return 0 ; } queuejob() { }