Пример #1
0
static char *tmpkname(void)
{
    static char buf[16];

    snprintf(buf,16,"%08x.pkt", sequencer());
    return buf;
}
Пример #2
0
int chatlog_init(char *remname,ftnaddr_t *ra,int side)
{
	FILE *chatlog=NULL;
	time_t tt;struct tm *t;
	char str[MAX_STRING]={0};
	write_log("Chat opened%s",side?" by remote side":"");
	adr=&cfgal(CFG_ADDRESS)->addr;
	if(cfgs(CFG_RUNONCHAT)&&side)execnowait("/bin/sh","-c",ccs,ftnaddrtoa(adr));
	if(cfgi(CFG_CHATLOGNETMAIL)) {
		snprintf(pktname,MAX_PATH-1,"%s/tmp/%08lx.pkt",cfgs(CFG_INBOUND),sequencer());
		cpkt=openpktmsg(adr,adr,"qico chat-log poster",xstrdup(cfgs(CFG_SYSOP)),"log of chat",NULL,pktname,137);
		if(!cpkt)write_log("can't open '%s' for writing",pktname);
	}
	if(cfgs(CFG_CHATTOEMAIL)) {
		snprintf(str,MAX_PATH,"/tmp/qlemail.%04lx",(long)getpid());
		lemail=fopen(str,"wt");
		if(!lemail)write_log("can't crearte temporary email-log file");
	}
	if(cfgs(CFG_CHATLOG))chatlog=fopen(ccs,"at");
	if(ccs&&!chatlog)write_log("can't open chat log %s",ccs);
	tt=time(NULL);t=localtime(&tt);
	snprintf(str,MAX_STRING,"[Chat with: %s (%u:%u/%u.%u) open by %s at ",remname,ra->z,ra->n,ra->f,ra->p,side?"remote":"my");
	strftime(str+strlen(str),MAX_STRING-1,"%d %b %y %H:%M:%S]\n",t);
	if(chatlog){fwrite(str,strlen(str),1,chatlog);fclose(chatlog);}
	if(lemail)fwrite(str,strlen(str),1,lemail);
	if(cpkt) {
		if(cfgi(CFG_RECODEPKTS))recode_to_remote(str);
		strtr(str,'\n','\r');
		fwrite(str,strlen(str),1,cpkt);
		runtoss=1;
	}
	mcpos=rcpos=0;*rchat=0;*mchat=0;
	return(cpkt!=NULL||chatlog!=NULL||lemail!=NULL);
}
Пример #3
0
/*
 * Create packet in OUTPKT with netmail message header
 */
int outpkt_netmail(Message *msg, Textlist *tl, char *program, char *origin,
		    char *tearline)
{
    FILE *fp;
    
    /* If from node is default, use aka for to zone */
#ifndef BEST_AKA
    cf_set_zone(msg->node_to.zone);
#else 
    cf_set_best(msg->node_to.zone, msg->node_to.net, msg->node_to.node);
#endif /* !BEST_AKA */

    if(msg->node_from.zone == 0)
	msg->node_from = cf_n_addr();
    
    /* Open outpkt packet */
    fp = outpkt_open(&msg->node_from, &msg->node_to, '0', '0', '0', FALSE);
    if(!fp)
	return ERROR;
    
    /* Write message header */
    pkt_put_msg_hdr(fp, msg, TRUE);
    /* Additional kludges */
    fprintf(fp, "\001MSGID: %s %08lx\r\n",
	    znf1(&msg->node_from), sequencer(cf_p_seq_msgid()));
    /* Write message body */
    tl_print_x(tl, fp, "\r\n");
    /* Additional kludges */
    if (!tearline)
    fprintf(fp, "\r\n--- FIDOGATE %s\r\n", version_global());
    else
    fprintf(fp, "\r\n--- %s\r\n", tearline);

    if ( NULL == msg->area )
    {
#ifndef FTS_VIA
    fprintf(fp, "\001Via FIDOGATE/%s %s, %s\r",
	    program, znf1(&msg->node_from),
	    date(DATE_VIA, NULL)  );
#else
    fprintf(fp, "\001Via %s @%s FIDOGATE/%s\r",
	    znf1(&msg->node_from),
	    date(DATE_VIA, NULL), program);
#endif /* FTS_VIA */
    }
    else
    {
	fprintf( fp, " * Origin: %s(%s)\r\n", origin,
			znfp1( &msg->node_from ) );
    }

    /* Terminating 0-byte */
    putc(0, fp);

    outpkt_close();

    return OK;
}
Пример #4
0
/*
 * Open RFC mail file
 */
int mail_open(int sel)
{
    long n;
    
    switch(sel)
    {
    case 'm':
    case 'M':
	n = sequencer(cf_p_seq_mail());
	str_printf(m_tmp,  sizeof(m_tmp),  "%s/%08ld.tmp", mail_dir, n);
	str_printf(m_name, sizeof(m_name), "%s/%08ld.rfc", mail_dir, n);
	m_file = fopen(m_tmp, W_MODE);
	if(!m_file) {
	    fglog("$Can't create mail file %s", m_tmp);
	    return ERROR;
	}
	break;
	
    case 'n':
    case 'N':
	n = sequencer(cf_p_seq_news());
	str_printf(n_tmp,  sizeof(n_tmp),  "%s/%08ld.tmp", news_dir, n);
	str_printf(n_name, sizeof(n_name), "%s/%08ld.rfc", news_dir, n);
	n_file = fopen(n_tmp, W_MODE);
	if(!n_file) {
	    fglog("$Can't create mail file %s", n_tmp);
	    return ERROR;
	}
	break;

    default:
	fglog("mail_open(%d): illegal value", sel);
	return ERROR;
    }

    return OK;
}
Пример #5
0
/*
 * Get name for new packet
 */
static char *pkt_newname(char *name)
{
    if(name)
    {
	BUF_COPY(packet_name, name);
	BUF_COPY(packet_tmp , name);
    }
    else
    {
	long n = sequencer(cf_p_seq_pkt());
	str_printf(packet_name, sizeof(packet_name),
		   "%s/%08ld.pkt", packet_dir, n);
	str_printf(packet_tmp , sizeof(packet_tmp),
		   "%s/%08ld.tmp", packet_dir, n);
    }

    return packet_name;
}
Пример #6
0
int main(int argc, char **argv)
{
	struct passwd	*pw;
	unsigned int	seq;

	InitConfig();

	pw = getpwuid(getuid());

	InitClient(pw->pw_name, (char *)"ftnseq", CFG.location, CFG.logfile, 
		CFG.util_loglevel, CFG.error_log, CFG.mgrlog, CFG.debuglog);

	Syslog(' ', " "); 
	Syslog(' ', "FTNSEQ v%s", VERSION);

	seq = sequencer();
	Syslog('+', "Sequence string %08lx", seq);
	printf("%08x", seq);
	fflush(stdout);

	Syslog(' ', "FTNSEQ finished");
	ExitClient(0);
	return 0;
}
Пример #7
0
/*
 *  Input a RFC news message.
 */
int rfc2ftn(FILE *fp)
{
    char            sbe[16], *p, *q, *temp, *origin, newsubj[4 * (MAXSUBJ+1)], *oldsubj;
    int             i, rc, newsmode, seenlen, oldnet;
    rfcmsg          *msg = NULL, *tmsg, *tmp;
    ftnmsg          *fmsg = NULL;
    FILE            *ofp, *qfp;
    fa_list         *sbl = NULL, *ptl = NULL, *tmpl;
    faddr           *ta, *fta;
    int             sot_kludge = FALSE, eot_kludge = FALSE, tinyorigin = FALSE;
    int             needsplit, hdrsize, datasize, splitpart, forbidsplit, rfcheaders;
    time_t          Now;
    struct tm	    *l_date;
    char	    *charset = NULL;

    temp = calloc(4097, sizeof(char));
    Syslog('m', "Entering rfc2ftn");
    rewind(fp);
    msg = parsrfc(fp);

    newsmode = hdr((char *)"Newsgroups", msg) ?TRUE:FALSE;
    if (newsmode == FALSE) {
	WriteError("Not a news article");
	return 1;
    }

    if ((fmsg = mkftnhdr(msg, newsmode, NULL)) == NULL) {
	WriteError("Unable to create FTN headers from RFC ones, aborting");
	tidyrfc(msg);
	return 1;
    }

    fmsg->area = xstrcpy(msgs.Tag);
    if ((p = hdr((char *)"Message-ID",msg))) {
	ftnmsgid(p, &fmsg->msgid_a, &fmsg->msgid_n, fmsg->area);
	hash_update_s(&fmsg->msgid_n, fmsg->area);
    }

    if ((p = hdr((char *)"References",msg))) {
	p = strrchr(p,' ');
	ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area);

//Griffin
	fmsg->reply_s=calloc(256,sizeof(char));
	findorigmsg(p,fmsg->reply_s);

	fmsg->to->name=calloc(strlen(Msg.From)+1,sizeof(char));
	strcpy(fmsg->to->name,Msg.From);
	Syslog('m', "fmsg to-name %s",fmsg->to->name);
	Syslog('m', "reply_s %s",fmsg->reply_s);

	if (!chkftnmsgid(p)) {
	    hash_update_s(&fmsg->reply_n, fmsg->area);
	}
    } else if ((p = hdr((char *)"In-Reply-To",msg))) {
	ftnmsgid(p,&fmsg->reply_a, &fmsg->reply_n,fmsg->area);
	if (!chkftnmsgid(p)) {
	    hash_update_s(&fmsg->reply_n, fmsg->area);
	}
    }

    chkftnmsgid(hdr((char *)"Message-ID",msg)); // ??
    removemime       = FALSE;
    removemsgid      = FALSE;
    removeref        = FALSE;
    removeinreply    = FALSE;
    removereplyto    = TRUE;
    removereturnto   = TRUE;
    ftnorigin = fmsg->ftnorigin;

    q = hdr((char *)"Content-Transfer-Encoding",msg);
    if (q) 
	while (*q && isspace(*q)) 
	    q++;
    if (!(q)) 
	q = (char *)"8bit"; 
    if ((p = hdr((char *)"Content-Type",msg))) {
	while (*p && isspace(*p)) 
	    p++;

	/*
	 * Check for mime to remove.
	 */
	if ((strncasecmp(p, "text/plain", 10) == 0) && ((q == NULL) || 
		    (strncasecmp(q,"7bit",4) == 0) || (strncasecmp(q,"8bit",4) == 0))) {
	    removemime = TRUE; /* no need in MIME headers */
	}

	q = strtok(p, " \n\0");
	q = strtok(NULL, "; \n\0");
	if (q) {
	    while (*q && isspace(*q))
		q++;
	    Syslog('m', "charset part: %s", printable(q, 0));
	    if (q && (strncasecmp(q, "charset=", 8) == 0)) {
		/*
		 * google.com quotes the charset name
		 */
		if (strchr(q, '"')) {
		    charset = xstrcpy(q + 9);
		    charset[strlen(charset)-1] = '\0';
		    Syslog('m', "Unquoted charset name");
		} else {
		    charset = xstrcpy(q + 8);
		}
		Syslog('m', "Charset \"%s\"", printable(charset, 0));
	    }
	}
    }

    if (charset == NULL) {
	charset = xstrcpy((char *)"ISO-8859-1");
	Syslog('m', "No charset, setting default to iso-8859-1");
    }

    chartran_init(charset, get_ic_ftn(msgs.Charset), 'm');

    if ((p = hdr((char *)"Message-ID",msg))) {
	if (!removemsgid)
	    removemsgid = chkftnmsgid(p);
    }

    if ((!removeref) && (p = hdr((char *)"References",msg))) {
	p = xstrcpy(p);
	q = strtok(p," \t\n");
	if ((q) && (strtok(NULL," \t\n") == NULL))
	    removeref = chkftnmsgid(q);       
	free(p);
    }

    if ((p = hdr((char *)"Reply-To",msg))) {
	removereplyto = FALSE;
	if ((q = hdr((char *)"From",msg))) {
	    char    *r;
	    r = xstrcpy(p); 
	    p = r;
	    while(*p && isspace(*p)) 
		p++;
	    if (p[strlen(p)-1] == '\n')
		p[strlen(p)-1]='\0';
	    if (strcasestr(q,p))
		removereplyto = TRUE;
	}
    }

    if ((p = hdr((char *)"Return-Receipt-To",msg))) {
	removereturnto = FALSE;
	if ((q = hdr((char *)"From",msg))) {
	    char    *r;

	    r = xstrcpy(p); 
	    p = r;
	    while (*p && isspace(*p)) 
		p++;
	    if (p[strlen(p)-1] == '\n') 
		p[strlen(p)-1]='\0';
	    if (strcasestr(q,p)) 
		removereturnto = TRUE;
	}
    }

    Syslog('m', "removemime=%s removemsgid=%s removeref=%s removeinreply=%s removereplyto=%s removereturnto=%s",
		removemime ?"TRUE ":"FALSE", removemsgid ?"TRUE ":"FALSE", removeref ?"TRUE ":"FALSE",
		removeinreply ?"TRUE ":"FALSE", removereplyto ?"TRUE ":"FALSE", removereturnto ?"TRUE ":"FALSE");

    p = ascfnode(fmsg->from,0x1f);
    i = 79-11-3-strlen(p);
    if (ftnorigin && fmsg->origin && (strlen(fmsg->origin) > i)) {
        /* This is a kludge...  I don't like it too much.  But well,
           if this is a message of FTN origin, the original origin (:)
           line MUST have been short enough to fit in 79 chars...
           So we give it a try.  Probably it would be better to keep
           the information about the address format from the origin
           line in a special X-FTN-... header, but this seems even
           less elegant.  Any _good_ ideas, anyone? */

        /* OK, I am keeping this, though if should never be used
           al long as X-FTN-Origin is used now */

	p = ascfnode(fmsg->from,0x0f);
	Syslog('m', "checkorigin 3");
	i = 79-11-3-strlen(p);
	tinyorigin = TRUE;
    }
    if (tinyorigin)
	Syslog('m', "tinyorigin = %s", tinyorigin ? "True":"False");

    if ((fmsg->origin) && (strlen(fmsg->origin) > i))
	fmsg->origin[i]='\0';
    forbidsplit = (ftnorigin || ((p = hdr((char *)"X-FTN-Split",msg))  && (strcasecmp(p," already\n") == 0)));
    needsplit = 0;
    splitpart = 0;
    hdrsize = 20;
    hdrsize += (fmsg->subj)?strlen(fmsg->subj):0;
    if (fmsg->from)
	hdrsize += (fmsg->from->name)?strlen(fmsg->from->name):0;
    if (fmsg->to)
	hdrsize += (fmsg->to->name)?strlen(fmsg->to->name):0;
    do {
	Syslog('m', "split loop, splitpart = %d", splitpart);
	datasize = 0;

	if (splitpart) {
	    snprintf(newsubj,4 * (MAXSUBJ+1),"[part %d] ",splitpart+1);
	    strncat(newsubj,fmsg->subj,MAXSUBJ-strlen(newsubj));
	} else {
	    strncpy(newsubj,fmsg->subj,MAXSUBJ);
	}
	newsubj[MAXSUBJ]='\0';

	if (splitpart) {
	    hash_update_n(&fmsg->msgid_n,splitpart);
	}
	oldsubj = fmsg->subj;
	fmsg->subj = newsubj;

	/*
	 * Create a new temp message in FTN style format
	 */
	if ((ofp = tmpfile()) == NULL) {
	    WriteError("$Can't open second tmpfile");
	    tidyrfc(msg);
	    return 1;
	}

	if ((fmsg->msgid_a == NULL) && (fmsg->msgid_n == 0)) {
	    Syslog('n', "No Messageid from poster, creating new MSGID");
	    fprintf(ofp, "\001MSGID: %s %08x\n", aka2str(msgs.Aka), sequencer());
	} else {
	    fprintf(ofp, "\001MSGID: %s %08x\n", MBSE_SS(fmsg->msgid_a),fmsg->msgid_n);
	}
	if (fmsg->reply_s) 
	    fprintf(ofp, "\1REPLY: %s\n", fmsg->reply_s);
	else if (fmsg->reply_a)
	    fprintf(ofp, "\1REPLY: %s %08x\n", fmsg->reply_a, fmsg->reply_n);
	Now = time(NULL) - (gmt_offset((time_t)0) * 60);
	fprintf(ofp, "\001TZUTC: %s\n", gmtoffset(Now));
	fprintf(ofp, "\001CHRS: %s\n", getftnchrs(msgs.Charset));
	
	fmsg->subj = oldsubj;
	if ((p = hdr((char *)"X-FTN-REPLYADDR",msg))) {
	    hdrsize += 10+strlen(p);
	    fprintf(ofp,"\1REPLYADDR:");
	    kludgewrite(p,ofp);
	} else if (replyaddr) {
	    hdrsize += 10+strlen(replyaddr);
	    fprintf(ofp,"\1REPLYADDR: ");
	    kludgewrite(replyaddr,ofp);
	}
	if ((p = hdr((char *)"X-FTN-REPLYTO",msg))) {
	    hdrsize += 8+strlen(p);
	    fprintf(ofp,"\1REPLYTO:");
	    kludgewrite(p,ofp);
	} else if (replyaddr) {
	    hdrsize += 15;
	    if (newsmode)
		fprintf(ofp,"\1REPLYTO: %s UUCP\n", aka2str(msgs.Aka));
	    else {
		fta = bestaka_s(fmsg->to);
		fprintf(ofp,"\1REPLYTO: %s UUCP\n", ascfnode(fta, 0x1f));
		tidy_faddr(fta);
	    }
	} else if ((p = hdr((char *)"Reply-To",msg))) {
	    if ((ta = parsefaddr(p))) {
		if ((q = hdr((char *)"From",msg))) {
		    if (!strcasestr(q,p)) {
			fprintf(ofp,"\1REPLYTO: %s %s\n", ascfnode(ta,0x1f), ta->name);
		    }
		}
		tidy_faddr(ta);
	    }
	}
	if ((p=strip_flags(hdr((char *)"X-FTN-FLAGS",msg)))) {
	    hdrsize += 15;
	    fprintf(ofp,"\1FLAGS:%s\n",p);
	    free(p);
	}
	if (!hdr((char *)"X-FTN-PID", msg)) { 
	    p = hdr((char *)"User-Agent", msg);
	    if (p == NULL) 
		p = hdr((char *)"X-Newsreader", msg);
	    if (p == NULL) 
		p = hdr((char *)"X-Mailer", msg);
	    if (p) {
		hdrsize += 4 + strlen(p);
		fprintf(ofp, "\1PID:");
		kludgewrite(p, ofp);
	    } else {
		fprintf(ofp, "\001PID: MBSE-NNTPD %s (%s-%s)\n", VERSION, OsName(), OsCPU());
	    }
	}

	if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) {
	    snprintf(temp, 4096, " MBSE-NNTPD %s (%s-%s)", VERSION, OsName(), OsCPU());
	    hdrsize += 4 + strlen(temp);
	    fprintf(ofp, "\1TID:");
	    kludgewrite(temp, ofp);
	}

	if ((splitpart == 0) || (hdrsize < MAXHDRSIZE)) {
	    for (tmp = msg; tmp; tmp = tmp->next) {
	 	if ((!strncmp(tmp->key,"X-Fsc-",6)) || (!strncmp(tmp->key,"X-FTN-",6) &&
			strcasecmp(tmp->key,"X-FTN-Tearline") &&
			strcasecmp(tmp->key,"X-FTN-Origin") &&
			strcasecmp(tmp->key,"X-FTN-Sender") &&
			strcasecmp(tmp->key,"X-FTN-Split") &&
			strcasecmp(tmp->key,"X-FTN-FLAGS") &&
			strcasecmp(tmp->key,"X-FTN-AREA") &&
			strcasecmp(tmp->key,"X-FTN-MSGID") &&
			strcasecmp(tmp->key,"X-FTN-REPLY") &&
			strcasecmp(tmp->key,"X-FTN-SEEN-BY") &&
			strcasecmp(tmp->key,"X-FTN-PATH") &&
			strcasecmp(tmp->key,"X-FTN-REPLYADDR") &&
			strcasecmp(tmp->key,"X-FTN-REPLYTO") &&
			strcasecmp(tmp->key,"X-FTN-To") &&
			strcasecmp(tmp->key,"X-FTN-From") &&
			strcasecmp(tmp->key,"X-FTN-CHARSET") &&
			strcasecmp(tmp->key,"X-FTN-CHRS") &&
			strcasecmp(tmp->key,"X-FTN-CODEPAGE") &&
			strcasecmp(tmp->key,"X-FTN-ORIGCHRS") &&
			strcasecmp(tmp->key,"X-FTN-SOT") &&
			strcasecmp(tmp->key,"X-FTN-EOT") &&
			strcasecmp(tmp->key,"X-FTN-Via"))) {
		    if ((strcasecmp(tmp->key,"X-FTN-KLUDGE") == 0)) {
			if (!strcasecmp(tmp->val," SOT:\n"))
			    sot_kludge = TRUE;
			else if (!strcasecmp(tmp->val," EOT:\n"))
			    eot_kludge = TRUE;
			else {
			    hdrsize += strlen(tmp->val);
			    fprintf(ofp,"\1");
			    /* we should have restored the original string here... */
			    kludgewrite((tmp->val)+1,ofp);
			}
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"\1%s:",tmp->key+6);
			kludgewrite(tmp->val,ofp);
		    }
		}
	    }

	    /* ZConnect are X-ZC-*: in usenet, \1ZC-*: in FTN */
	    for (tmp=msg;tmp;tmp=tmp->next)
		if ((!strncmp(tmp->key,"X-ZC-",5))) {
		    hdrsize += strlen(tmp->key)+strlen(tmp->val);
		    fprintf(ofp,"\1%s:",tmp->key+2);
		    kludgewrite(tmp->val,ofp);
		}

	    /* mondo.org gateway uses ".MSGID: ..." in usenet */
	    for (tmp=msg;tmp;tmp=tmp->next)
		if ((!strncmp(tmp->key,".",1)) && (strcasecmp(tmp->key,".MSGID"))) {
		    hdrsize += strlen(tmp->key)+strlen(tmp->val);
		    fprintf(ofp,"\1%s:",tmp->key+1);
		    kludgewrite(tmp->val,ofp);
		}

	    for (tmp = msg; tmp; tmp = tmp->next) {
		if ((needputrfc(tmp, newsmode) == 1)) {
		    if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) {
			hdrsize += 10+strlen(tmp->val);
			fprintf(ofp,"\1RFC-Newsgroups:");
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"\1RFC-%s:",tmp->key);
		    }
		    kludgewrite(tmp->val, ofp);
		}
	    }

	    rfcheaders=0;
	    for (tmp=msg;tmp;tmp=tmp->next) {
		if ((needputrfc(tmp, newsmode) > 1)) {
		    rfcheaders++;
		    if (strcasestr((char *)"X-Origin-Newsgroups",tmp->key)) {
			hdrsize += 10+strlen(tmp->val);
			fprintf(ofp,"Newsgroups:");
		    } else {
			hdrsize += strlen(tmp->key)+strlen(tmp->val);
			fprintf(ofp,"%s:",tmp->key);
		    }
		    charwrite(tmp->val, ofp);
		}
	    }

	    if (rfcheaders) 
		charwrite((char *)"\n",ofp);
	    if ((hdr((char *)"X-FTN-SOT",msg)) || (sot_kludge))
		fprintf(ofp,"\1SOT:\n");
	}
	if (replyaddr) {
	    replyaddr = NULL;
	}

	if (needsplit) {
	    fprintf(ofp," * Continuation %d of a split message *\n\n", splitpart);
	    needsplit = FALSE;
	} else if ((p=hdr((char *)"X-Body-Start",msg))) {
	    datasize += strlen(p);
	    charwrite(p, ofp);
	}
	while (!(needsplit=(!forbidsplit) && (((splitpart && (datasize > (CFG.new_split * 1024))) ||
		      (!splitpart && ((datasize+hdrsize) > (CFG.new_split * 1024)))))) && (bgets(temp,4096-1,fp))) {
	    datasize += strlen(temp);
	    charwrite(temp, ofp);
	}

	if (needsplit) {
	    fprintf(ofp,"\n * Message split, to be continued *\n");
	    splitpart++;
	}
	if ((p=hdr((char *)"X-FTN-EOT",msg)) || (eot_kludge))
	    fprintf(ofp,"\1EOT:\n");

	if ((p=hdr((char *)"X-FTN-Tearline",msg))) {
	    fprintf(ofp,"---");
	    if (strcasecmp(p," (none)\n") == 0)
		charwrite((char *)"\n",ofp);
	    else
		charwrite(p,ofp);
	} else
	    fprintf(ofp,"\n%s\n", TearLine());

	if ((p = hdr((char *)"X-FTN-Origin",msg))) {
	    if (*(q=p+strlen(p)-1) == '\n') 
		*q='\0';
	    origin = xstrcpy((char *)" * Origin: ");
	    origin = xstrcat(origin, p);
	} else {
	    origin = xstrcpy((char *)" * Origin: ");
	    if (fmsg->origin)
		origin = xstrcat(origin, fmsg->origin);
	    else
		origin = xstrcat(origin, CFG.origin);
	    origin = xstrcat(origin, (char *)" (");
	    origin = xstrcat(origin, ascfnode(fmsg->from,tinyorigin?0x0f:0x1f));
	    origin = xstrcat(origin, (char *)")");
	}
	fprintf(ofp, "%s", origin);

	if (newsmode) {
	    /*
	     * Setup SEEN-BY lines, first SEEN-BY from RFC message, then all matching AKA's
	     */
	    for (tmsg = msg; tmsg; tmsg = tmsg->next)
		if (strcasecmp(tmsg->key, "X-FTN-SEEN-BY") == 0)
		    fill_list(&sbl, tmsg->val, NULL);
	    for (i = 0; i < 40; i++) {
		if (CFG.akavalid[i] && (CFG.aka[i].point == 0) && (msgs.Aka.zone == CFG.aka[i].zone) &&
				    !((msgs.Aka.net == CFG.aka[i].net) && (msgs.Aka.node == CFG.aka[i].node))) {
		    snprintf(sbe, 16, "%u/%u", CFG.aka[i].net, CFG.aka[i].node);
		    fill_list(&sbl, sbe, NULL);
		}
	    }
	    if (msgs.Aka.point == 0) {
		snprintf(sbe, 16, "%u/%u", msgs.Aka.net, msgs.Aka.node);
		fill_list(&sbl, sbe, NULL);
	    }

	    /*
	     *  Only add SEEN-BY lines if there are any
	     */
	    if (sbl != NULL) {
		uniq_list(&sbl);
		sort_list(&sbl);
		seenlen = MAXSEEN + 1;
		memset(&sbe, 0, sizeof(sbe));
		/* ensure it will not match for the first entry */
		oldnet = sbl->addr->net-1;
		for (tmpl = sbl; tmpl; tmpl = tmpl->next) {
		    if (tmpl->addr->net == oldnet)
			snprintf(sbe,16," %u",tmpl->addr->node);
		    else
			snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node);
		    oldnet = tmpl->addr->net;
		    seenlen += strlen(sbe);
		    if (seenlen > MAXSEEN) {
			seenlen = 0;
			fprintf(ofp,"\nSEEN-BY:");
			snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node);
			seenlen = strlen(sbe);
		    }
		    fprintf(ofp,"%s",sbe);
		}
		tidy_falist(&sbl);
	    }

	    /*
	     *  Setup PATH lines
	     */
	    for (tmp = msg; tmp; tmp = tmp->next)
		if (!strcasecmp(tmp->key,"X-FTN-PATH"))
		    fill_path(&ptl,tmp->val);
	    if (msgs.Aka.point == 0) {
	        snprintf(sbe,16,"%u/%u",msgs.Aka.net, msgs.Aka.node);
		fill_path(&ptl,sbe);
	    }

	    /*
	     *  Only add PATH line if there is something
	     */
	    if (ptl != NULL) {
		uniq_list(&ptl);
		seenlen = MAXPATH+1;
		/* ensure it will not match for the first entry */
		oldnet = ptl->addr->net-1;
		for (tmpl = ptl; tmpl; tmpl = tmpl->next) {
		    if (tmpl->addr->net == oldnet)
			snprintf(sbe,16," %u",tmpl->addr->node);
		    else
			snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node);
		    oldnet = tmpl->addr->net;
		    seenlen += strlen(sbe);
		    if (seenlen > MAXPATH) {
			seenlen = 0;
			fprintf(ofp,"\n\1PATH:");
			snprintf(sbe,16," %u/%u",tmpl->addr->net, tmpl->addr->node);
			seenlen = strlen(sbe);
		    }
		    fprintf(ofp,"%s",sbe);
		}
		tidy_falist(&ptl);
	    }
	} /* if (newsmode) */

	/*
	 *  Add newline and message is ready.
	 */
	fprintf(ofp,"\n");
	fflush(ofp);
	rewind(ofp);

	Syslog('m', "========== Fido start");
	while (fgets(temp, 4096, ofp) != NULL) {
	    /*
	     *  Only log kludges, skip the body
	     */
	    if ((temp[0] == '\001') || !strncmp(temp, "AREA:", 5) || !strncmp(temp, "SEEN-BY", 7)) {
		Striplf(temp);
		Syslogp('m', printable(temp, 0));
	    }
	}
	Syslog('m', "========== Fido end");

	if (!Msg_Open(msgs.Base)) {
	    WriteError("Failed to open msgbase \"%s\"", msgs.Base);
	} else {
	    if (!Msg_Lock(30L)) {
		WriteError("Can't lock %s", msgs.Base);
	    } else {
		Msg_New();
		strcpy(Msg.From, fmsg->from->name);
		strcpy(Msg.To, fmsg->to->name);
		strcpy(Msg.FromAddress, ascfnode(fmsg->from,0x1f));
		strcpy(Msg.Subject, fmsg->subj);
		Msg.Written = Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60);
		Msg.Local = TRUE;
		rewind(ofp);
		while (fgets(temp, 4096, ofp) != NULL) {
		    Striplf(temp);
		    MsgText_Add2(temp);
		}

		Msg_AddMsg();
		Msg_UnLock();
		Syslog('+', "Msg (%ld) to \"%s\", \"%s\"", Msg.Id, Msg.To, Msg.Subject);
		do_mailout = TRUE;

		/*
		 * Create fast scan index
		 */
		snprintf(temp, PATH_MAX, "%s/tmp/echomail.jam", getenv("MBSE_ROOT"));
		if ((qfp = fopen(temp, "a")) != NULL) {
		    fprintf(qfp, "%s %u\n", msgs.Base, Msg.Id);
		    fclose(qfp);
		}

		/*
		 * Link messages
		 */
		rc = Msg_Link(msgs.Base, TRUE, CFG.slow_util);
		if (rc != -1)
		    Syslog('+', "Linked %d message%s", rc, (rc != 1) ? "s":"");
		else
		    Syslog('+', "Could not link messages");

		/*
		 * Update statistical counters
		 */
		Now = time(NULL);
		l_date = localtime(&Now);
		msgs.LastPosted = time(NULL);
		msgs.Posted.total++;
		msgs.Posted.tweek++;
		msgs.Posted.tdow[l_date->tm_wday]++;
		msgs.Posted.month[l_date->tm_mon]++;
		mgroup.LastDate = time(NULL);
		mgroup.MsgsSent.total++;
		mgroup.MsgsSent.tweek++;
		mgroup.MsgsSent.tdow[l_date->tm_wday]++;
		mgroup.MsgsSent.month[l_date->tm_mon]++;
		UpdateMsgs();

		snprintf(temp, PATH_MAX, "%s/etc/users.data", getenv("MBSE_ROOT"));
		if ((qfp = fopen(temp, "r+"))) {
		    fread(&usrconfighdr, sizeof(usrconfighdr), 1, qfp);
		    fseek(qfp, usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize), SEEK_SET);
		    if (fread(&usrconfig, usrconfighdr.recsize, 1, qfp) == 1) {
			usrconfig.iPosted++;
			fseek(qfp, usrconfighdr.hdrsize + (grecno * usrconfighdr.recsize), SEEK_SET);
			fwrite(&usrconfig, usrconfighdr.recsize, 1, qfp);
		    }
		    fclose(qfp);
		}
	    }
	    Msg_Close();
	}
	
	free(origin);
        fclose(ofp);
    } while (needsplit);
    free(temp);
    if (charset)
	free(charset);
    chartran_close();
    tidyrfc(msg);
    tidy_ftnmsg(fmsg);
    UpdateMsgs();

    return 0;
}
Пример #8
0
int Bounce(faddr *f, faddr *t, FILE *fp, char *reason)
{
    int	    rc = 0, count = 0;
    char    *Buf;
    FILE    *np;
    time_t  Now;
    faddr   *from;

    Now = time(NULL);
    if (SearchFidonet(f->zone))
	f->domain = xstrcpy(fidonet.domain);

    Syslog('+', "Bounce msg from %s", ascfnode(f, 0xff));
    Buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
    rewind(fp);

    np = tmpfile();
    from = bestaka_s(f);
    from->zone  = t->zone;
    from->net   = t->net;
    from->node  = t->node;
    from->point = t->point;
    from->name  = xstrcpy((char *)"Postmaster");

    if (f->point)
	fprintf(np, "\001TOPT %d\r", f->point);
    if (from->point)
	fprintf(np, "\001FMPT %d\r", from->point);
    fprintf(np, "\001INTL %d:%d/%d %d:%d/%d\r", f->zone, f->net, f->node, from->zone, from->net, from->node);

    /*
     * Add MSGID, REPLY and PID
     */
    fprintf(np, "\001MSGID: %s %08x\r", ascfnode(from, 0x1f), sequencer());
    while ((fgets(Buf, MAX_LINE_LENGTH, fp)) != NULL) {
	Striplf(Buf);
	if (strncmp(Buf, "\001MSGID:", 7) == 0) {
	    fprintf(np, "\001REPLY:%s\r", Buf+7);
	}
    }
    fprintf(np, "\001PID: FTND-FIDO %s (%s-%s)\r", VERSION, OsName(), OsCPU());
    fprintf(np, "\001TZUTC: %s\r", gmtoffset(Now));

    fprintf(np, "     Dear %s\r\r", FTND_SS(f->name));
    fprintf(np, "Your message could not be delevered, reason: %s\r\r", reason);
    fprintf(np, "Here are the first lines of the original message from you:\r\r");
    fprintf(np, "======================================================================\r");

    rewind(fp);
    while ((fgets(Buf, MAX_LINE_LENGTH, fp)) != NULL) {
	Striplf(Buf);
	if (Buf[0] == '\001') {
	    fprintf(np, "^a");
	    fwrite(Buf + 1, strlen(Buf) -1, 1, np);
	} else {
	    fwrite(Buf, strlen(Buf), 1, np);
	}
	fputc('\r', np);
	count++;
	if (count == 50)
	    break;
    }
    fprintf(np, "======================================================================\r");
    if (count == 50) {
	fprintf(np, "\rOnly the first 50 lines are displayed\r");
    }

    fprintf(np, "\rWith regards, %s\r\r", CFG.sysop_name);
    fprintf(np, "%s\r", TearLine());
    Now = time(NULL) - (gmt_offset((time_t)0) * 60);
    rc = postnetmail(np, from, f, NULL, (char *)"Bounced message", Now, 0x0000, FALSE, from->zone, f->zone);
    tidy_faddr(from);

    fclose(np);

    free(Buf);
    return rc;
}
Пример #9
0
int PrepARC(char *Queue, fidoaddr Dest)
{
    char    *pktfile;
    FILE    *fp;

    Syslog('p', "Prepare ARCmail for %s", aka2str(Dest));

    if (!SearchNode(Dest)) {
	WriteError("Downlink %s not found", aka2str(Dest));
	return FALSE;
    }

    pktfile = calloc(PATH_MAX, sizeof(char));
    snprintf(pktfile, PATH_MAX, "%s/%d.%d.%d.%d/%08x.pkt", CFG.out_queue, Dest.zone, Dest.net, Dest.node, Dest.point, sequencer());
    Syslog('p', "Rename .pkt to %s", pktfile);

    if (rename(Queue, pktfile)) {
	WriteError("$Can't rename %s to %s", Queue, pktfile);
	free(pktfile);
	return FALSE;
    }

    /*
     * Add zero word to end of .pkt file
     */
    if ((fp = fopen(pktfile, "a+")) == NULL) {
	WriteError("$Can't open %s", pktfile);
	free(pktfile);
	return FALSE;
    }
    putc('\0', fp);
    putc('\0', fp);
    fsync(fileno(fp));
    fclose(fp);

    free(pktfile);
    return TRUE;
}
void RequestGenerator::initiateRelease()
{
  DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Release");
  sequencer()->makeRequest(CacheMsg(m_address, CacheRequestType_ST, Address(3), AccessModeType_UserMode, 1, PrefetchBit_No)); 
}
void RequestGenerator::initiateSwap()
{
  DEBUG_MSG(TESTER_COMP, MedPrio, "initiating Swap");
  sequencer()->makeRequest(CacheMsg(m_address, CacheRequestType_ATOMIC, Address(2), AccessModeType_UserMode, 1, PrefetchBit_No)); 
}
int main(int argc, const char ** argv) {
	auto start = std::chrono::high_resolution_clock::now();

	std::cout << "MSAcquisitionSimulator Version " << MSAcquisitionSimulator_VERSION_MAJOR << "." << MSAcquisitionSimulator_VERSION_MINOR << "." << MSAcquisitionSimulator_VERSION_PATCH << std::endl;
	std::cout << "AcquisitionSimulator Version " << AcquisitionSimulator_VERSION_MAJOR << "." << AcquisitionSimulator_VERSION_MINOR << "." << AcquisitionSimulator_VERSION_PATCH << std::endl;

	std::string sqlite_in_path;
	std::string mzml_out_path;
	std::string param_file_path;
	std::string fido_out_path;
	std::string fasta_in_path;
	std::string target_decoy_out_path;
	std::string acquisition_algorithm_name;

	std::vector<std::string> acquisition_param_values;

	double ms1_scan_time;
	double ms2_scan_time;
	double scan_overhead_time;
	int acquisition_length;

	double elution_tau;
	double elution_sigma;

	double resolution;
	double dynamic_range;

	double db_search_min_mass;
	double db_search_max_mass;
	double db_search_mass_tolerance;
	int db_search_max_missed_cleavages;
	int db_search_max_dynamic_mods;
	int db_search_min_enzymatic_termini;
	double null_lambda;

	double max_ms1_injection_time;
	double max_ms2_injection_time;
	double ms1_target_total_ion_count;
	double ms2_target_total_ion_count;

	std::vector<DBPTM> PTMs;
	std::vector<DBEnzyme> enzymes;


	//region Command line specification
	boost::program_options::options_description general("USAGE: AcquisitionSimulator [options] ground_truth.tab\n\nOptions");
	general.add_options()
			("help", "Print usage and exit.")
			("conf,c", boost::program_options::value<std::string>(&param_file_path)->default_value("acquisition.conf"), "Input path to config file.")
			("mzml_out_path,o", boost::program_options::value<std::string>(&mzml_out_path)->default_value("sample.mzML"), "output path for mzML file.")
			("fido_out_path,f", boost::program_options::value<std::string>(&fido_out_path)->default_value("sample.fido"), "output path for fido file.")
			("target_decoy_out_path,d", boost::program_options::value<std::string>(&target_decoy_out_path)->default_value("targetDecoy.txt"), "output path for fido targetDecoy file.")
			;

	boost::program_options::options_description hidden("");
	hidden.add_options()
			("ground_truth_in_path", boost::program_options::value<std::string>(&sqlite_in_path), "input path for ground truth file made by GroundTruthSimulator.")
			;

	boost::program_options::options_description all("Allowed options");
	all.add(general).add(hidden);

	boost::program_options::positional_options_description p;
	p.add("ground_truth_in_path", -1);

	boost::program_options::variables_map vm;
	boost::program_options::store(boost::program_options::command_line_parser(argc, argv).options(all).positional(p).run(), vm);
	boost::program_options::notify(vm);
	//endregion

	//region Command line processing
	if (vm.count("help")) {
		std::cout << general << std::endl;
		return 0;
	}

	//region config file specification
	boost::program_options::options_description config("Configuration file options");
	config.add_options()
			("acquisition_algorithm", boost::program_options::value<std::string>(&acquisition_algorithm_name)->default_value("TopN"), "acquisition algorithm")
			("acquisition_algorithm_params", boost::program_options::value<std::vector<std::string>>(&acquisition_param_values)->multitoken(), "acquisition_algorithm_params")
			("ms1_scan_time", boost::program_options::value<double>(&ms1_scan_time)->default_value(0.256), "ms1_scan_time")
			("ms2_scan_time", boost::program_options::value<double>(&ms2_scan_time)->default_value(0.064), "ms2_scan_time")
			("scan_overhead_time", boost::program_options::value<double>(&scan_overhead_time)->default_value(0.015), "scan_overhead_time")
			("acquisition_length", boost::program_options::value<int>(&acquisition_length)->default_value(3600), "acquisition_length")
			("fasta", boost::program_options::value<std::string>(&fasta_in_path), "acquisition fasta_in_path")
			("elution_tau", boost::program_options::value<double>(&elution_tau)->default_value(4), "elution_tau")
			("elution_sigma", boost::program_options::value<double>(&elution_sigma)->default_value(6), "elution_sigma")
			("resolution", boost::program_options::value<double>(&resolution)->default_value(60000), "resolution")
			("dynamic_range", boost::program_options::value<double>(&dynamic_range)->default_value(5000), "dynamic_range")
			("db_search_min_mass", boost::program_options::value<double>(&db_search_min_mass)->default_value(200), "db_search_min_mass")
			("db_search_max_mass", boost::program_options::value<double>(&db_search_max_mass)->default_value(9000), "db_search_max_mass")
			("db_search_max_missed_cleavages", boost::program_options::value<int>(&db_search_max_missed_cleavages)->default_value(0), "db_search_max_missed_cleavages")
			("db_search_max_dynamic_mods", boost::program_options::value<int>(&db_search_max_dynamic_mods)->default_value(0), "db_search_max_dynamic_mods")
			("db_search_min_enzymatic_termini", boost::program_options::value<int>(&db_search_min_enzymatic_termini)->default_value(2), "db_search_min_enzymatic_termini")
			("db_search_mass_tolerance", boost::program_options::value<double>(&db_search_mass_tolerance)->default_value(.05), "db_search_mass_tolerance")
			("db_search_PTM", boost::program_options::value<std::vector<DBPTM> >(&PTMs)->multitoken(), "PTMs")
			("db_search_enzyme", boost::program_options::value<std::vector<DBEnzyme>>(&enzymes)->multitoken(), "enzymes")
			("db_search_null_lambda", boost::program_options::value<double>(&null_lambda)->default_value(6), "db_search_null_lambda")
			("max_ms1_injection_time", boost::program_options::value<double>(&max_ms1_injection_time)->default_value(0.2), "max_ms1_injection_time")
			("max_ms2_injection_time", boost::program_options::value<double>(&max_ms2_injection_time)->default_value(0.5), "max_ms2_injection_time")
			("ms1_target_total_ion_count", boost::program_options::value<double>(&ms1_target_total_ion_count)->default_value(1e6), "ms1_target_total_ion_count")
			("ms2_target_total_ion_count", boost::program_options::value<double>(&ms2_target_total_ion_count)->default_value(1e5), "ms2_target_total_ion_count")
			;
	boost::program_options::variables_map vm_config;
	std::ifstream config_file(param_file_path.c_str());

	if(!config_file.is_open()) {
		std::cerr << "Unable to open configuration file: " << param_file_path << std::endl;
		exit(1);
	}

	boost::program_options::store(boost::program_options::parse_config_file(config_file, config, true), vm_config);
	boost::program_options::notify(vm_config);
	//endregion


	ElutionShapeSimulator elution_shape_simulator(elution_tau, elution_sigma);
	std::unique_ptr<GroundTruthText> db = std::unique_ptr<GroundTruthText>(new GroundTruthText(sqlite_in_path, false));
	std::unique_ptr<Instrument> instrument = std::unique_ptr<Instrument>(new Instrument(resolution, dynamic_range, ms1_scan_time, ms2_scan_time,
																						scan_overhead_time, max_ms1_injection_time,
																						max_ms2_injection_time, ms1_target_total_ion_count,
																						ms2_target_total_ion_count));

	Sequencer sequencer(fasta_in_path, PTMs, enzymes, db_search_mass_tolerance, db_search_max_missed_cleavages, db_search_min_enzymatic_termini, db_search_min_mass, db_search_max_mass, db_search_max_dynamic_mods, null_lambda);
	Oracle oracle(db.get(), instrument.get(), elution_shape_simulator);
	MzMLWriter mzml_writer(mzml_out_path);
	FidoWriter fido_writer(fido_out_path);

	AcquisitionController* controller = get_controller(acquisition_algorithm_name, acquisition_param_values);

	int ms1_count = 0;
	int ms2_count = 0;
	int quality_ms2_count = 0;
	double current_time = 0;

	std::cout << "Simulating Acquisition:" << std::endl;

	while (current_time <= acquisition_length) {
		std::unique_ptr<ScanRequest> scan_request = controller->get_scan_request(current_time);
		std::unique_ptr<Scan> scan = oracle.get_scan_data(scan_request.get(), current_time);

		if (scan->scan_type == Scan::ScanType::MS2) {
			ms2_count++;
			MS2Scan* tmp_scan = static_cast<MS2Scan*>(scan.get());
			sequencer.sequence_ms2_scan(tmp_scan);

			if (tmp_scan->probability >= 0 && tmp_scan->peptide != "DECOY") {
				fido_writer.write_peptide(tmp_scan->probability, tmp_scan->peptide, tmp_scan->proteins);
				if (tmp_scan->probability >= .9) quality_ms2_count++;
			}

			/*double max_int = 0;
			std::string max_pep;
			for (auto itr = tmp_scan->peptide2intensity.begin(); itr != tmp_scan->peptide2intensity.end(); ++itr) {
				if (itr->second > max_int) {
					max_int = itr->second;
					max_pep = itr->first;
				}
			}
			std::cout << tmp_scan->precursor_peak.mz << " " << tmp_scan->precursor_peak.intensity << " " << tmp_scan->elapsed_time << " " << tmp_scan->TIC << " " << max_pep << " " << max_int / tmp_scan->TIC << " " << tmp_scan->peptide << std::endl;
			*/
		} else {
			ms1_count++;
		}

		controller->process_scan(scan.get());
		current_time += scan->elapsed_time;

		if (scan->scan_id % 20 == 0) {
			std::cout << "\rCurrent time: " << current_time << " seconds. MS1 count: " << ms1_count << ". MS2 count: " << ms2_count << ". Num PSMs >= 0.9: " << quality_ms2_count << std::flush;
		}

		mzml_writer.add_to_scan_buffer(std::move(scan));
		if (mzml_writer.buffer.size() > 100) mzml_writer.write_buffer();
	}

	std::cout << "\rCurrent time: " << current_time << " seconds. MS1 count: " << ms1_count << ". MS2 count: " << ms2_count << ". Num PSMs >= 0.9: " << quality_ms2_count << std::endl;

	mzml_writer.write_buffer();
	mzml_writer.output_file_end();

	mzml_writer.close_file();
	fido_writer.close_file();

	sequencer.write_target_decoy_file(target_decoy_out_path);

	auto end = std::chrono::high_resolution_clock::now();

	std::cout << "Simulation Complete." << std::endl;
	std::cout << "Elapsed time: " << std::chrono::duration_cast<std::chrono::seconds>(end-start).count() << " seconds" << std::endl;

	return 0;
}
Пример #13
0
int Post(char *To, int Area, char *Subj, char *File, char *Flavor)
{
    int		    i, rc = FALSE, has_tear = FALSE, has_origin = FALSE;
    char	    *aka, *temp, *sAreas;
    FILE	    *fp, *tp;
    unsigned int    crc = -1;
    time_t	    tt;
    struct tm	    *t;

    ftnd_CleanSubject(Subj);

    if (!do_quiet) {
	ftnd_colour(CYAN, BLACK);
	printf("Post \"%s\" to \"%s\" in area %d\n", File, To, Area);
    }

    IsDoing("Posting");
    Syslog('+', "Post \"%s\" area %d to \"%s\" flavor %s", File, Area, To, Flavor);
    Syslog('+', "Subject: \"%s\"", Subj);

    if ((tp = fopen(File, "r")) == NULL) {
	WriteError("$Can't open %s", File);
	if (!do_quiet)
	    printf("Can't open \"%s\"\n", File);
	return -1;
    }

    sAreas = calloc(PATH_MAX, sizeof(char));
    snprintf(sAreas, PATH_MAX, "%s/etc/mareas.data", getenv("FTND_ROOT"));
    if ((fp = fopen(sAreas, "r")) == NULL) {
	WriteError("$Can't open %s", sAreas);
	free(sAreas);
	fclose(tp);
	return -1;
    }

    fread(&msgshdr, sizeof(msgshdr), 1, fp);
    if (fseek(fp, (msgshdr.recsize + msgshdr.syssize) * (Area - 1), SEEK_CUR) == 0) {
	if (fread(&msgs, msgshdr.recsize, 1, fp) == 1) {
	    rc = TRUE;
	} else {
	    WriteError("$Can't read area %ld", Area);
	}
    } else {
	WriteError("$Can't seek area %ld", Area);
    }

    free(sAreas);
    if (rc == FALSE) {
	fclose(fp);
	fclose(tp);
	return -1;
    }

    if (!msgs.Active) {
	WriteError("Area %s not active", msgs.Name);
	fclose(fp);
	fclose(tp);
	return -1;
    }

    /*
     * Check the proper syntax in the To parameter, in netmail areas
     * it must have a destination address, in all other areas just a
     * full name.
     */
    if (msgs.Type == NETMAIL) {
	if ((strchr(To, '@') == NULL) || (strstr(To, (char *)".n") == NULL) || (strstr(To, (char *)".z") == NULL)) {
	    WriteError("No address in \"%s\" and area is netmail", To);
	    if (!do_quiet)
		printf("No address in \"%s\" and area is netmail\n", To);
	    fclose(fp);
	    fclose(tp);
	    return -1;
	}
    } else {
	if ((strchr(To, '@')) || (strstr(To, (char *)".n")) || (strstr(To, (char *)".z"))) {
	    WriteError("Address present in \"%s\" and area is not netmail", To);
	    if (!do_quiet)
		printf("Address present in \"%s\" and area is not netmail\n", To);
	    fclose(fp);
	    fclose(tp);
	    return -1;
	}
    }

    if (!Msg_Open(msgs.Base)) {
	WriteError("Can't open %s", msgs.Base);
	fclose(fp);
	fclose(tp);
	return -1;
    }

    if (!Msg_Lock(30L)) {
	WriteError("Can't lock %s", msgs.Base);
	Msg_Close();
	fclose(fp);
	fclose(tp);
	return -1;
    }

    tt = time(NULL);
    t = localtime(&tt);
    Diw = t->tm_wday;
    Miy = t->tm_mon;
    memset(&Msg, 0, sizeof(Msg));
    Msg_New();

    /*
     * Update statistic counter for message area
     */
    fseek(fp, - msgshdr.recsize, SEEK_CUR);
    msgs.Posted.total++;
    msgs.Posted.tweek++;
    msgs.Posted.tdow[Diw]++;
    msgs.Posted.month[Miy]++;
    fwrite(&msgs, msgshdr.recsize, 1, fp);
    fclose(fp);

    /*
     * Start writing the message
     */
    snprintf(Msg.From, 101, CFG.sysop_name);
    snprintf(Msg.To, 101, To);

    /*
     * If netmail, clean the To field.
     */
    if ((msgs.Type == NETMAIL) && strchr(To, '@')) {
	for (i = 0; i < strlen(Msg.To); i++) {
	    if (Msg.To[i] == '_')
		Msg.To[i] = ' ';
	    if (Msg.To[i] == '@') {
		Msg.To[i] = '\0';
		break;
	    }
	}
    }

    snprintf(Msg.Subject, 101, "%s", Subj);
    snprintf(Msg.FromAddress, 101, "%s", aka2str(msgs.Aka));
    Msg.Written = Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60);
    Msg.Local = TRUE;

    if (strchr(Flavor, 'c'))
	Msg.Crash = TRUE;
    if (strchr(Flavor, 'p'))
	Msg.Private = TRUE;
    if (strchr(Flavor, 'h'))
	Msg.Hold = TRUE;

    switch (msgs.Type) {
	case LOCALMAIL:	
			Msg.Localmail = TRUE;
			break;

	case NETMAIL:
			Msg.Netmail = TRUE;
			snprintf(Msg.ToAddress, 101, "%s", ascfnode(parsefaddr(To), 0xff));
			break;

	case ECHOMAIL:
			Msg.Echomail = TRUE;
			break;

	case NEWS:
			Msg.News = TRUE;
			break;
    }

    temp = calloc(PATH_MAX, sizeof(char));
    snprintf(temp, PATH_MAX, "\001MSGID: %s %08x", aka2str(msgs.Aka), sequencer());
    MsgText_Add2(temp);
    Msg.MsgIdCRC = upd_crc32(temp, crc, strlen(temp));
    Msg.ReplyCRC = 0xffffffff;
    snprintf(temp, PATH_MAX, "\001PID: FTND-FIDO %s (%s-%s)", VERSION, OsName(), OsCPU());
    MsgText_Add2(temp);
    if (msgs.Charset != FTNC_NONE) {
	snprintf(temp, PATH_MAX, "\001CHRS: %s", getftnchrs(msgs.Charset));
    } else {
	snprintf(temp, PATH_MAX, "\001CHRS: %s", getftnchrs(FTNC_LATIN_1));
    }
    MsgText_Add2(temp);
    snprintf(temp, PATH_MAX, "\001TZUTC: %s", gmtoffset(tt));
    MsgText_Add2(temp);

    while ((Fgets(temp, PATH_MAX, tp)) != NULL) {
	if (strncmp(temp, "--- ", 4) == 0)
	    has_tear = TRUE;
	if (strncmp(temp, " * Origin: ", 11) == 0)
	    has_origin = TRUE;
    }
    rewind(tp);
    Syslog('m', "has tearline=%s, has origin=%s", has_tear?"True":"False", has_origin?"True":"False");

    /*
     * Add the file as text
     */
    Msg_Write(tp);
    fclose(tp);

    /*
     * Finish the message
     */
    if ((! has_tear) && (! has_origin)) {
	MsgText_Add2((char *)"");
	MsgText_Add2(TearLine());
    }

    if (! has_origin) {
	aka = calloc(40, sizeof(char));

	if (msgs.Aka.point)
	    snprintf(aka, 40, "(%d:%d/%d.%d)", msgs.Aka.zone, msgs.Aka.net, msgs.Aka.node, msgs.Aka.point);
	else
	    snprintf(aka, 40, "(%d:%d/%d)", msgs.Aka.zone, msgs.Aka.net, msgs.Aka.node);

	if (strlen(msgs.Origin))
	    snprintf(temp, 81, " * Origin: %s %s", msgs.Origin, aka);
	else
	    snprintf(temp, 81, " * Origin: %s %s", CFG.origin, aka);

	MsgText_Add2(temp);
	free(aka);
    }

    Msg_AddMsg();
    Msg_UnLock();
    Syslog('+', "Posted message %ld", Msg.Id);

    if (msgs.Type != LOCALMAIL) {
	snprintf(temp, PATH_MAX, "%s/tmp/%smail.jam", getenv("FTND_ROOT"), (msgs.Type == ECHOMAIL) ? "echo" : "net");
	if ((fp = fopen(temp, "a")) != NULL) {
	    fprintf(fp, "%s %u\n", msgs.Base, Msg.Id);
	    fclose(fp);
	}
	CreateSema((char *)"mailout");
    }

    free(temp);
    Msg_Close();

    return 0;
}
Пример #14
0
/*
 *  Start a netmail to one of our nodes in the setup.
 *  Return a file descriptor if success else NULL.
 *  Later the pack routine will add these mails to the outbound.
 */
FILE *SendMgrMail(faddr *t, int Keep, int FileAttach, char *bymgr, char *subj, char *reply)
{
	FILE		*qp;
	time_t		Now;
	fidoaddr	Orig, Dest;
	faddr		From;
	unsigned	flags = M_PVT;
	char		ext[4];

	From = *bestaka_s(t);
	memset(&Orig, 0, sizeof(Orig));
	Orig.zone  = From.zone;
	Orig.net   = From.net;
	Orig.node  = From.node;
	Orig.point = From.point;
	snprintf(Orig.domain, 13, "%s", From.domain);

	memset(&Dest, 0, sizeof(Dest));
	Dest.zone  = t->zone;
	Dest.net   = t->net;
	Dest.node  = t->node;
	Dest.point = t->point;
	snprintf(Dest.domain, 13, "%s", t->domain);

	if (!SearchNode(Dest)) {
		Syslog('!', "SendMgrMail(): Can't find node %s", aka2str(Dest));
		return NULL;
	}

	Syslog('m', "  Netmail from %s to %s", aka2str(Orig), ascfnode(t, 0x1f));

	Now = time(NULL) - (gmt_offset((time_t)0) * 60);
	flags |= (nodes.Crash)            ? M_CRASH    : 0;
	flags |= (FileAttach)             ? M_FILE     : 0;
	flags |= (nodes.Hold)             ? M_HOLD     : 0;

	/*
	 *  Increase counters, update record and reload.
	 */
	StatAdd(&nodes.MailSent, 1L);
	UpdateNode();
	SearchNode(Dest);

	memset(&ext, 0, sizeof(ext));
	if (nodes.PackNetmail)
		snprintf(ext, 4, (char *)"qqq");
	else if (nodes.Crash)
		snprintf(ext, 4, (char *)"ccc");
	else if (nodes.Hold)
		snprintf(ext, 4, (char *)"hhh");
	else
		snprintf(ext, 4, (char *)"nnn");

	if ((qp = OpenPkt(Orig, Dest, (char *)ext)) == NULL)
		return NULL;

	if (AddMsgHdr(qp, &From, t, flags, 0, Now, nodes.Sysop, tlcap(bymgr), subj)) {
		fclose(qp);
		return NULL;
	}

	if (Dest.point)
		fprintf(qp, "\001TOPT %d\r", Dest.point);
	if (Orig.point)
		fprintf(qp, "\001FMPT %d\r", Orig.point);

	fprintf(qp, "\001INTL %d:%d/%d %d:%d/%d\r", Dest.zone, Dest.net, Dest.node, Orig.zone, Orig.net, Orig.node);

	/*
	 * Add MSGID, REPLY and PID
	 */
	fprintf(qp, "\001MSGID: %s %08x\r", aka2str(Orig), sequencer());
	if (reply != NULL)
		fprintf(qp, "\001REPLY: %s\r", reply);
	fprintf(qp, "\001PID: MBSE-FIDO %s (%s-%s)\r", VERSION, OsName(), OsCPU());
	fprintf(qp, "\001TZUTC: %s\r", gmtoffset(Now));
	return qp;
}
Пример #15
0
/*
 *  Save the message to disk.
 */
int Save_Email(int IsReply)
{
    int             i;
    char            *p, *temp;
    unsigned int    crc = -1;
    int		    id;
    FILE	    *fp;

    if (Line < 2)
	return TRUE;

    if (!Open_Msgbase(sMailpath, 'w')) {
	return FALSE;
    }

    Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60);
    Msg.Written = Msg.Arrived;
    Msg.Local = TRUE;
    Msg.Netmail = TRUE;
    temp = calloc(PATH_MAX, sizeof(char));

    /*
     * Add header lines
     */
    snprintf(temp, PATH_MAX, "\001Date: %s", rfcdate(Msg.Written));
    MsgText_Add2(temp);
    snprintf(temp, PATH_MAX, "\001From: %s", Msg.From);
    MsgText_Add2(temp);
    snprintf(temp, PATH_MAX, "\001Subject: %s", Msg.Subject);
    MsgText_Add2(temp);
    snprintf(temp, PATH_MAX, "\001Sender: %s", Msg.From);
    MsgText_Add2(temp);
    snprintf(temp, PATH_MAX, "\001To: %s", Msg.To);
    MsgText_Add2(temp);
    MsgText_Add2((char *)"\001MIME-Version: 1.0");
    if (exitinfo.Charset != FTNC_NONE) {
	snprintf(temp, PATH_MAX, "\001Content-Type: text/plain; charset=%s", getrfcchrs(exitinfo.Charset));
    } else {
	snprintf(temp, PATH_MAX, "\001Content-Type: text/plain; charset=iso8859-1");
    }
    MsgText_Add2(temp);
    MsgText_Add2((char *)"\001Content-Transfer-Encoding: 8bit");
    snprintf(temp, PATH_MAX, "\001X-Mailreader: MBSE BBS %s", VERSION);
    MsgText_Add2(temp);
    p = calloc(81, sizeof(char));
    id = sequencer();
    snprintf(p, 81, "<%08x@%s>", id, CFG.sysdomain);
    snprintf(temp, PATH_MAX, "\001Message-id: %s", p);
    MsgText_Add2(temp);
    Msg.MsgIdCRC = upd_crc32(temp, crc, strlen(temp));
    free(p);

    if (IsReply) {
	snprintf(temp, PATH_MAX, "\001In-reply-to: %s", Msg.Replyid);
	MsgText_Add2(temp);
	crc = -1;
	Msg.ReplyCRC = upd_crc32(temp, crc, strlen(temp));
    } else
	Msg.ReplyCRC = 0xffffffff;

    /*
     * Add message text
     */
    for (i = 1; i < Line; i++) {
	MsgText_Add2(Message[i]);
    }

    /*
     * Add signature.
     */
    snprintf(temp, PATH_MAX, "%s/%s/.signature", CFG.bbs_usersdir, exitinfo.Name);
    if ((fp = fopen(temp, "r"))) {
        Syslog('m', "  Add .signature");
        MsgText_Add2((char *)"");
        while (fgets(temp, 80, fp)) {
	    Striplf(temp);
	    MsgText_Add2(temp);
	}
	fclose(fp);
	MsgText_Add2((char *)"");
    }
    MsgText_Add2(TearLine());

    /*
     * Save if to disk
     */
    Msg_AddMsg();
    Msg_UnLock();

    ReadExitinfo();
    exitinfo.iPosted++;
    mib_posted++;
    WriteExitinfo();

    do_mailout = TRUE;
    LC_Wrote = TRUE;

    Syslog('+', "Email (%ld) to \"%s\", \"%s\", in mailbox", Msg.Id, Msg.To, Msg.Subject);

    Enter(1);
    /* Saving message to disk */
    snprintf(temp, 81, "%s(%d)", (char *) Language(202), Msg.Id);
    pout(CFG.HiliteF, CFG.HiliteB, temp);
    Enter(2);
    sleep(2);

    /*
     * Add quick mailscan info
     */
    snprintf(temp, PATH_MAX, "%s/tmp/netmail.jam", getenv("MBSE_ROOT"));
    if ((fp = fopen(temp, "a")) != NULL) {
	fprintf(fp, "%s/%s/mailbox %u\n", CFG.bbs_usersdir, exitinfo.Name, Msg.Id);
	fclose(fp);
    }

    free(temp);
    Close_Msgbase(sMailpath);

    return TRUE;
}
Пример #16
0
/*
 * Get output packet sequence number
 */
long outpkt_sequencer(void)
{
    return sequencer(cf_p_seq_toss()) & 0x000fffff;
}
Пример #17
0
int freq_ifextrp(slist_t *reqs)
{
    FILE *f, *g, *r;
    char s[MAX_PATH], fn[MAX_PATH], sfn[MAX_PATH], *ss;
    char priv = 'a', *p, *sprt = "UNPROTEC", *slst = "UNLIS";
    int got = 0, wz = cfgs( CFG_EXTRP ) ? 1 : 0, kil;
    long tpid = (long) getpid();
    ftnaddr_t *ma = akamatch( &rnode->addrs->addr, cfgal( CFG_ADDRESS ));

    DEBUG(('R',1,"Freq received"));

    if ( rnode->options & O_LST ) {
        priv = 'l';
        slst += 2;
    }
    if( rnode->options & O_PWD ) {
        priv = 'p';
        sprt += 2;
    }
    
    snprintf( fn, MAX_PATH, "/tmp/qreq.%04lx", tpid );
    if( !( f = fopen( fn, "wt" ))) {
        write_log( "can't open '%s' for writing: %s", fn, strerror( errno ));
        return 0;
    }

    while( reqs ) {
        if ( cfgs( CFG_MAPIN ) && strchr( ccs, 'r' ))
            recode_to_local( reqs->str );
        DEBUG(('R',1,"requested '%s'", reqs->str));
        fprintf( f, "%s\n", reqs->str );
        reqs = reqs->next;
    }
    fclose( f );
    if(!wz) {
        falist_t *ra;
        snprintf(sfn,MAX_PATH,"/tmp/qsrif.%04lx",tpid);
        if(!(r=fopen(sfn,"wt"))){write_log("can't open '%s' for writing: %s",sfn,strerror(errno));return 0;}
        fprintf(r,"SessionType %s\n",bink?"OTHER":"EMSI");
        fprintf(r,"Sysop %s\n",rnode->sysop);
        for(ra=rnode->addrs;ra;ra=ra->next)fprintf(r,"AKA %s\n",ftnaddrtoa(&ra->addr));
        if(!is_ip)fprintf(r,"Baud %d\n",rnode->realspeed);
        fprintf(r,"Time -1\n");
        fprintf(r,"RemoteStatus %sTED\n",sprt);
        fprintf(r,"SystemStatus %sTED\n",slst);
        fprintf(r,"RequestList /tmp/qreq.%04lx\n",tpid);
        fprintf(r,"ResponseList /tmp/qfls.%04lx\n",tpid);
        fprintf(r,"Location %s\n",rnode->place);
        if(rnode->phone&&*rnode->phone)fprintf(r,"Phone %s\n",rnode->phone);
        if(rnode->options&O_PWD)fprintf(r,"Password %s\n",rnode->pwd);
        fprintf(r,"Mailer %s\n",rnode->mailer);
        fprintf(r,"Site %s\n",rnode->name);
        if(!is_ip&&(ss=getenv("CALLER_ID"))&&strcasecmp(ss,"none")&&strlen(ss)>3)fprintf(r,"CallerID %s\n",ss);
        fprintf(r,"OurAKA %s\n",ftnaddrtoa(ma));
        fprintf(r,"TRANX %08lu\n",time(NULL));
        fclose(r);
        snprintf(s,MAX_PATH,"%s %s",cfgs(CFG_SRIFRP),sfn);
    } else snprintf(s,MAX_PATH,"%s -wazoo -%c -s%d %s /tmp/qreq.%04lx /tmp/qfls.%04lx /tmp/qrep.%04lx",
            cfgs(CFG_EXTRP),priv,rnode->realspeed,ftnaddrtoa(&rnode->addrs->addr),tpid,tpid,tpid);
    write_log("exec '%s' returned rc=%d",s,execsh(s));
    lunlink(fn);lunlink(sfn);
    snprintf(fn,MAX_PATH,"/tmp/qfls.%04lx",tpid);
    if(!(f=fopen(fn,"rt"))) {
        snprintf(fn,MAX_PATH,"/tmp/qrep.%04lx",tpid);
        lunlink(fn);
        snprintf(fn,MAX_PATH,"/tmp/qfls.%04lx",tpid);
        lunlink(fn);
        write_log("can't open '%s' for reading",fn);
        return 0;
    }
    while(fgets(s,MAX_PATH-1,f)) {
        if(*s=='\n'||*s=='\r'||*s==' '||!*s)continue;
        ss=s;kil=0;got=1;
        if(*s=='='||*s=='-'){ss++;kil=1;}
            else if(*s=='+')ss++;
        p=ss+strlen(ss)-1;
        while(*p=='\r'||*p=='\n')*p--=0;
        p=strrchr(ss,' ');
        if(p)*p++=0;else p=ss;
        DEBUG(('R',1,"sending '%s' as '%s'%s",ss,qbasename((p!=ss)?p:ss),kil?" and kill":""));
        addflist(&fl,xstrdup(ss),xstrdup(qbasename((p!=ss)?p:ss)),kil?'^':' ',0,NULL,0);
    }
    fclose(f);lunlink(fn);
    snprintf(fn,MAX_PATH,"/tmp/qrep.%04lx",tpid);
    if(!(f=fopen(fn,"rt"))&&wz)write_log("can't open '%s' for reading",fn);
    snprintf(fn,MAX_PATH,"/tmp/qpkt.%04lx%02x",tpid,++freq_pktcount);
    g=openpktmsg(ma,&rnode->addrs->addr,cfgs(CFG_FREQFROM),rnode->sysop,cfgs(CFG_FREQSUBJ),NULL,fn,1);
    if(!g) {
        write_log("can't open '%s' for writing: %s",fn,strerror(errno));
        if(f)fclose(f);
        freq_pktcount--;
    }
    if(f&&g) {
        while(fgets(s,MAX_PATH-1,f)) {
            p=s+strlen(s)-1;
            while(*p=='\r'||*p=='\n')*p--=0;
            if(cfgi(CFG_RECODEPKTS))recode_to_remote(s);
            fputs(s,g);fputc('\r',g);
        }
        fclose(f);
        closeqpkt(g,ma);
        snprintf(s,MAX_PATH,"/tmp/qpkt.%04lx%02x",tpid,freq_pktcount);
        p=xstrdup(s);
        snprintf(s,MAX_PATH,"%08lx.pkt",sequencer());
        addflist(&fl,p,xstrdup(s),'^',0,NULL,1);
    }
    snprintf(fn,MAX_PATH,"/tmp/qrep.%04lx",tpid);
    lunlink(fn);
    return got;
}
Пример #18
0
void ForwardFile(fidoaddr Node, fa_list *sbl)
{
    char	*subject = NULL, *fwdfile = NULL, *queuedir, *listfile, *ticfile = NULL, *ticname, flavor;
    FILE	*fp, *fi, *fl, *net;
    faddr	*dest, *routeto, *Fa, *Temp, *ba;
    int		i, z, n;
    time_t	now, ftime;
    fa_list	*tmp;

    if (!SearchNode(Node)) {
	WriteError("TIC forward in %s, node %s not in setup but defined in area setup", TIC.TicIn.Area, aka2str(Node));
	return;
    }
    Syslog('+', "Forward file to %s %s netmail", aka2str(Node), nodes.Message?"with":"without");

    fwdfile  = calloc(PATH_MAX, sizeof(char));
    queuedir = calloc(PATH_MAX, sizeof(char));
    listfile = calloc(PATH_MAX, sizeof(char));
    snprintf(queuedir, PATH_MAX, "%s/%d.%d.%d.%d", CFG.out_queue, Node.zone, Node.net, Node.node, Node.point);
    snprintf(listfile, PATH_MAX, "%s/.filelist", queuedir);
    mkdirs(listfile, 0750);
    if ((fl = fopen(listfile, "a+")) == NULL) {
	WriteError("$Can't open %s", listfile);
	free(fwdfile);
	free(listfile);
	free(queuedir);
	return;
    }
    
    /*
     * Create the full filename
     */
    if (TIC.PassThru || TIC.SendOrg) {
	snprintf(fwdfile, PATH_MAX, "%s/%s", TIC.Inbound, TIC.TicIn.File);
	subject = xstrcpy(TIC.TicIn.File);
    } else {
	/*
	 * Make sure the file attach is the 8.3 filename
	 */
	snprintf(fwdfile, PATH_MAX, "%s/%s", TIC.BBSpath, TIC.NewFile);
	subject = xstrcpy(TIC.NewFile);
    }

    flavor = 'f';
    if (nodes.Crash) 
	flavor = 'c';
    if (nodes.Hold)
	flavor = 'h';

    fprintf(fl, "%c LEAVE FDN %s\n", flavor, fwdfile);

    if (nodes.RouteVia.zone)
	routeto = fido2faddr(nodes.RouteVia);
    else
	routeto = fido2faddr(Node);
    dest = fido2faddr(Node);

    ticfile = calloc(PATH_MAX, sizeof(char));
    ticname = calloc(15, sizeof(char));
    if (nodes.Tic) {
	snprintf(ticname, 15, "%08x.tic", sequencer());
	subject = xstrcat(subject, (char *)" ");
	subject = xstrcat(subject, ticname);
	snprintf(ticfile, PATH_MAX, "%s/%s", CFG.ticout, ticname);
    }
    free(ticname);

    /*
     *  Send netmail message if the node has it turned on.
     */
    if (nodes.Message) {
	Temp = fido2faddr(Node);
	if ((net = SendMgrMail(Temp, CFG.ct_KeepMgr, TRUE, (char *)"Filemgr", subject, NULL)) != NULL) {
	    if ((fi = OpenMacro("forward.tic", nodes.Language, FALSE)) != NULL) {
		ftime = TIC.FileDate;
		MacroVars("a", "s", TIC.TicIn.Area);
		MacroVars("b", "s", tic.Comment);
		MacroVars("c", "d", TIC.FileCost);
		MacroVars("d", "s", fgroup.Comment);
		if (TIC.PassThru || TIC.SendOrg)
		    MacroVars("f", "s", TIC.TicIn.FullName);
		else
		    MacroVars("f", "s", TIC.NewFullName);
		MacroVars("g", "d", TIC.FileSize);
		MacroVars("h", "d", (TIC.FileSize / 1024));
		MacroVars("i", "s", TIC.TicIn.Crc);
		MacroVars("j", "s", TIC.TicIn.Origin);
		MacroVars("m", "s", rfcdate(ftime));
		MacroVars("n", "s", TIC.TicIn.Desc);
		MacroVars("s", "s", nodes.Sysop);
		if (TIC.PassThru || TIC.SendOrg)
		    MacroVars("e", "s", TIC.TicIn.File);
		else
		    MacroVars("e", "s", TIC.NewFile);
		if (strlen(TIC.TicIn.Magic))
		    MacroVars("k", "s", TIC.TicIn.Magic);
		if (strlen(TIC.TicIn.Replace))
		    MacroVars("l", "s", TIC.TicIn.Replace);
		MacroRead(fi, net);
		fprintf(net, "%s\r", TearLine());
		CloseMail(net, Temp);
	    }
	} else {
	    WriteError("Can't create netmail");
	}
	tidy_faddr(Temp);
    }
    free(subject);

    /*
     * If we need a .TIC file, start creating it.
     */
    if (nodes.Tic) {
	mkdirs(ticfile, 0770);
	if ((fp = fopen(ticfile, "a+")) != NULL) {
	    fprintf(fp, "Area %s\r\n", TIC.TicIn.Area);
	    fprintf(fp, "Origin %s\r\n", TIC.TicIn.Origin);
	    Fa = fido2faddr(tic.Aka);
	    fprintf(fp, "From %s\r\n", ascfnode(Fa, 0x0f));
	    free(Fa);
	    if (strlen(TIC.TicIn.Replace))
		fprintf(fp, "Replaces %s\r\n", TIC.TicIn.Replace);
	    if (strlen(TIC.TicIn.Magic))
		fprintf(fp, "Magic %s\r\n", TIC.TicIn.Magic);

	    if ((TIC.PassThru) || (TIC.SendOrg)) {
		fprintf(fp, "File %s\r\n", TIC.TicIn.File);
		if (strlen(TIC.TicIn.FullName))
		    fprintf(fp, "Lfile %s\r\n", TIC.TicIn.FullName);
	    } else {
		fprintf(fp, "File %s\r\n", TIC.NewFile);
		if (strlen(TIC.NewFullName))
		    fprintf(fp, "Lfile %s\r\n", TIC.NewFullName);
	    }
	    fprintf(fp, "Size %d\r\n", (int)(TIC.FileSize));
	    fprintf(fp, "Desc %s\r\n", TIC.TicIn.Desc);
	    fprintf(fp, "Crc %s\r\n", TIC.TicIn.Crc);
	    if (nodes.TIC_To) {
		fprintf(fp, "To %s, %s\r\n", nodes.Sysop, ascfnode(dest, 0x1f));
	    }
	    if (nodes.AdvTic) {
		fprintf(fp, "Areadesc %s\r\n", tic.Comment);
		fprintf(fp, "Fdn %s\r\n", fgroup.Comment);
		if (TIC.TicIn.TotLDesc)
		    for (i = 0; i < TIC.TicIn.TotLDesc; i++)
			fprintf(fp, "LDesc %s\r\n", TIC.TicIn.LDesc[i]);
	    }
	    fprintf(fp, "Created by MBSE BBS %s %s\r\n", VERSION, SHORTRIGHT);
	    if (TIC.TicIn.TotPath)
		for (i = 0; i < TIC.TicIn.TotPath; i++)
		    fprintf(fp, "Path %s\r\n", TIC.TicIn.Path[i]);
	    /*
	     * Add our system to the path
	     */
	    now = time(NULL);
	    subject = ctime(&now);
	    Striplf(subject);
	    ba = bestaka_s(dest);
	    fprintf(fp, "Path %s %u %s %s\r\n", ascfnode(ba, 0x1f), (int)mktime(localtime(&now)), subject, tzname[0]);
	    tidy_faddr(ba);

	    if (nodes.TIC_AdvSB) {
		/*
		 * In advanced TIC mode we send multiple seenby
		 * addresses on one line in stead of one line
		 * per system.
		 */
		z = 0;
		n = 0;
		subject = xstrcpy((char *)"Seenby");
		for (tmp = sbl; tmp; tmp = tmp->next) {
		    if (strlen(subject) > 70) {
			fprintf(fp, "%s\r\n", subject);
			z = 0;
			n = 0;
			free(subject);
			subject = xstrcpy((char *)"Seenby ");
		    } else {
			subject = xstrcat(subject, (char *)" ");
		    }

		    if (z != tmp->addr->zone) {
			if (nodes.Tic4d)
			    subject = xstrcat(subject, ascfnode(tmp->addr, 0x0f));
			else
			    subject = xstrcat(subject, ascfnode(tmp->addr, 0x0e));
			z = tmp->addr->zone;
		    } else { 
			if (n != tmp->addr->net) {
			    if (nodes.Tic4d)
				subject = xstrcat(subject, ascfnode(tmp->addr, 0x07));
			    else
				subject = xstrcat(subject, ascfnode(tmp->addr, 0x06));
			    n = tmp->addr->net;
			} else {
			    if (nodes.Tic4d)
				subject = xstrcat(subject, ascfnode(tmp->addr, 0x03));
			    else
				subject = xstrcat(subject, ascfnode(tmp->addr, 0x02));
			}
		    }
		}
		if (strlen(subject) > 7) {
		    fprintf(fp, "%s\r\n", subject);
		    free(subject);
		}
	    } else {
		/*
		 * Old style seenby lines
		 */
		for (tmp = sbl; tmp; tmp = tmp->next) {
		    fprintf(fp, "Seenby %s\r\n", ascfnode(tmp->addr, 0x0f));
		}
	    }

	    /*
	     * Now append all passthru ticlines
	     */
	    if (TIC.TicIn.Unknowns)
		for (i = 0; i < TIC.TicIn.Unknowns; i++)
		    fprintf(fp, "%s\r\n", TIC.TicIn.Unknown[i]);

	    fprintf(fp, "Pw %s\r\n", nodes.Fpasswd);
	    fclose(fp);
	    fprintf(fl, "%c KFS NOR %s\n", flavor, ticfile);
	} else {
	    WriteError("$Can't create %s", ticfile);
	}
    }
    fsync(fileno(fl));
    fclose(fl);
    
    /*
     * Update the nodes statistic counters
     */
    StatAdd(&nodes.FilesSent, 1L);
    StatAdd(&nodes.F_KbSent, T_File.SizeKb);
    UpdateNode();
    SearchNode(Node);
    free(ticfile);
    free(fwdfile);
    free(queuedir);
    free(listfile);
    tidy_faddr(routeto);
}
Пример #19
0
void flush_dir(char *ndir)
{
    struct dirent   *de;
    DIR		    *dp;
    FILE	    *fp, *inf, *ouf;
    faddr	    noden, *bestaka;
    fidoaddr	    nodenr;
    int		    flavor, mode, Attach, fage, first, bread, rc;
    int		    fsize;
    char	    *p, *temp, *fname, *arcfile, *pktfile, *ext, maxnr, nr, oldnr, *buf;
    time_t	    Now;
    struct tm	    *ptm;
    struct stat	    sbuf;
    fd_list	    *fdl = NULL;

    temp = calloc(PATH_MAX, sizeof(char));
    snprintf(temp, PATH_MAX, "%s/%s", CFG.out_queue, ndir);
    if (chdir(temp) == -1) {
	WriteError("$Error chdir to %s", temp);
	free(temp);
	return;
    }

    /*
     * Get the nodenumber from the filename
     */
    noden.domain = NULL;
    noden.name   = NULL;
    noden.zone   = atoi(strtok(ndir, "."));
    noden.net    = atoi(strtok(NULL, "."));
    noden.node   = atoi(strtok(NULL, "."));
    noden.point  = atoi(strtok(NULL, "\0"));
    if (SearchFidonet(noden.zone))
	noden.domain = xstrcpy(fidonet.domain);

    memset(&nodenr, 0, sizeof(nodenr));
    nodenr.zone  = noden.zone;
    nodenr.net   = noden.net;
    nodenr.node  = noden.node;
    nodenr.point = noden.point;
    snprintf(nodenr.domain, 13, "%s", noden.domain);

    if (!SearchNode(nodenr)) {
	/*
	 * Node not in setup, blank noderecord and fill in some details
	 * so that we are able to send mail crash or immediate.
	 */
	Syslog('+', "Node %s not in setup, using default settings", aka2str(nodenr));
	memset(&nodes, 0, sizeof(nodes));
	nodes.Aka[0].zone  = noden.zone;
	nodes.Aka[0].net   = noden.net;
	nodes.Aka[0].node  = noden.node;
	nodes.Aka[0].point = noden.point;
	snprintf(nodes.Archiver, 6, (char *)"ZIP");
    }

    /*
     * If we route via another aka, change everything.
     */
    if (nodes.RouteVia.zone) {
	p = xstrcpy(aka2str(nodenr));
	Syslog('+', "Route to %s via %s", p, aka2str(nodes.RouteVia));
	free(p);
	noden.zone   = nodes.RouteVia.zone;
	noden.net    = nodes.RouteVia.net;
	noden.node   = nodes.RouteVia.node;
	noden.point  = nodes.RouteVia.point;
	if (noden.domain)
	    free(noden.domain);
	noden.domain = xstrcpy(nodes.RouteVia.domain);
	/*
	 * Load routevia noderecord to get the correct flavor.
	 * If there is no noderecord, reload the old one.
	 */
	if (!SearchNode(nodes.RouteVia))
	    SearchNode(nodenr);
    }

    /*
     * At this point we are ready to add everything to the real outbound.
     * Lock the node, if this fails because the node is busy we abort
     * and try to add at a later time.
     */
    if (nodes.Session_out == S_DIR) {
	if (islocked(nodes.Dir_out_clock, nodes.Dir_out_chklck, nodes.Dir_out_waitclr, 'p')) {
	    Syslog('+', "Mail and files stay in queue, will be added later");
	    if (noden.domain)
		free(noden.domain);
	    free(temp);
	    return;
	} else {
	    if (! setlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck, 'p')) {
		Syslog('+', "Mail and files stay in queue, will be added later");
		if (noden.domain)
		    free(noden.domain);
		free(temp);
		return;
	    }
	}
    } else {
	if (nodelock(&noden, mypid)) {
	    Syslog('+', "Mail and files stay in queue, will be added later");
	    if (noden.domain)
		free(noden.domain);
	    free(temp);
	    return;
	}
    }

    /*
     * Create arcmail filename for this node.
     */
    Now = time(NULL);
    arcfile = calloc(PATH_MAX, sizeof(char));
    if (nodes.Session_out == S_DIR) {

	ptm = localtime(&Now);
	ext = dow[ptm->tm_wday];

	if (!nodes.ARCmailCompat && (nodes.Aka[0].zone != noden.zone)) {
	    /*
	     * Generate ARCfile name from the CRC of the ASCII string of the node address.
	     */
	    snprintf(arcfile, PATH_MAX, "%s/%08x.%s0", nodes.Dir_out_path, StringCRC32(ascfnode(&noden, 0x1f)), ext);
	} else {
	    bestaka = bestaka_s(&noden);

	    if (noden.point) {
		snprintf(arcfile, PATH_MAX, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff,
			((bestaka->node) - (noden.node) + (noden.point)) & 0xffff, ext);
	    } else if (bestaka->point) {
		/*
		 * Inserted the next code for if we are a point,
		 * I hope this is ARCmail 0.60 compliant. 21-May-1999
		 */
		snprintf(arcfile, PATH_MAX, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff,
			((bestaka->node) - (noden.node) - (bestaka->point)) & 0xffff, ext);
	    } else {
		snprintf(arcfile, PATH_MAX, "%s/%04x%04x.%s0", nodes.Dir_out_path, ((bestaka->net) - (noden.net)) & 0xffff,
			((bestaka->node) - (noden.node)) &0xffff, ext);
	    }
	}
    } else {
	snprintf(arcfile, PATH_MAX, "%s", arcname(&noden, nodes.Aka[0].zone, nodes.ARCmailCompat));
    }

    /*
     * If there is a mailpkt.qqq file, close it and rename it.
     */
    pktfile = calloc(PATH_MAX, sizeof(char));
    fname   = calloc(PATH_MAX, sizeof(char));
    snprintf(fname, PATH_MAX, "%s/mailpkt.qqq", temp);
    if (access(fname, W_OK) == 0) {
	snprintf(pktfile, PATH_MAX, "%s/%08x.pkt", temp, sequencer());
	if (rename(fname, pktfile)) {
	    WriteError("$Can't rename %s to %s", fname, pktfile);
	} else {
	    /*
	     * Add zero word to end of .pkt file
	     */
	    if ((fp = fopen(pktfile, "a+")) == NULL) {
		WriteError("$Can't open %s", pktfile);
	    }
	    putc('\0', fp);
	    putc('\0', fp);
	    fsync(fileno(fp));
	    fclose(fp);
	}
    }
    free(fname);

    /*
     * Now all mail pkts are ready to archive
     */
    if ((dp = opendir(temp)) == NULL) {
	WriteError("$Can't open %s", temp);
	free(temp);
	free(arcfile);
	if (nodes.Session_out == S_DIR)
	    remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck, 'p');
	else
	    nodeulock(&noden, mypid);
	if (noden.domain)
	    free(noden.domain);
	return;
    }

    /*
     * Read all .pkt filenames, get the timestamp and add them
     * to the memory array for later sort on filedate.
     */ 
    while ((de = readdir(dp)))
	if ((strlen(de->d_name) == 12) && (strncasecmp(de->d_name+8,".pkt",4) == 0)) {
	    stat(de->d_name, &sbuf);
	    Syslog('p', "Adding %s to filelist", de->d_name);
	    fill_fdlist(&fdl, de->d_name, sbuf.st_mtime);
	}

    closedir(dp);
    sort_fdlist(&fdl);

    if (getarchiver(nodes.Archiver)) {
	flavor = 'f';
	if (nodes.Crash)
	    flavor = 'c';
	if (nodes.Hold)
	    flavor = 'h';
    } else {
	WriteError("Archiver %s not found", nodes.Archiver);
	if (noden.domain)
	    free(noden.domain);
	free(temp);
	free(arcfile);
	return;
    }

    first = TRUE;
    while ((fname = pull_fdlist(&fdl)) != NULL) {
	/*
	 *  Check the size of the existing archive if there is a size limit.
	 *  Change to new archive names if the existing is too large.
	 *  If the archive size is zero, it's an already sent archive, the
	 *  number will be bumped also.
	 *  If the archive is older then 6 days, the name is also bumped.
	 *  Do this until we find a new name or if the last digit is a '9' or 'z'.
	 *  Purge archives older then toss_days.
	 */
	nr = oldnr = '0';
	if (nodes.ARCmailAlpha)
	    maxnr = 'z';
	else
	    maxnr = '9';
	Attach = FALSE;

	for (;;) {
	    fsize = file_size(arcfile);
	    fage  = (int)((Now - file_time(arcfile)) / 86400);

	    if (fsize == -1L) {
		Attach = TRUE;
		break;
	    }

	    if (fsize == 0L) {
		if ((fage > 6) && (nr < maxnr)) {
		    /*
		     * Remove truncated ARCmail files older then 6 days.
		     */
		    unlink(arcfile);
		    fsize = -1L;
		    Attach = TRUE;
		    break;
		}

		/*
		 * Increase filename extension if there is a truncated file of today.
		 */
		if (nr < maxnr) {
		    nr++;
		    if (nr == ('9' +1))
			nr = 'a';
		    arcfile[strlen(arcfile) -1] = nr;
		} else {
		    Syslog('!', "Warning: archive filename extensions exhausted for today");
		    break;
		}
	    } else if (CFG.maxarcsize && (fsize > (CFG.maxarcsize * 1024)) && (nr < maxnr)) {
		/*
		 * Use a new ARCmail file if the last one is too big.
		 */
		nr++;
		if (nr == ('9' +1))
		    nr = 'a';
		arcfile[strlen(arcfile) -1] = nr;
	    }

	    fsize = file_size(arcfile);
	    fage  = (int)((Now - file_time(arcfile)) / 86400);

	    if ((fsize > 0L) && (fage > 6) && (nr < maxnr)) {
		/*
		 * If there is ARCmail of a week old or older, add mail
		 * to a new ARCmail bundle.
		 */
		nr++;
		if (nr == ('9' +1))
		    nr = 'a';
		arcfile[strlen(arcfile) -1] = nr;
	    }

	    if (oldnr == nr)
		break;
	    else
		oldnr = nr;
	}

	fsize = file_size(arcfile);

	/*
	 * If arcfile names were exhausted then the file ending on a z could still
	 * be in the outbound but truncated if it has been sent. Since we are
	 * reusing that filename (not a good solution) we must erase it or the
	 * archiver program will complain.
	 */
	if (fsize == 0L) {
	    unlink(arcfile);
	    Attach = TRUE;
	}

	if (first) {
	    Syslog('+', "Pack ARCmail for %s via %s with %s", aka2str(nodenr), ascfnode(&noden, 0x1f), nodes.Archiver);
	    if (!do_quiet) {
		printf("\rAdding ARCmail for %s                      ", ascfnode(&noden, 0x1f));
		fflush(stdout);
	    }
	    first = FALSE;
	    flushed = TRUE;
	}

	if (execute_str(archiver.marc, arcfile, fname, (char *)"/dev/null", (char *)"/dev/null", (char *)"/dev/null") == 0) {
	    unlink(fname);
	} else {
	    WriteError("Can't add %s to ARCmail archive", fname);
	    Attach = FALSE;
	}

	/*
	 * Change filemode so downlink has rights to the file.
	 */
	if (nodes.Session_out == S_DIR)
	    chmod(arcfile, 0660);
	
	/*
	 * Attach file to .flo, not for FTP or Directory sessions.
	 */
	if (Attach && nodes.Session_out == S_DIRECT)
	    attach(noden, arcfile, TFS, flavor);
    }

    /*
     * Open directory again.
     */
    if ((dp = opendir(temp)) == NULL) {
	WriteError("$Can't open %s", temp);
	free(temp);
	free(arcfile);
	if (nodes.Session_out == S_DIR)
	    remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck, 'p');
	else
	    nodeulock(&noden, mypid);
	if (noden.domain)
	    free(noden.domain);
	return;
    }

    /*
     * Read all other mail filenames, get the timestamp and add them
     * to the memory array for later sort on filedate.
     */ 
    while ((de = readdir(dp)))
	if ((strlen(de->d_name) == 11) && (strncasecmp(de->d_name,"mailpkt.",8) == 0)) {
	    stat(de->d_name, &sbuf);
	    Syslog('p', "Adding %s to filelist", de->d_name);
	    fill_fdlist(&fdl, de->d_name, sbuf.st_mtime);
	}

    closedir(dp);
    sort_fdlist(&fdl);

    first = TRUE;
    while ((fname = pull_fdlist(&fdl)) != NULL) {
	if (first) {
	    Syslog('+', "Pack unpacked mail for %s via %s", aka2str(nodenr), ascfnode(&noden, 0x1f));
	    if (!do_quiet) {
		printf("\rAdding netmail for %s                      ", ascfnode(&noden, 0x1f));
		fflush(stdout);
	    }
	    first = FALSE;
	    flushed = TRUE;
	}

	snprintf(pktfile, PATH_MAX, "%s/%s", temp, fname);

	if (strstr(fname, ".ddd"))
	    flavor = 'd';
	else if (strstr(fname, ".ccc"))
	    flavor = 'c';
	else if (strstr(fname, ".hhh"))
	    flavor = 'h';
	else
	    flavor = 'o';

	if (nodes.Session_out == S_DIR) {
	    snprintf(arcfile, PATH_MAX, "%s/%08x.pkt", nodes.Dir_out_path, sequencer());
	} else {
	    snprintf(arcfile, PATH_MAX, "%s", pktname(&noden, flavor));
	}

	/*
	 *  Now we must see if there is already mail in the outbound.
	 *  If that's the case, we must skip the .pkt header from the queue
	 *  because there is already a .pkt header also, append to the
	 *  outbound 2 bytes before the end of file, this is the zero word.
	 */
	if ((inf = fopen(pktfile, "r")) != NULL) {
	    if (access(arcfile, R_OK) == -1) {
		ouf = fopen(arcfile, "w");  /* create new  */
		Syslog('p', "Create new %s", arcfile);
	    } else {
		ouf = fopen(arcfile, "r+"); /* open R/W    */
		fseek(ouf, -2, SEEK_END);   /* b4 0 word   */
		fseek(inf, 58, SEEK_SET);   /* skip header */
		Syslog('p', "Append to %s", arcfile);
	    }

	    if (ouf != NULL) {
		buf = malloc(16384);

		do {
		    bread = fread(buf, 1, 16384, inf);
		    fwrite(buf, 1, bread, ouf);
		} while (bread);

		free(buf);
		putc('\0', ouf);
		putc('\0', ouf);
		fsync(fileno(ouf));
		fclose(ouf);
		fclose(inf);
		unlink(pktfile);
	    } else {
		WriteError("$Can't open %s", arcfile);
		fclose(inf);
	    }
	}

	/*
	 * Change filemode so downlink has rights to the file.
	 */
	if (nodes.Session_out == S_DIR)
	    chmod(arcfile, 0660);
    }

    /*
     * Now add the files for the node, information is in the .filelist
     * file, this tells the location of the file and what to do with
     * it after it is sent.
     */
    snprintf(pktfile, PATH_MAX, "%s/.filelist", temp);
    if ((fp = fopen(pktfile, "r")) != NULL) {

	Syslog('+', "Adding files for %s via %s", aka2str(nodenr), ascfnode(&noden, 0x1f));
	if (!do_quiet) {
	    printf("\rAdding files for %s                        ", ascfnode(&noden, 0x1f));
	    fflush(stdout);
	    flushed = TRUE;
	}

	buf = calloc(PATH_MAX + 1, sizeof(char));

	while (fgets(buf, PATH_MAX, fp)) {
	    Striplf(buf);
	    Syslog('p', ".filelist: %s", buf);
	    flavor = buf[0];
	    p = strchr(buf, ' ');
	    p++;
	    if (strncmp(p, "LEAVE ", 6) == 0)
		mode = LEAVE;
	    else if (strncmp(p, "KFS ", 4) == 0)
		mode = KFS;
	    else if (strncmp(p, "TFS ", 4) == 0)
		mode = TFS;
	    else {
		WriteError("Syntax error in filelist \"%s\"", buf);
		mode = LEAVE;
	    }
	    p = strchr(p, ' ');
	    p++;
	    // Here is a extra now unused keyword.
	    p = strchr(p, ' ');
	    p++;

	    Syslog('p', "File attach %s to %s", p, ascfnode(&noden, 0x1f));
	    if (nodes.Session_out == S_DIRECT) {
		attach(noden, p, mode, flavor);
	    } else if (nodes.Session_out == S_DIR) {
		snprintf(arcfile, PATH_MAX, "%s/%s", nodes.Dir_out_path, Basename(p));
		if (mode == LEAVE) {
		    /*
		     * LEAVE file, so we copy this one.
		     */
		    rc = file_cp(p, arcfile);
		    Syslog('p', "file_cp(%s, %s) rc=%d", p, arcfile, rc);
		} else {
		    /*
		     * KFS or TFS, move file to node directory
		     */
		    rc = file_mv(p, arcfile);
		    Syslog('p', "file_mv(%s, %s) rc=%d", p, arcfile, rc);
		}
		chmod(arcfile, 0660);
	    }
	}

	free(buf);
	fclose(fp);
	unlink(pktfile);
    }

    /*
     * We are done, the queue is flushed, unlock the node.
     */
    if (nodes.Session_out == S_DIR)
	remlock(nodes.Dir_out_mlock, nodes.Dir_out_mklck, 'p');
    else
	nodeulock(&noden, mypid);

    if (noden.domain)
	free(noden.domain);
    free(temp);
    free(arcfile);
    free(pktfile);
    return;
}