/* The are the MAILCMDS */
#include <time.h>
#include <ctype.h>
#ifdef MSDOS
#include <alloc.h>
#endif
#ifdef  UNIX
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include "global.h"
#ifdef MAILCMDS
#include "timer.h"
#include "proc.h"
#include "socket.h"
#include "usock.h"
#include "session.h"
#include "smtp.h"
#include "dirutil.h"
#include "telnet.h"
#include "ftp.h"
#include "ftpserv.h"
#include "commands.h"
#include "netuser.h"
#include "files.h"
#include "bm.h"
#include "pktdrvr.h"
#include "ax25.h"
#include "mailbox.h"
#include "mailutil.h"
#include "ax25mail.h"
#include "nr4mail.h"
#include "cmdparse.h"
#include "mailfor.h"
  
/* By setting the fp to NULL, we can check in exitbbs()
 * wether a tempfile has been closed or not - WG7J
 */
#define MYFCLOSE(x) { fclose(x); x = (FILE *) 0; }
  
char CcLine[] = "Cc: ";
char Mbwarning[] = "Third Party mail is not permitted.\n";
char InvalidNameChars[] = "?*<>[],;:+=\"";
  
int MbSent;
int MbRead;
int MbRecvd;
  
#ifdef MBFWD
int MbForwarded;
extern char *Mbhaddress;
#else
#define Mbhaddress NULL
#endif
  
int
dosid(argc,argv,p)
int argc;
char *argv[];
void *p;
{
    struct mbx *m;
    char *cp;
  
    m = (struct mbx *)p;
    if((argc == 1) || (argv[1][strlen(argv[1]) - 1] != ']')) /* must be an SID */
        return 1;
#ifdef notdef
    if(m->stype == 'Z' && strncmp(argv[1],"cz",2) == 0) {
        /* LAN-LINK's [ZCZ] */
        m->sid |= MBX_LL;
        return 0;
    }
#endif
    /* Other bbs's */
    m->sid |= MBX_SID;
  
    /* Now check to see if this is an RLI board.
     * As usual, Hank does it a bit differently from
     * the rest of the world.
     */
    if(m->stype == 'R' && strncmp(argv[1],"li",2) == 0)/* [RLI] at a minimum */
        m->sid |= MBX_RLI_SID;
    /* Or maybe it is F6FBB ? */
    else if(m->stype == 'F')
        m->sid |= MBX_FBB;
    /* Check to see if the BBS supports a kludge called "hierarchical
     * routing designators."
     *
     * No need to check for ']' -- it must be there or this is not
     * a valid mbox id -- it is checked earlier (fix de OH3LKU)
     *
     * Sid format is [BBSTYPE-VERSION-OPTIONS]
     * check for LAST -, to allow for version portion. - WG7J
     */
    if((cp = strrchr(argv[1],'-')) != NULLCHAR) {
        cp++;
    /* Okay, now parse the options */
        if((strchr(cp,'h') != NULLCHAR) && (strchr(cp,'$') != NULLCHAR))
            m->sid |= MBX_HIER_SID;
        if(strchr(cp,'m') != NULLCHAR)
            m->sid |= MBX_MID;
#if defined(MBFWD) && defined(FBBFWD)
        if(Mfbb)
           if(strchr(cp,'f') != NULLCHAR)
               m->sid |= MBX_FBBFWD;
#endif
#if defined(MBFWD) && defined(FBBCMP)
        if(Mfbb==2 && !(m->sid&MBX_FOREGO_FBBCMP))
           if(strchr(cp,'b') != NULLCHAR)
               m->sid |= MBX_FBBCMP;
#endif
    }
    return 0;
}
  
int
doarea(argc,argv,p)
int argc;
char *argv[];
void *p;
{
    struct mbx *m;
    FILE *fp;
    int cnt;
    char buf[MBXLINE];
  
    m = (struct mbx *) p;
  
    if(argc < 2){
#ifdef USERLOG
        if(m->stype == 'N') {
            listnewmail(m,0);
            return 0;
        }
#endif
        tprintf("Current message area is: %s\n\n",m->area);
        tprintf("Available areas are:\n\n%-10s",m->name);
        if(m->stype == 'F')
            tputs("  Your private mail area\n");
        else
            tputc('\n');
        if((fp = fopen(Arealist,READ_TEXT)) == NULLFILE)
            return 0;
        if(m->stype == 'F')
            sendfile(fp,m->user,ASCII_TYPE,0,m);
        else {
            /* send only the area names, not the description.  Multi-columns by WA7TAS */
            cnt=0;
            while(fgets(buf,MBXLINE,fp) != NULLCHAR) {
                if(buf[0] != '#') { /* skip comments */
                    firsttoken(buf);
                    tprintf("%-10s",buf);
                    if(++cnt > 5 ) {
                        cnt=0;
                        tprintf("\n");
                    }
                }
            }
            if(cnt) tprintf("\n");
            tputs("\nType AF to get description of areas.\nAF <name> tells more about that area.\n\n");
        }
        fclose(fp);
        return 0;
    } else {
        dotformat(argv[1]);
//#ifdef AREADOCS
        if(m->stype == 'F' && isarea(argv[1])) { /* AF areaname => display areaname.doc */
            dirformat(argv[1]);
            sprintf(buf, "%s/%s.doc", Mailspool, argv[1]);
            if ((fp = fopen(buf, READ_TEXT)) != NULLFILE) {
                sendfile(fp,m->user,ASCII_TYPE,0,m);
                fclose(fp);
            }
            else tputs("No additional info found.\n");
        } else
//#endif /* AREADOCS */
        if(!strcmp(m->name,argv[1]) || isarea(argv[1]) ||
           ((m->privs&SYSOP_CMD) && strpbrk(argv[1],InvalidNameChars)==NULLCHAR
            && *(argv[1]+strlen(argv[1])-1)!='.' )){
            changearea(m,argv[1]);
            if(m->areatype == PRIVATE)
                tputs("You have ");
            else
                tprintf("%s: ",m->area);
            if(m->nmsgs){
#ifdef USERLOG
                tprintf("%d message%s -  %d new.\n",m->nmsgs,
                m->nmsgs == 1 ? " " : "s ", m->newmsgs);
#else
                if(m->areatype == PRIVATE)
                    tprintf("%d message%s -  %d new.\n", m->nmsgs,
                    m->nmsgs == 1 ? " " : "s ", m->newmsgs);
                else
                    tprintf("%d message%s.\n", m->nmsgs,
                    m->nmsgs == 1 ? "" : "s");
#endif
            } else
                tputs("0 messages.\n");
        } else
            tprintf("No such message area: %s\n",argv[1]);
    }
    return 0;
}
  
/* subroutine to do the actual switch from one area to another */
/* USERLOGGING added by WG7J */
void
changearea(m,area)
struct mbx *m;
char *area;
{
    if (m->area[0]) {    /* current area non-null? */
#ifdef USERLOG
        setlastread(m);
#endif
        closenotes(m);
    }
    dotformat(area);
    strcpy(m->area,area);
    /* Check areas first, so regular users loging in with areaname
     * cannot gain permission to kill messages in areas
     * (if univperm in ftpusers doesn't allow that)
     */
    m->areatype = USER;
    if (m->area[0]) {  /* non-null area name */
        if(isarea(area))
            m->areatype = AREA;
        else if(!strcmp(m->name,area))
            m->areatype = PRIVATE;
        /* else was Sysop checking someone else's area; leave areatype==USER */
        
  
#ifdef USERLOG
        /* only read last read message-id if this IS a bbs, or
         * current area is a public area and not 'help'
         * or area starts with 'sys' or we have (sysop or no_lastread) privs.
         */
        if((m->sid & MBX_SID) ||
#ifdef FWDFILE
            m->family == AF_FILE ||
#endif
            (strcmp(area,"help") && m->areatype == AREA) ||
            !strncmp(m->area,"sys",3) ||
            (m->privs & (SYSOP_CMD|NO_LASTREAD)) )
                getlastread(m);
#endif
  
        scanmail(m);
    }
}
  
/* States for send line parser state machine */
#define         LOOK_FOR_USER           2
#define         IN_USER                 3
#define         AFTER_USER              4
#define         LOOK_FOR_HOST           5
#define         IN_HOST                 6
#define         AFTER_HOST              7
#define         LOOK_FOR_FROM           8
#define         IN_FROM                 9
#define         AFTER_FROM              10
#define         LOOK_FOR_MSGID          11
#define         IN_MSGID                12
#define         FINAL_STATE             13
#define         ERROR_STATE             14
  
/* Prepare the addressee.  If the address is bad, return -1, otherwise
 * return 0
 */
int
mbx_to(argc,argv,p)
int argc;
char *argv[];
void *p;
{
    char *cp;
    int state, i;
    char *user, *host, *from, *msgid;
    int userlen = 0, hostlen = 0, fromlen = 0, msgidlen = 0;
    struct mbx *m;
  
    m = (struct mbx *)p;
    /* Free anything that might be allocated
     * since the last call to mbx_to() or mbx_reply()
     */
    free(m->to);
    m->to = NULLCHAR;
    free(m->tofrom);
    m->tofrom = NULLCHAR;
    free(m->tomsgid);
    m->tomsgid = NULLCHAR;
    free(m->origto);
    m->origto = NULLCHAR;
    free(m->origbbs);
    m->origbbs = NULLCHAR;
    free(m->subject);
    m->subject = NULLCHAR;
    free(m->date);
    m->date = NULLCHAR;
  
    if(argc == 1)
        return -1;
    i = 1;
    cp = argv[i];
    state = LOOK_FOR_USER;
    while(state < FINAL_STATE){
#ifdef MBDEBUG
        tprintf("State is %d, char is %c\n", state, *cp);
#endif
        switch(state){
            case LOOK_FOR_USER:
                if(*cp == '@' || *cp == '<' || *cp == '$'){
                    state = ERROR_STATE;            /* no user */
                } else {
                    user = cp;                      /* point at start */
                    userlen++;                      /* start counting */
                    state = IN_USER;
                }
                break;
            case IN_USER:
            switch(*cp){
                case '\0':
                    state = AFTER_USER;             /* done with username */
                    break;
                case '@':
                    state = LOOK_FOR_HOST;          /* hostname should follow */
                    break;
                case '<':
                    state = LOOK_FOR_FROM;          /* from name should follow */
                    break;
                case '$':
                    state = LOOK_FOR_MSGID; /* message id should follow */
                    break;
                default:
                    userlen++;                      /* part of username */
            }
                break;
            case AFTER_USER:
            switch(*cp){
                case '@':
                    state = LOOK_FOR_HOST;          /* hostname follows */
                    break;
                case '<':
                    state = LOOK_FOR_FROM;          /* fromname follows */
                    break;
                case '$':
                    state = LOOK_FOR_MSGID; /* message id follows */
                    break;
                default:
                    state = ERROR_STATE;
            }
                break;
            case LOOK_FOR_HOST:
                if(*cp == '@' || *cp == '<' || *cp == '$'){
                    state = ERROR_STATE;
                    break;
                }
                if(*cp == '\0')
                    break;
                host = cp;
                hostlen++;
                state = IN_HOST;
                break;
            case IN_HOST:
            switch(*cp){
                case '\0':
                    state = AFTER_HOST;             /* found user@host */
                    break;
                case '@':
                    state = ERROR_STATE;            /* user@host@? */
                    break;
                case '<':
                    state = LOOK_FOR_FROM;          /* fromname follows */
                    break;
                case '$':
                    state = LOOK_FOR_MSGID; /* message id follows */
                    break;
                default:
                    hostlen++;
            }
                break;
            case AFTER_HOST:
            switch(*cp){
                case '@':
                    state = ERROR_STATE;            /* user@host @ */
                    break;
                case '<':
                    state = LOOK_FOR_FROM;          /* user@host < */
                    break;
                case '$':
                    state = LOOK_FOR_MSGID; /* user@host $ */
                    break;
                default:
                    state = ERROR_STATE;            /* user@host foo */
            }
                break;
            case LOOK_FOR_FROM:
                if(*cp == '@' || *cp == '<' || *cp == '$'){
                    state = ERROR_STATE;
                    break;
                }
                if(*cp == '\0')
                    break;
                from = cp;
                fromlen++;
                state = IN_FROM;
                break;
            case IN_FROM:
            switch(*cp){
                case '\0':
                    state = AFTER_FROM;             /* user@host <foo */
                    break;
                case '<':
                    state = ERROR_STATE;            /* user@host <foo< */
                    break;
                case '$':
                    state = LOOK_FOR_MSGID; /* message id follows */
                    break;
                default:
                    fromlen++;
            }
                break;
            case AFTER_FROM:
            switch(*cp){
                case '@':                               /* user@host <foo @ */
                case '<':                               /* user@host <foo < */
                    state = ERROR_STATE;
                    break;
                case '$':
                    state = LOOK_FOR_MSGID; /* user@host <foo $ */
                    break;
                default:
                    state = ERROR_STATE;            /* user@host foo */
            }
                break;
            case LOOK_FOR_MSGID:
                if(*cp == '\0')
                    break;
                msgid = cp;
                msgidlen++;
                state = IN_MSGID;
                break;
            case IN_MSGID:
                if(*cp == '\0')
                    state = FINAL_STATE;
                else
                    msgidlen++;
                break;
            default:
            /* what are we doing in this state? */
                state = ERROR_STATE;
        }
        if(*(cp) == '\0'){
            ++i;
            if(i < argc)
                cp = argv[i];
            else break;
        } else
            ++cp;
    }
    if(state == ERROR_STATE || state == LOOK_FOR_HOST
        || state == LOOK_FOR_FROM || state == LOOK_FOR_MSGID)
        return -1;              /* syntax error */
  
    m->to = mallocw((unsigned)userlen + hostlen + 2);
  
    strncpy(m->to, user, (unsigned)userlen);
    m->to[userlen] = '\0';
  
    if(hostlen){
        m->to[userlen] = '@';
        strncpy(m->to + userlen + 1, host, (unsigned)hostlen);
        m->to[userlen + hostlen + 1] = '\0';
    }
    if(fromlen){
        m->tofrom = mallocw((unsigned)fromlen + 1);
        strncpy(m->tofrom, from, (unsigned)fromlen);
        m->tofrom[fromlen] = '\0';
    }
    if(msgidlen){
        m->tomsgid = mallocw((unsigned)msgidlen + 1);
        strncpy(m->tomsgid, msgid, (unsigned)msgidlen);
        m->tomsgid[msgidlen] = '\0';
#ifdef FBBFWD
        if(strncmp(m->tomsgid, "fbbbid",6) == 0) {
            m->origto = mallocw((unsigned)msgidlen + 1 - 7);
            strcpy(m->origto, &msgid[7]);
            cp = strstr(m->origto,"->");
            *cp = '\0';
        }
#endif
    }
    return 0;
}
  
/* This opens the data file and writes the mail header into it.
 * Returns 0 if OK, and -1 if not.
 */
int
mbx_data(m,cclist,extra)
struct mbx *m;
struct list *cclist;    /* list of carbon copy recipients */
char *extra;        /* optional extra header lines */
{
    time_t t;
    struct list *ap;
    int cccnt = 0;
  
#ifdef notdef
    time(&t);
    /*These 2 lines get added again when the smtp-server handles the mail
     *not really needed - WG7J
     */
    fprintf(m->tfile,Hdrs[RECEIVED]);
    if(m->tofrom != NULLCHAR)
        fprintf(m->tfile,"from %s ",m->name);
    fprintf(m->tfile,"by %s (%s)\n\tid AA%ld ; %s",
    Hostname, Version, get_msgid(),ptime(&t));
#endif
  
    /* If m->date is set, use this one (comes from bbs-forwarded mail) */
    time(&t);
    if(m->date != NULLCHAR) {
        fprintf(m->tfile,"%s%s",Hdrs[DATE],m->date);
#ifdef RLINE
        if(Rholdold && m->stype=='B' &&
          (t - mydate(m->date)) > 86400L*Rholdold)  /* too old? */
            fprintf(m->tfile, "%sAge\n", Hdrs[XBBSHOLD]);
#endif
    }
    else {
        fprintf(m->tfile,"%s%s",Hdrs[DATE],ptime(&t));
    }
  
    /* Bulletin ID, if any */
    fprintf(m->tfile,Hdrs[MSGID]);
    if(m->tomsgid)
        fprintf(m->tfile,"<%s@%s.bbs>\n", m->tomsgid, m->name);
    else
  
        fprintf(m->tfile,"<%ld@%s>\n",get_msgid(), Hostname);
  
    /* From : , could use 'real bbs address', if origbbs is set */
    fprintf(m->tfile,Hdrs[FROM]);
    if(m->tofrom) {  /* BBS style '< call' */
        if(m->origbbs != NULLCHAR)
            fprintf(m->tfile,"%s@%s\n",m->tofrom,m->origbbs);
        else
            fprintf(m->tfile,"%s%%%s.bbs@%s\n",m->tofrom, m->name, Hostname);
    } else {
        if(m->origbbs != NULLCHAR)
            fprintf(m->tfile,"%s@%s\n",m->name,m->origbbs);
        else {
            int found = 0;
            char *cp,*cp2;
            FILE *fp;
            char line[128];
  
            if((fp = fopen(Pdbase,READ_TEXT)) != NULLFILE) {
                while(fgets(line,128,fp) != NULLCHAR) {
                    rip(line);
                    cp = skipwhite(line);
                    if(*cp == '#')
                        continue;
                    /* Now find end of fist entry */
                    cp2 = cp;
                    while(*cp2 && *cp2 != ' ' && *cp2 != '\t')
                        cp2++;
                    if(*cp2 == '\0') /* No additional data */
                        continue;
                    *cp2 = '\0';    /* terminate first entry */
                    if(!stricmp(cp,m->name)) {
                        /* Found one, now get the name */
                        cp = skipwhite(++cp2);
                        if(*cp) {
                            found = 1;
                            fprintf(m->tfile,"%s <%s@%s>\n",cp,m->name,Hostname);
                        }
                    }
                }
                fclose(fp);
            }
            if(!found)
                fprintf(m->tfile,"%s@%s\n",m->name,Hostname);
        }
    }
  
#if defined USERLOG && defined REGISTER
    if((m->sid & MBX_REPLYADDR) && m->IPemail)
        fprintf(m->tfile,"%s%s\n",Hdrs[REPLYTO],m->IPemail);
#endif /* REPLY-TO HEADER */
  
    fprintf(m->tfile,"%s%s\n",Hdrs[TO],m->origto != NULLCHAR ? m->origto : m->to);
  
    /* Write Cc: line */
    for(ap = cclist; ap != NULLLIST; ap = ap->next) {
        if(cccnt == 0){
            fprintf(m->tfile,"%s",Hdrs[CC]);
            cccnt = 4;
        }
        else {
            fprintf(m->tfile,", ");
            cccnt += 2;
        }
        if(cccnt + strlen(ap->val) > 80 - 3) {
            fprintf(m->tfile,"\n    ");
            cccnt = 4;
        }
        fputs(ap->val,m->tfile);
        cccnt += strlen(ap->val);
    }
    if(cccnt)
        fputc('\n',m->tfile);
    fprintf(m->tfile,"%s%s\n",Hdrs[SUBJECT],m->subject);
    if(!isspace(m->stype) && ((m->stype != 'R' && m->stype != 'F') ||
        (m->sid & MBX_SID) !=0))
        fprintf(m->tfile,"%s%c\n", Hdrs[BBSTYPE],m->stype);
  
#ifdef notdef
    /*not really needed, the 'From <user%fwdbbs@host>' shows this too!*/
    /* Also store the 'real smtp from' address */
    if((m->tofrom != NULLCHAR) && (m->origbbs != NULLCHAR))
        fprintf(m->tfile,"%s%s%%%s@%s\n",Hdrs[XFROM],m->tofrom,m->name, Hostname);
#endif
  
    if(extra != NULLCHAR)
        fprintf(m->tfile,extra);
  
    return 0;
}
  
/* Returns true if string is in history file or if string appears to be a
 * message id generated by our system.
 */
int
msgidcheck(string)
char *string;
{
    FILE *fp;
    char *cp,buf[LINELEN];
  
    if(string == NULLCHAR)
        return 0;
  
    /* BID's that we have generated ourselves are not kept in the history
     * file. Such BID's are in the nnnnn_hhhhhh form, where hhhhhh is a part of
     * our hostname or mbHaddress, truncated at the first period so that the
     * BID is no longer than 12 characters.  [see makecl() in forward.c]
     */

    if((cp = strchr(string,'_')) != NULLCHAR && *(cp+1) != '\0' &&
        strnicmp(cp+1,(Mbhaddress?Mbhaddress:Hostname),strlen(cp+1)) == 0
        && *((Mbhaddress?Mbhaddress:Hostname)+strlen(cp+1)) == '.'
        && strspn(string,"0123456789") == (cp-string) )
        return 1;

    if((fp = fopen(Historyfile,READ_TEXT)) == NULLFILE)
        return 0;
    setvbuf(fp, NULLCHAR, _IOFBF, 2048);       /* N5KNX: use bigger input buffer if possible */

    while(fgets(buf,LINELEN,fp) != NULLCHAR) {
        firsttoken(buf);
        if(stricmp(string,buf) == 0) {    /* found */
            fclose(fp);
            return 1;
        }
    }
    fclose(fp);
    return 0;
}
  
#ifdef MBFWD
int
storebid(bid)
char *bid;
{
    long now;
    FILE *fp;
    int i;

    /* Save it in the history file - WG7J */
    /* n5knx: lock it first.  Competition from makecl() and Oldbidtick() ... */
    for (i=30; i>0; i--) {  /* try to lock bid History file */
        if(!mlock(Historyfile,NULLCHAR)) break;
        pause(2000L);
    }
    if (i) {
        if ((fp = fopen(Historyfile,APPEND_TEXT)) != NULLFILE) {
            /* Timestamp added to allow automatic expiry of bid file - WG7J */
            time(&now);
            fprintf(fp,"%s %ld\n",bid,now); /* Save BID */
            fclose(fp);
        }
        else i=0;  /* open error */
        (void)rmlock(Historyfile,NULLCHAR);
    }
    return i;  /* 0 => unable to store bid */
}
#endif /* MBFWD */

/* Attempt to determine if this is third-pary mail. */
int
thirdparty(m)
struct mbx *m;
{
    char buf[MBXLINE], *cp, *rp;
    FILE *fp;
  
    if(strpbrk(m->to,"@%!") != NULLCHAR)
        return 0;
  
    rp = strdup(Hostname);
  
    if((cp = strchr(rp, '.')) != NULLCHAR)
        *cp = '\0';
  
    if(stricmp(m->to,rp) == 0){
        free(rp);
        return -1;
    }
    free(rp);
  
    if(stricmp(m->to,"sysop") == 0)
        return -1;
  
    if((fp = fopen(Arealist,READ_TEXT)) == NULLFILE)
        return 0;
  
    while(fgets(buf,MBXLINE,fp) != NULLCHAR){
        /* The first word on each line is all that matters */
        firsttoken(buf);
        if(stricmp(m->to,buf) == 0){
            fclose(fp);
            return -1;
        }
    }
    fclose(fp);
    return 0;
}
  
/* Move messages from current area to another */
int
dombmovemail(argc,argv,p)
int argc;
char *argv[];
void *p;
{
    long pos;
    int num,i;
    int move[NARG];
    char *to;
    struct mbx *m;
    FILE * Mfile;           /* file to move to */
    int not_area;           /* is to-file an area or a regular file? */
    struct let *cmsg;
    int thisone=0;
    int start;
    int end;
    char *area;
    struct mailindex ind;
    char buf[MBXLINE];
  
    m = (struct mbx *)p;
  
    if(argc == 1) {
        tputs("Syntax: MM area - moves current message\n"
        "        MM n1 [n2...] [n3-n4] area - move message n1 (n2...) (n3 to n4)\n");
        return 0;
    }
    if(argc == 2) {
        /* NO message #, use current message */
        num = 1;
        to = argv[1];
        move[0] = m->current;
    } else {
        /* n5knx: to specify a range, put start and (-end) into the move[] array */
        num=0;
        for(i=1; i<argc-1 && num<NARG; i++) {  /* scan all but last arg (the destination) */
            start = atoi(argv[i]);
            if(start < 1 || start > m->nmsgs) {
                tprintf(Badmsg,start);
                continue;
            }
            move[num++] = start;
            to = strchr(argv[i],'-'); /* N5KNX: allow from-to msg specification */

            if (to != NULLCHAR && num<NARG) {
                end = atoi(++to);
                if (end < start || end > m->nmsgs) {
                    tprintf(Badmsg,end);
                    num--;
                    continue;
                }
                move[num++] = -end;
            }
        }
        to = argv[argc-1];
    }

#ifdef UNIX  
    if (*to == '/') {  /* not area if begins with slash */
#else
    if (*to == '/' || *to == '\\' || *(to+1) == ':') {  /* not area if begins with slash or drive spec */
#endif
        not_area=1;
        strncpy(buf, to, sizeof(buf));  buf[sizeof(buf)-1] = '\0';
    }
    else {
        int c;

        not_area=0;
        dotformat(to);
        if (!isarea(to)) {
            tprintf("%s is not a public area... Are you sure? ",to);
            if(charmode_ok(m))
                c = tkeywait("Move(N=no)?",0,
                        (int)(OPT_IS_DEFINED(m,TN_LINEMODE)&OPT_IS_SET(m,TN_LINEMODE)));
            else  /* For AX.25 and NET/ROM connects */
                c = mykeywait("Move(N=No)?",m);
            if(c == -1 || c == 'n' || c == 'N') {
                tputs("Aborted.\n");
                return 0;
            }
        } /* endif */
        dirformat(to);

        /* Now try to lock the destination file */
        if(mlock(Mailspool,to) == -1) {
            tprintf("Can't lock '%s', please try later\n",to);
            return 0;
        }
        sprintf(buf,"%s/%s.txt",Mailspool,to);
    }
    /* open the destination file for appending, and set file pos for ftell() */
    if( ((Mfile=fopen(buf,"a+")) == NULLFILE) || fseek(Mfile, 0L, SEEK_END)) {
        tprintf("Can't open/seek '%s'\n",buf);
        goto unlock_and_exit;
    }
  
    /* Open the mailbox file for reading */
    area = strdup(m->area);
    dirformat(area);
    sprintf(buf,"%s/%s.txt",Mailspool,area);
    if((m->mfile=fopen(buf,"rt")) == NULLFILE) {
        tprintf("Can't open '%s'\n",buf);
        goto close_unlock_exit;
    }
    memset(&ind,0,sizeof(struct mailindex));
  
    /* Okay, let's do the work */
    for(i=0;i<num;i++) {
        if ((start = move[i]) < 0) {  /* range in progress */
            thisone++;
            if(thisone > -start)
                continue;  /* end of range */
            else
                i--;  /* don't advance the index into move[] array */
        }
        else
            thisone = start;

        cmsg = &m->mbox[thisone];
  
        /* find start of this message */
        fseek(m->mfile,cmsg->start,0);
  
        /* Get the index for this message */
        get_index(thisone,area,&ind);
  
        /* now read this message */
        fgets(buf,MBXLINE,m->mfile);    /* The 'From ' line */
        pos = ftell(Mfile);
        fputs(buf,Mfile);
        while(fgets(buf,MBXLINE,m->mfile)!= NULL) {
            if(!strncmp(buf,"From ",5))
                break;
            /*if(!strnicmp(buf,Hdrs[STATUS],strlen(Hdrs[STATUS]))) continue; * Don't copy a STATUS: R hdr */
            fputs(buf,Mfile);
        }
        if (!not_area) {
            /* Update the index with the new message */
            ind.size = ftell(Mfile) - pos;
            ind.status &= ~BM_READ;  /* mark as not read yet */
            if (write_index(to,&ind) == -1)
                log(m->user, "index update failed for %s", to);
        }
  
        if((m->stype == 'C') || (m->stype == 'c')) {
            tprintf("Message %d copied...\n",thisone);
        } else {
            /* delete this message */
            cmsg->status |= BM_DELETE;
            m->change = 1;
            tprintf("Message %d moved...\n",thisone);
        }
    }
    fclose(m->mfile);
    m->mfile = NULL;

close_unlock_exit:
    fclose(Mfile);
    free(area);
  
unlock_and_exit:
    if(!not_area) rmlock(Mailspool,to);
  
    return 0;
}
  
/*Some additional security - WG7J
 *NO_3PARTY =  disallow all 3rd party mail
 *NO_SENDCMD = only allow mail to sysop
 */
int
dosend(argc,argv,p)
int argc;
char *argv[];
void *p;
{
    int cccnt = 0, fail = 0;
    char *host, *cp, fullfrom[MBXLINE], sigwork[LINELEN], *rhdr = NULLCHAR;
    struct list *ap, *cclist = NULLLIST;
    struct mbx *m;
    FILE *fp;
#ifdef notdef
    time_t now;
#endif
    int done = 0;
    char *cp2;
    int c;
#if defined(EDITOR) && defined(ED) && defined(SEND_EDIT_OK)
    char tmpfname[L_tmpnam+20];
#define S_QUERY "Send(N=no,E=edit)?"
#else
#define S_QUERY "Send(N=no)?"
#endif
  
#ifdef RLINE
    struct tm t;
#define ODLEN   16
#define OBLEN   32
    char tmpline[MBXLINE];
    char fwdbbs[NUMFWDBBS][FWDBBSLEN+1];
    int myfwds = 0;
    int i;
    int zulu=0;
    int check_r = 0;
    int found_r = 0;
    char origdate[ODLEN+1];
    char origbbs[OBLEN+1];
    int loops = 0;
    char Me[15];
  
    origdate[0] = '\0';
    origbbs[0] = '\0';
#endif
  
    m = (struct mbx *)p;
  
    if((m->stype != 'R' || (m->sid & MBX_SID)) && mbx_to(argc,argv,m)
    == -1){
        tputs((m->sid & MBX_SID) ? "NO - syntax error\n" : \
        "S command syntax error - format is:\n" \
        "S[C|F] name [@ host] [< from_addr] [$bulletin_id]\n" \
        "SR [number]\n");
#ifdef MAILERROR
        mail_error("%s: MBOX S syntax error - %s\n",m->name,cmd_line(argc,argv,m->stype));
#endif
        return 0;
    }
  
    /* N5KNX: Only seven chars are legal after the S ... reject any others */
    if(strchr(" BPTCFR", m->stype) == NULLCHAR) {
        tputs((m->sid & MBX_SID) ? "NO - syntax error\n" : \
        "S command syntax error.\n");
#ifdef MAILERROR
        mail_error("%s: MBOX S syntax error - %s\n",m->name,cmd_line(argc,argv,m->stype));
#endif
        return 0;
    }

    /*Check for send permission */
    if(m->privs & NO_SENDCMD) { /*is this to 'SYSOP' or 'sysop' ?*/
        if(m->stype == 'R' || stricmp(m->to,"sysop")) {
            tputs((m->sid & MBX_SID) ? "NO - permission denied\n" : \
            "Sorry, only mail to 'sysop' allowed!\n");
#ifdef MAILERROR
            mail_error("%s: no mail permission - %s\n",m->name,(m->to?m->to:"SR"));
#endif
            return 0;
        }
    }
  
#ifdef FBBFWD
    if(m->tomsgid && strncmp(m->tomsgid, "fbbbid",6) == 0) {
       // This has already been processed by the fbb forwarding code.
       // Swap m->origto and m->to.
       cp        = m->origto;
       m->origto = m->to;
       m->to     = cp;

       // Strip off anything up to and including a "->" on the BID.
       cp        = strstr(m->tomsgid,"->");
       cp++;
       cp++;
       strcpy(m->tomsgid,cp);
#ifdef FBBDEBUG2
       log(m->user,"Sending %s", m->tomsgid);
#endif
    }
    else {
#endif
    /* Check for a BID on bulletins from other bbs's - WG7J */
    if((m->sid & MBX_SID) && !NoBid &&
    (m->stype == 'B') && (m->tomsgid == NULLCHAR)) {
        tputs("NO - No BID!\n");
        log(m->user,"MBOX %s: SB without BID - %s",m->name,m->to);
#ifdef MAILERROR
        mail_error("MBOX %s: SB without BID - %s",m->name,m->to);
#endif
        return 0;
    }
  
    if(m->stype != 'R' && msgidcheck(m->tomsgid)) {
        if(m->sid & MBX_SID)
            tputs("NO - ");
        tprintf("Already have %s\n",m->tomsgid);
        return 0;
    }
    if(m->stype == 'R' && !(m->sid & MBX_SID) &&
    mbx_reply(argc,argv,m,&cclist,&rhdr) == -1) {
        tputs("Can not reply\n");
        return 0;
    }
    if((cp = rewrite_address(m->to,REWRITE_TO)) != NULLCHAR)
        if(strcmp(m->to,cp) != 0){
            free(m->origto);     /* n5knx: in case non-null */
            m->origto = m->to;
            m->to = cp;
        }
        else
            free(cp);
  
    /* refuse any mail that gets rewritten into 'refuse' - WG7J */
    if(!strcmp(m->to,"refuse")) {
        tputs((m->sid & MBX_SID) ? "NO - refused\n" : \
        "Bad user or hostname,  please mail 'sysop' for help\n");
        return 0;
    }
  
    if( (!ThirdParty && !(m->privs & SYSOP_CMD)) || (m->privs & NO_3PARTY) )
        if(thirdparty(m) == 0){
            tputs(Mbwarning);
#ifdef MAILERROR
            mail_error("%s: 3rd party mail refused - %s\n",m->name,m->to);
#endif
            return 0;
        }
  
    /* Send the new 'To:' line to sysops only - WG7J */
    if((m->privs&SYSOP_CMD) && (m->origto != NULLCHAR || m->stype == 'R') \
        && !(m->sid & MBX_SID))
        tprintf("To: %s\n", m->to);
    if(validate_address(m->to) == BADADDR){
        tputs((m->sid & MBX_SID) ? "NO - bad address\n" : \
        "Bad user or hostname,  please mail 'sysop' for help\n");
        free(rhdr);
        del_list(cclist);
        /* We don't free any more buffers here. They are freed upon
         * the next call to mbx_to() or to domboxbye()
         */
        return 0;
    }
#ifdef FBBFWD
    }
#endif
    /* Display the Cc: line (during SR command) */
    for(ap = cclist; ap != NULLLIST; ap = ap->next) {
        if(cccnt == 0){
            tprintf("%s",Hdrs[CC]);
            cccnt = 4;
        }
        else {
            tputs(", ");
            cccnt += 2;
        }
        if(cccnt + strlen(ap->val) > 80 - 3) {
            tputs("\n    ");
            cccnt = 4;
        }
        tputs(ap->val);
        cccnt += strlen(ap->val);
    }
    if(cccnt)
        tputc('\n');
  
    /* If the the command was 'SC' then read the Cc: list now - WG7J */
    if((m->stype == 'C') && !(m->sid & MBX_SID)) {
        m->stype = 'P'; /* make everything private */
        tputs(CcLine);
        if(mbxrecvline(m) != -1) {
            if(strlen(m->line)) {
                if(*m->line == 0x01) { /* CTRL-A, abort */
                    free(rhdr);
                    del_list(cclist);
                    tputs(MsgAborted);
                    return 0;
                }
                cp = m->line;
        /* get all the Cc addresses, separated by commas, tabs or blanks */
                while((cp2=strpbrk(cp,", \t")) != NULLCHAR) { /* Allow , and whitespace separators */
                    *cp2 = '\0';
            /*get rid of leading spaces or tabs*/
                    while(*cp == ' ' || *cp == '\t')
                        cp++;
                    if(strlen(cp))
                        addlist(&cclist,cp,0,NULLCHAR);
                    cp = cp2 + 1;
                }
        /* Do the last or only one */
        /* get rid of leading spaces or tabs*/
                while(*cp == ' ' || *cp == '\t')
                    cp++;
                if(strlen(cp))
                    addlist(&cclist,cp,0,NULLCHAR);
            }
        } else {
            free(rhdr);
            del_list(cclist);
            return 0;
        }
    }
  
    /* Now check to make sure we can create the needed tempfiles - WG7J */
#if defined(EDITOR) && defined(ED) && defined(SEND_EDIT_OK)
    if((m->tfile = fopen(tmpnam(tmpfname),"w+b")) == NULLFILE) {
#else
    if((m->tfile = tmpfile()) == NULLFILE) {
#endif
        free(rhdr);
        del_list(cclist);
/*
    tputs((m->sid & MBX_SID) ? "NO - no temp file\n" : \
        "Can't create temp file for mail\n");
    return 0;
 */
    /* instead of saying NO and have the other bbs think we already
     * have the message, disconnect !
     */
        if(m->sid & MBX_SID)
            return -2;
    /* tell regualr users about it */
        tputs("Can't create temp file for mail\n");
        return 0;
    }
#ifdef RLINE
    /* Only accept R: lines from bbs's */
    if((m->sid & MBX_SID)&&(Rdate || Rreturn || Rfwdcheck || Mbloophold)){
    /* Going to interpret R:headers,
     * we need another tempfile !
     */
        if((m->tfp = tmpfile()) == NULLFILE) {
            free(rhdr);
            del_list(cclist);
            MYFCLOSE(m->tfile);
#if defined(EDITOR) && defined(ED) && defined(SEND_EDIT_OK)
            unlink(tmpfname);  /* since we didn't use tmpfile() */
#endif
/*
        tputs("NO - no temp file\n");
        return 0;
 */
        /* disconnect to avoid the other bbs to think that we already have
         * the message !
         */
            return -2;
        }
    /* Now we got enough :-) */
        check_r = 1;
        Checklock++;
    /* Set the call, used in loop detect code - WG7J */
        if(Mbloophold) {
           strncpy(Me,(Mbhaddress?Mbhaddress:Hostname),sizeof(Me));
           Me[sizeof(Me)-1] = '\0';

           if((cp = strchr(Me,'.')) != NULLCHAR)
              *cp = '\0'; /* use just the callsign */
        }
    }
#endif
  
    m->state = MBX_SUBJ;
    if(m->stype != 'R' || (m->sid & MBX_SID)) {
#ifdef FBBFWD
       if(!(m->sid & MBX_FBBFWD))
          /* Don't display the OK or Subject: tag on FBB forwards */
#endif
        tputs((m->sid & MBX_SID) ? "OK\n" : "Subject:\n");
        if(mbxrecvline(m) == -1) {
#ifdef RLINE
            if(check_r) {
                MYFCLOSE(m->tfp);
                Checklock--;
            }
#endif
            return 0;
        }
    }
    else                            /* Replying to a message */
        tprintf("Subject: %s\n",m->line);
  
    m->subject = strdup(m->line);
  
#ifdef RLINE
    if(!check_r) {
#endif
        mbx_data(m,cclist,rhdr);
    /*Finish smtp headers*/
        fprintf(m->tfile,"\n");
#ifdef RLINE
    }
#endif
    m->state = MBX_DATA;
    if(!(m->sid & MBX_SID) && m->stype != 'F')
        tprintf("Enter message.  %s",Howtoend);
  
    if(m->stype != 'F' || (m->sid & MBX_SID) != 0) {
        while(mbxrecvline(m) != -1){
            if(m->line[0] == 0x01 && !(m->sid & MBX_SID)){  /* CTRL-A */
                MYFCLOSE(m->tfile);
#if defined(EDITOR) && defined(ED) && defined(SEND_EDIT_OK)
                unlink(tmpfname);  /* since we didn't use tmpfile() */
#endif
#ifdef RLINE
                if(check_r)
                    MYFCLOSE(m->tfp);
#endif
                tputs(MsgAborted);
                free(rhdr);
                del_list(cclist);
                return 0;
            }
            if(m->line[0] != CTLZ && stricmp(m->line, "/ex")) {
#ifdef RLINE
                if(check_r) {
            /* Check for R: lines to start with */
                    if(!strncmp(m->line,"R:",2)) { /*found one*/
                        found_r = 1;
            /*Write this line to the second tempfile
             *for later rewriting to the real one
             */
                        fprintf(m->tfp,"%s\n",m->line);
            /* Find the '@[:]CALL.STATE.COUNTRY'or
             * or the '?[:]CALL.STATE.COUNTRY' string
             * The : is optional.
             */
                        if( ((cp=strchr(m->line,'@')) != NULLCHAR) ||
                        ((cp=strchr(m->line,'?')) != NULLCHAR) ) {
                            if((cp2=strpbrk(cp," \t\n")) != NULLCHAR)
                                *cp2 = '\0';
                /* Some bbs's send @bbs instead of @:bbs*/
                            if (*++cp == ':')
                                cp++;
                /* if we use 'return addres'
                 * copy whole 'domain' name
                 */
                            if(Rreturn)
                                if(strlen(cp) <= OBLEN)
                                    strcpy(origbbs,cp);
                /* Optimize forwarding ? */
                            if(Rfwdcheck || Mbloophold) {
                /*if there is a HADDRESS, cut off after '.'*/
                                if((cp2=strchr(cp,'.')) != NULLCHAR)
                                    *cp2 = '\0';
                                if(Mbloophold)
                    /* check to see if this is my call ! */
                                    if(!stricmp(Me,cp))
                                        loops++;
                /*cross-check with MyFwds list*/
                                if(Rfwdcheck) {
                                    for(i=0;i<Numfwds;i++) {
                                        if(!strcmp(MyFwds[i],cp)) {
                        /*Found one !*/
                                            strcpy(fwdbbs[myfwds++],cp);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        if(Rdate) {
                /* Find the 'R:yymmdd/hhmmz' string */
                            if((cp=strchr(m->line,' ')) != NULLCHAR) {
                                *cp = '\0';
                                if(strlen(m->line+2) <= ODLEN)
                                    strcpy(origdate,m->line+2);
                            }
                        }
                    } else {
            /* The previous line was last R: line
             * so we're done checking
             * now write the smtp headers and
             * all saved R: lines to the right tempfile
             */
                        check_r = 0;
                        Checklock--;
            /*Did we actually find one ?*/
                        if(found_r) {
                            if(Rreturn)
                                m->origbbs = strdup(strlwr(origbbs));
                            if(Rdate) {
                                if((cp=strchr(origdate,'/')) != NULLCHAR) {
                                    if((*(cp+5) == 'z') || (*(cp+5) == 'Z')) {
                                        *(cp+5) = '\0';
                                        zulu = 1;
                                    }
                                    t.tm_min = atoi(cp+3);
                                    *(cp+3) = '\0';
                                    t.tm_hour = atoi(cp+1);
                                    *cp = '\0';
                                    t.tm_mday = atoi(&origdate[4]);
                                    origdate[4] = '\0';
                                    t.tm_mon = (atoi(&origdate[2]) - 1);
                                    origdate[2] = '\0';
                                    t.tm_year = atoi(origdate);
                    /* Set the date in rfc 822 format */
                                    if((unsigned)t.tm_mon < 12) {  /* bullet-proofing */
                                        m->date = mallocw(40);
                                        sprintf(m->date,"%.2d %s %02d %02d:%02d:00 %.3s\n",
                                            t.tm_mday, Months[t.tm_mon], t.tm_year,
                                            t.tm_hour, t.tm_min, zulu ? "GMT" : "");
				    }
                                }
                            }
                        }
            /* Now write the headers,
             * possibly adding Xforwarded lines for bulletins,
             * or anything that has a BID.
             * Add the X-Forwarded lines and loop detect
             * headers FIRST,
             * this speeds up forwarding...
             */
                        if(Mbloophold && loops >= Mbloophold)
                            fprintf(m->tfile,"%sLoop\n",Hdrs[XBBSHOLD]);
                        if(Rfwdcheck && found_r && \
                        ((m->stype == 'B') || (m->tomsgid)) ){
                /*write Xforwarded headers*/
                            for(i=0;i<myfwds;i++) {
                                fprintf(m->tfile,"%s%s\n",Hdrs[XFORWARD],fwdbbs[i]);
                            }
                        }
            /*write regular headers*/
                        mbx_data(m,cclist,rhdr);
            /* Finish smtp headers */
                        fprintf(m->tfile,"\n");
  
            /* Now copy the R: lines back */
                        if(found_r) {
                            rewind(m->tfp);
                            while(fgets(tmpline,sizeof(tmpline),m->tfp)!=NULLCHAR)
                                fputs(tmpline,m->tfile);
                        }
                        MYFCLOSE(m->tfp);
  
            /* And add this first non-R: line */
                        fprintf(m->tfile,"%s\n",m->line);
                        if(m->line[strlen(m->line)-1] == CTLZ)
                            goto eol_ctlz;
                    }
                } else
#endif
                    fprintf(m->tfile,"%s\n",m->line);
                if(m->line[strlen(m->line)-1] == CTLZ)
                    goto eol_ctlz;
            } else {
                eol_ctlz:
#ifdef RLINE
                if(check_r) {
            /* Hmm, this means we never finished the R: headers
             * tmp file still open !
             */
                    MYFCLOSE(m->tfp);
                }
#endif
                done = 1; /* To indicate the difference between
               * mbxrecvline() returning -1 and /ex ! - WG7J
               * Now also used to indicate if the message should
               * be sent or not !
               */
        /* Now ask users if they want to send this ! - WG7J */
                if( Mbsendquery && !(m->sid & MBX_SID)) {
repeat_query:
                    if(charmode_ok(m))
                        c = tkeywait(S_QUERY,0,
                            (int)(OPT_IS_DEFINED(m,TN_LINEMODE)&OPT_IS_SET(m,TN_LINEMODE)));
                    else  /* For AX.25 and NET/ROM connects */
                        c = mykeywait(S_QUERY,m);
                    if(c == -1 || c == 'n' || c == 'N') {
                        done = 0;   /* signal delete of message */
                        tputs(MsgAborted);
                    }
#if defined(EDITOR) && defined(ED) && defined(SEND_EDIT_OK)
                    else if (c == 'e' || c == 'E') {
                        char *argv[3];

                        if(m->privs & SYSOP_CMD)
                            argv[1]="--";
                        else
                            argv[1]="-rd";   /* restricted to cmdline filespec */
                        argv[2] = tmpfname;
                        fflush(m->tfile);
                        close(dup(fileno(m->tfile)));  /* set bytecount */
                        /* If we invoke editor directly, it is possible that the
                         * telnet options resulting from tkeywait() will confuse
                         * the first cmd line read in editor(). We thus read one
                         * more line, which consumes telopts so editor is happy.
                         */
                        tputs("Invoking Unix ed(itor); use Q to quit without"
                              " saving changes.\nNow press return to begin:");
                        tflush();
                        if(mbxrecvline(m) != -1)
                            editor(3,argv,m);
                        fseek(m->tfile,0,SEEK_END);  /* be sure at EOF */
                        goto repeat_query;
                    }
#endif
                }
                break;  /* all done */
            }
        }
        if(!done) {
        /* We did NOT get ^Z or /EX, but mbxrecvline returned -1 !!!
         * This means the connection is gone ! - WG7J
         * Now can also mean that the user doesn't want to send msg !
         */
            MYFCLOSE(m->tfile);
#if defined(EDITOR) && defined(ED) && defined(SEND_EDIT_OK)
            unlink(tmpfname);  /* since we didn't use tmpfile() */
#endif
#ifdef RLINE
            if(check_r)
                MYFCLOSE(m->tfp);
#endif
            del_list(cclist);
            free(rhdr); /*Just in case*/
            return 0;
        }
    } else {
        fprintf(m->tfile,"----- Forwarded message -----\n\n");
        msgtofile(m);
        fprintf(m->tfile,"----- End of forwarded message -----\n");
    }
  
    free(rhdr);
    /* Insert customised signature if one is found */
    if(!(m->sid & MBX_SID)) {       /* not a forwarding BBS */
        sprintf(sigwork,"%s/%s.sig",Signature,
        m->tofrom ? m->tofrom : m->name);
        if((fp = fopen(sigwork,READ_TEXT)) != NULLFILE){
            while(fgets(sigwork,LINELEN,fp) != NULLCHAR)
                fputs(sigwork,m->tfile);
            fclose(fp);
        }
    }
  
    if((host = strrchr(m->to,'@')) == NULLCHAR) {
        host = Hostname;        /* use our hostname */
        if(m->origto != NULLCHAR) {
            /* rewrite_address() will be called again by our
             * SMTP server, so revert to the original address.
             */
            free(m->to);
            m->to = m->origto;
            m->origto = NULLCHAR;
        }
    }
    else
        host++; /* use the host part of address */
  
    /* make up full from name for work file */
    if(m->tofrom != NULLCHAR)
        sprintf(fullfrom,"%s%%%s@%s",m->tofrom, (m->origbbs!=NULLCHAR)?m->origbbs:m->name, Hostname);
    else
        sprintf(fullfrom,"%s@%s",m->name,Hostname);
    if(cclist != NULLLIST && stricmp(host,Hostname) != 0) {
        fseek(m->tfile,0L,0);   /* reset to beginning */
        fail = queuejob(m->tfile,Hostname,cclist,fullfrom);
        del_list(cclist);
        cclist = NULLLIST;
    }
    addlist(&cclist,m->to,0,NULLCHAR);
    fseek(m->tfile,0L,0);
    fail += queuejob(m->tfile,host,cclist,fullfrom);
    del_list(cclist);
    MYFCLOSE(m->tfile);
#if defined(EDITOR) && defined(ED) && defined(SEND_EDIT_OK)
    unlink(tmpfname);  /* since we didn't use tmpfile() */
#endif
    if(fail){
        if(!(m->sid & MBX_SID)) /* only when we're not a bbs */
            tputs("Couldn't queue msg!\n");
    } else {
        if(m->sid & MBX_SID)
            MbRecvd++;
        else {
            tputs("Msg queued\n");
            MbSent++;
        }
    /* BID is now saved in the smtp server ! - WG7J */
    }
    /* Instead of kicking off the smtp now, let it happen in a short time.
     * That way the user gets the prompt back immediately, and the smtp kick
     * will run when the user most likely is working on typing the next command.
     * this *should* improve the user's perception of system's speed, and
     * might speed up bbs forwarding a bit too... :-) - WG7J
     */
    {
        #define WAITTM 5000L
        extern struct timer Smtpcli_t;
        int32 t,orig_dur;
  
        stop_timer(&Smtpcli_t);
        orig_dur = Smtpcli_t.duration;
        t = read_timer(&Smtpcli_t);
        if(t <= 0  || t > WAITTM)
            set_timer(&Smtpcli_t,WAITTM);  /* set timer duration */
        if(Smtpcli_t.func == NULL) {    /* in case not set yet */
            Smtpcli_t.func = (void (*)__ARGS((void*)))smtptick;/* what to call on timeout */
            Smtpcli_t.arg = NULL;       /* dummy value */
        }
        start_timer(&Smtpcli_t);        /* and fire it up */
        Smtpcli_t.duration = orig_dur;  /* then back to previous interval */
    }
 #ifdef notdef
    smtptick(NULL);     /* wake SMTP to send that mail */
 #endif
  
    return 0;
}
  
  
#endif /* MAILCMDS */
