static char *tmpkname(void) { static char buf[16]; snprintf(buf,16,"%08x.pkt", sequencer()); return buf; }
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); }
/* * 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; }
/* * 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; }
/* * 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; }
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; }
/* * 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; }
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; }
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>(¶m_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; }
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; }
/* * 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; }
/* * 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; }
/* * Get output packet sequence number */ long outpkt_sequencer(void) { return sequencer(cf_p_seq_toss()) & 0x000fffff; }
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; }
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); }
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; }