Beispiel #1
0
int StartMsg(void)
{
    Syslog('m', "StartMsg()");
    if (!Msg_Open(newfiles.Area))
	return -1;

    if (!Msg_Lock(30L)) {
	Msg_Close();
	return -1;
    }
    Msg_New();

    CountPosted(newfiles.Area);

    chartran_init((char *)"CP437", get_ic_ftn(newfiles.charset), 'f');

    snprintf(Msg.From, 101, "%s", chartran(newfiles.From));
    snprintf(Msg.To, 101, "%s", chartran(newfiles.Too));
    if (MsgCount == 1) {
	snprintf(Msg.Subject, 101, "%s", chartran(newfiles.Subject));
	TotalSize = TotalFiles = 0;
    } else
	snprintf(Msg.Subject, 101, "%s #%d", chartran(newfiles.Subject), MsgCount);
    snprintf(Msg.FromAddress, 101, "%s", aka2str(newfiles.UseAka));
    Msg.Written = time(NULL);
    Msg.Arrived = time(NULL);
    Msg.Local = TRUE;
    Msg.Echomail = TRUE;

    /*
     * Start message text including kludges
     */
    Msg_Id(newfiles.UseAka);
    Msg_Pid(newfiles.charset);
    return Msg_Top(newfiles.Template, newfiles.Language, newfiles.UseAka);
}
Beispiel #2
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;
}
Beispiel #3
0
void retr_msg(int msgnum)
{
    char	    *p, *q, temp[PATH_MAX], *base;
    int		    Header;
    unsigned int    crc = -1;

    snprintf(temp, 81, "RETR %d\r\n", msgnum);
    if (pop3_cmd(temp) == 0) {
	Msg_New();
	Header = TRUE;
	snprintf(temp, PATH_MAX, "%s/%s/mailbox", CFG.bbs_usersdir, exitinfo.Name);
	base = xstrcpy(temp);
	Open_Msgbase(base, 'w');
	Msg.Arrived = time(NULL) - (gmt_offset((time_t)0) * 60);
	Msg.Private = TRUE;
	while (TRUE) {
	    p = pop3_receive();
	    if ((p[0] == '.') && (strlen(p) == 1)) {
		break;
	    } else {
		if (Header) {
		    /*
		     *  Check the primary message header lines.
		     */
		    if (strncmp(p, "To: ", 4) == 0) {
			if (strlen(p) > 104)
			    p[104] = '\0';
			snprintf(Msg.To, 101, "%s", p+4);
		    }
		    if (strncmp(p, "From: ", 6) == 0) {
		        if (strlen(p) > 106)
			    p[106] = '\0';
			snprintf(Msg.From, 101, "%s", p+6);
		    }
		    if (strncmp(p, "Subject: ", 9) == 0) {
			if (strlen(p) > 109)
			    p[109] = '\0';
			snprintf(Msg.Subject, 101, "%s", p+9);
			mbse_CleanSubject(Msg.Subject);
		    }
		    if (strncmp(p, "Date: ", 6) == 0)
			Msg.Written = parsedate(p+6, NULL) - (gmt_offset((time_t)0) * 60);
		    if (strncmp(p, "Message-Id: ", 12) == 0) {
			q = xstrcpy(p+12);
			Msg.MsgIdCRC = upd_crc32(q, crc, strlen(q));
			free(q);
		    }
		    Msg.ReplyCRC = 0xffffffff;
		    if (strlen(p) == 0) {
			Header = FALSE;
		    } else {
			snprintf(temp, PATH_MAX, "\001%s", p);
			MsgText_Add2(temp);
		    }
		} else {
		    MsgText_Add2(p);
		}
	    }
	}
	Msg_AddMsg();
	Msg_UnLock();
	Close_Msgbase(base);
	free(base);
	snprintf(temp, 81, "DELE %d\r\n", msgnum);
	pop3_cmd(temp);
    } else {
	WriteError("POP3: Can't retrieve message %d", msgnum);
    }
}
Beispiel #4
0
void Write_Email(void)
{
    faddr   *Dest = NULL;
    int	    i;
    char    *orgbox;

    if (HasNoEmail())
	return;

    orgbox = xstrcpy(sMailbox);
    SetEmailArea((char *)"mailbox");

    WhosDoingWhat(READ_POST, NULL);
    clear();

    for (i = 0; i < (TEXTBUFSIZE + 1); i++)
	Message[i] = (char *) calloc(MAX_LINE_LENGTH +1, sizeof(char));
    Line = 1;

    Msg_New();

    Enter(1);
    colour(LIGHTBLUE, BLACK);
    /* Posting message in area: */
    pout(LIGHTBLUE, BLACK, (char *) Language(156));
    PUTSTR((char *)"\"mailbox\"");
    Enter(2);

    /* From   : */
    pout(YELLOW, BLACK, (char *) Language(157));
    if (CFG.EmailMode != E_PRMISP) {
	/*
	 * If not permanent connected to the internet, use fidonet.org style addressing.
	 */
	Dest = fido2faddr(CFG.EmailFidoAka);
	snprintf(Msg.From, 101, "%s@%s (%s)", exitinfo.sUserName, ascinode(Dest, 0x2f), exitinfo.sUserName);
    } else
	snprintf(Msg.From, 101, "%s@%s (%s)", exitinfo.Name, CFG.sysdomain, exitinfo.sUserName);
    
    for (i = 0; i < strlen(Msg.From); i++) {
        if (Msg.From[i] == ' ')
            Msg.From[i] = '_';
        if (Msg.From[i] == '@')
            break;
    }
    
    pout(CFG.MsgInputColourF, CFG.MsgInputColourB, Msg.From);
    Syslog('b', "Setting From: %s", Msg.From);
    Enter(1);

    /* To     : */
    pout(YELLOW, BLACK, (char *) Language(158));
    colour(CFG.MsgInputColourF, CFG.MsgInputColourB);
    alarm_on();
    GetstrU(Msg.To, 63);

    if ((strcmp(Msg.To, "")) == 0) {
	for (i = 0; i < (TEXTBUFSIZE + 1); i++)
	    free(Message[i]);
	SetEmailArea(orgbox);
	free(orgbox);
	return;
    }

    /* Subject  :  */
    pout(YELLOW, BLACK, (char *) Language(161));
    colour(CFG.MsgInputColourF, CFG.MsgInputColourB);
    alarm_on();
    GetstrP(Msg.Subject, 65, 0);
    mbse_CleanSubject(Msg.Subject);

    if ((strcmp(Msg.Subject, "")) == 0) {
	Enter(1);
	/* Abort Message [y/N] ?: */
	pout(CYAN, BLACK, (char *) Language(162));
	alarm_on();

	if (toupper(Readkey()) == Keystroke(162, 0)) {
	    for (i = 0; i < (TEXTBUFSIZE + 1); i++)
		free(Message[i]);
	    SetEmailArea(orgbox);
	    free(orgbox);
	    return;
	}
    }

    Msg.Private = TRUE;

    if (Edit_Msg()) {
	Save_Email(FALSE);
    }

    for (i = 0; i < (TEXTBUFSIZE + 1); i++)
	free(Message[i]);

    SetEmailArea(orgbox);
    free(orgbox);
}
Beispiel #5
0
/*
 *  Reply message, in Msg.From and Msg.Subject must be the
 *  name to reply to and the subject.
 */
void Reply_Email(int IsReply)
{
    int     i, j, x;
    char    to[101], from[101], subj[101], msgid[101], replyto[101], replyaddr[101], *tmp, *buf, qin[9], temp[81];
    faddr   *Dest = NULL;

    snprintf(from, 101, "%s", Msg.To);
    snprintf(to, 101, "%s", Msg.From);
    snprintf(replyto, 101, "%s", Msg.ReplyTo);
    snprintf(replyaddr, 101, "%s", Msg.ReplyAddr);

    if (strncasecmp(Msg.Subject, "Re:", 3) && IsReply) {
	snprintf(subj, 101, "Re: %s", Msg.Subject);
    } else {
	snprintf(subj, 101, "%s", Msg.Subject);
    }
    mbse_CleanSubject(subj);
    Syslog('m', "Reply msg to %s, subject %s", to, subj);
    Syslog('m', "Msgid was %s", Msg.Msgid);
    snprintf(msgid, 101, "%s", Msg.Msgid);

    x = 0;
    Line = 1;
    WhosDoingWhat(READ_POST, NULL);
    clear();
    snprintf(temp, 81, "   %-70s", sMailbox);
    pout(BLUE, LIGHTGRAY, temp);
    snprintf(temp, 81, "#%-5u", EmailBase.Highest + 1);
    pout(RED, LIGHTGRAY, temp);
    Enter(1);

    colour(CFG.HiliteF, CFG.HiliteB);
    if (utf8)
	chartran_init((char *)"CP437", (char *)"UTF-8", 'B');
    PUTSTR(chartran(sLine_str()));
    chartran_close();
    Enter(1);

    for (i = 0; i < (TEXTBUFSIZE + 1); i++)
	Message[i] = (char *) calloc(MAX_LINE_LENGTH +1, sizeof(char));
    Line = 1;
    Msg_New();

    snprintf(Msg.Replyid, sizeof(Msg.Replyid), "%s", msgid);
    snprintf(Msg.ReplyTo, sizeof(Msg.ReplyTo), "%s", replyto);
    snprintf(Msg.ReplyAddr, sizeof(Msg.ReplyAddr), "%s", replyaddr);

    /* From     : */
    pout(YELLOW, BLACK, (char *) Language(209));
    if (CFG.EmailMode != E_PRMISP) {
	/*
	 * If not permanent connected to the internet, use fidonet.org style addressing.
	 */
	Dest = fido2faddr(CFG.EmailFidoAka);
	snprintf(Msg.From, 101, "%s@%s (%s)", exitinfo.sUserName, ascinode(Dest, 0x2f), exitinfo.sUserName);
    } else {
	snprintf(Msg.From, 101, "%s@%s (%s)", exitinfo.Name, CFG.sysdomain, exitinfo.sUserName);
    }
    for (i = 0; i < strlen(Msg.From); i++) {
	if (Msg.From[i] == ' ')
	    Msg.From[i] = '_';
	if (Msg.From[i] == '@')
	    break;
    }
    pout(CFG.MsgInputColourF, CFG.MsgInputColourB, Msg.From);
    Enter(1);
    Syslog('b', "Setting From: %s", Msg.From);

    /* To       : */
    snprintf(Msg.To, 101, "%s", to);
    pout(YELLOW, BLACK, (char *) Language(208));
    pout(CFG.MsgInputColourF, CFG.MsgInputColourB, Msg.To);
    Enter(1);

    /* Enter to keep Subject. */
    pout(LIGHTRED, BLACK, (char *) Language(219));
    Enter(1);
    /* Subject  : */
    pout(YELLOW, BLACK, (char *) Language(210));
    snprintf(Msg.Subject, 101, "%s", subj);
    pout(CFG.MsgInputColourF, CFG.MsgInputColourB, Msg.Subject);

    x = strlen(subj);
    colour(CFG.MsgInputColourF, CFG.MsgInputColourB);
    GetstrP(subj, 50, x);

    if (strlen(subj))
	strcpy(Msg.Subject, subj);

    Msg.Private = TRUE;
    Enter(1);

//  Check_Attach();

    /*
     *  Quote original message now, format the original users
     *  initials into qin. If its a [email protected] the use the
     *  first 8 characters of the name part.
     */
    snprintf(Message[1], TEXTBUFSIZE +1, "%s wrote to %s:", to, from);
    memset(&qin, 0, sizeof(qin));
    if (strchr(to, '@')) {
	tmp = xstrcpy(strtok(to, "@"));
	tmp[8] = '\0';
	snprintf(qin, 9, "%s", tmp);
	free(tmp);
    } else {
	x = TRUE;
	j = 0;
	for (i = 0; i < strlen(to); i++) {
	    if (x && isalpha(to[i])) {
		qin[j] = to[i];
		j++;
		x = FALSE;
	    }
	    if (to[i] == ' ' || to[i] == '.')
		x = TRUE;
	    if (j == 6)
		break;
	}
    }

    Line = 2;
    tmp = calloc(PATH_MAX, sizeof(char));
    buf = calloc(TEXTBUFSIZE +1, sizeof(char));

    snprintf(tmp, PATH_MAX, "%s/%s/.quote", CFG.bbs_usersdir, exitinfo.Name);
    if ((qf = fopen(tmp, "r")) != NULL) {
	while ((fgets(buf, TEXTBUFSIZE, qf)) != NULL) {
	    Striplf(buf);
	    snprintf(Message[Line], TEXTBUFSIZE +1, "%s> %s", (char *)qin, buf);
	    Line++;
	    if (Line == TEXTBUFSIZE)
		break;
	}
	fclose(qf);
    } else
	WriteError("$Can't read %s", tmp);

    free(buf);
    free(tmp);

    if (Edit_Msg())
	Save_Email(IsReply);

    for (i = 0; i < (TEXTBUFSIZE + 1); i++)
	free(Message[i]);
}
Beispiel #6
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;
}