Beispiel #1
0
/*
 * Load signature file in memory for editing.
 */
int loadsignature(void)
{
    char    *temp;
    FILE    *fp;
    int	    i;

    temp  = calloc(PATH_MAX, sizeof(char));
    snprintf(temp, PATH_MAX, "%s/%s/.signature", CFG.bbs_usersdir, exitinfo.Name);

    if ((fp = fopen(temp, "r")) == NULL) {
	WriteError("$Can't load %s", temp);
	free(temp);
	return FALSE;
    }
    
    clear();

    /* Edit message signature */
    pout(WHITE, BLACK, (char *) Language(107));
    Enter(2);

    Syslog('+', "%s will edit his .signature", exitinfo.sUserName);

    i = 0;
    while (fgets(temp, LENSIGLINES+1, fp)) {
	Striplf(temp);
	strcpy(sLiNE[i], temp);
	i++;
    }
    fclose(fp);
    free(temp);

    toprow();
    for (i = 0; i < MAXSIGLINES; i++) {
	snprintf(temp, 80, "%d:", i+1);
	pout(LIGHTRED, BLACK, temp);
	poutCR(CFG.MoreF, CFG.MoreB, sLiNE[i]);
    }
    botrow();

    return TRUE;
}
Beispiel #2
0
void ForwardFile(fidoaddr Node, fa_list *sbl)
{
    char	*subject = NULL, *fwdfile = NULL, *queuedir, *listfile, *ticfile = NULL, *ticname, flavor;
    FILE	*fp, *fi, *fl, *net;
    faddr	*dest, *routeto, *Fa, *Temp, *ba;
    int		i, z, n;
    time_t	now, ftime;
    fa_list	*tmp;

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

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

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

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

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

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

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

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

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

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

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

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

	    fprintf(fp, "Pw %s\r\n", nodes.Fpasswd);
	    fclose(fp);
	    fprintf(fl, "%c KFS NOR %s\n", flavor, ticfile);
	} else {
	    WriteError("$Can't create %s", ticfile);
	}
    }
    fsync(fileno(fl));
    fclose(fl);
    
    /*
     * Update the nodes statistic counters
     */
    StatAdd(&nodes.FilesSent, 1L);
    StatAdd(&nodes.F_KbSent, T_File.SizeKb);
    UpdateNode();
    SearchNode(Node);
    free(ticfile);
    free(fwdfile);
    free(queuedir);
    free(listfile);
    tidy_faddr(routeto);
}
Beispiel #3
0
void dlcount(void)
{
    char	*temp, *p, *q = NULL, *date, *file, *base, month[20];
    FILE	*fp;
    int		i, date_ok, file_ok, result, filesize;
    time_t	filedate = (time_t)0, lastcheck;
    struct tm	tm;
    
    temp = calloc(PATH_MAX, sizeof(char));
    
    /*
     * Check if we have a mark when we did this the last time.
     * If not, create one and don't do anything. Run the next time.
     */
    snprintf(temp, PATH_MAX, "%s/var/dlcount.stat", getenv("MBSE_ROOT"));
    if ((lastcheck = file_time(temp)) == -1) {
	Syslog('+', "Checking WWW downloads never done before, creating timestamp");
	if ((fp = fopen(temp, "a"))) {
	    fclose(fp);
	}
	free(temp);
	return;
    }
    
    /*
     * Refresh timestamp
     */
    unlink(temp);
    if ((fp = fopen(temp, "a"))) {
	fclose(fp);
    }

    date = calloc(81, sizeof(char));
    file = calloc(PATH_MAX, sizeof(char));
    base = calloc(PATH_MAX, sizeof(char));

    if (strlen(CFG.www_logfile) && (fp = fopen(CFG.www_logfile, "r"))) {

	/*
	 * Check apache logfile
	 */
	if (!do_quiet)
	    printf("Checking WWW downloads\n");
	Syslog('+', "Checking WWW downloads");

	while (fgets(temp, PATH_MAX-1, fp)) {
	    date_ok = file_ok = FALSE;
	    memset(date, 0, 80);
	    memset(file, 0, PATH_MAX);
	    memset(base, 0, PATH_MAX);
	    Striplf(temp);

	    /*
	     * Parse logline, be aware for lots of garbage created by systems
	     * that try to compromise the webserver.
	     */
//	    Syslog('f', "%s", printable(temp, 100));
	    p = strchr(temp, '[');
	    if (p) {
		q = strchr(p, ']');
		if (q && ((q-p) < 40)) {
		    strncpy(date, p+1, q - p - 1);
		    tm.tm_mday = atoi(strtok(date, "/\0"));
		    snprintf(month, 20, "%s", strtok(NULL, "/\0"));
		    for (i = 0; i < 12; i++)
			if (strncasecmp(months[i], month, 3) == 0)
			    break;
		    tm.tm_mon = i;
		    tm.tm_year = atoi(strtok(NULL, ":\0")) - 1900;
		    tm.tm_hour = atoi(strtok(NULL, ":\0"));
		    tm.tm_min  = atoi(strtok(NULL, ":\0"));
		    tm.tm_sec  = atoi(strtok(NULL, ":\0"));
		    filedate = mktime(&tm);
		    if (filedate > lastcheck)
			date_ok = TRUE;
		}
	    }
	    if (date_ok && (p = strchr(temp, '"'))) {
		q = strchr(p+1, '"');
		if (q && ((q-p) < 128)) {
		    strncpy(file, p+1, q - p - 1);
		    if (strncmp(file, "GET ", 4) == 0) {
			if ((p = strstr(file, CFG.www_link2ftp))) {
			    snprintf(base, PATH_MAX, "%s%s", CFG.ftp_base, p + strlen(CFG.www_link2ftp));
			    for (i = strlen(base); i; i--) {
				if (base[i] == ' ') {
				    base[i] = '\0';
				    break;
				}
			    }
			    file_ok = TRUE;
			}
		    }
		}
	    }
	    if (file_ok) {
		p = strtok(q, (char *)" \0");
		result = atoi(strtok(NULL, (char *)" \0"));
		filesize = atoi(strtok(NULL, (char *)" \0"));
		if (result == 200) {
		    /*
		     * So far it seems that the file is possible downloaded from the bbs.
		     * Now search the download area and filerecord.
		     */
		    Syslog('f', "%s %s %d", rfcdate(filedate), base, filesize);
		    count_download(base, filedate, filesize, (char *)"WWW");
		}
	    }
	}
	fclose(fp);
    }

    if (strlen(CFG.ftp_logfile) && (fp = fopen(CFG.ftp_logfile, "r"))) {

	/*
	 * Check ftp logfile
	 */
	if (!do_quiet)
	    printf("Checking FTP downloads\n");
	Syslog('+', "Checking FTP downloads");

	while (fgets(temp, PATH_MAX-1, fp)) {
	    date_ok = file_ok = FALSE;
	    memset(date, 0, 80);
	    memset(file, 0, PATH_MAX);
	    memset(base, 0, PATH_MAX);
	    Striplf(temp);

	    /*
	     * Parse logline.
	     */
//	    Syslog('f', "%s", printable(temp, 100));
	    p = strtok(temp, " \0");	    /* Day of week	*/
	    p = strtok(NULL, " \0");	    /* Month		*/
	    for (i = 0; i < 12; i++)
		if (strncasecmp(months[i], p, 3) == 0)
		    break;
	    tm.tm_mon = i;
	    tm.tm_mday = atoi(strtok(NULL, " \0"));	    /* Day in month	*/
	    tm.tm_hour = atoi(strtok(NULL, ":\0"));	    /* Hour		*/
	    tm.tm_min  = atoi(strtok(NULL, ":\0"));	    /* Minute		*/
	    tm.tm_sec  = atoi(strtok(NULL, " \0"));	    /* Seconds		*/
	    tm.tm_year = atoi(strtok(NULL, " \0")) - 1900;  /* Year		*/
	    filedate = mktime(&tm);
	    if (filedate > lastcheck)
		date_ok = TRUE;
	    p = strtok(NULL, " \0");			    /* 0		*/
	    p = strtok(NULL, " \0");			    /* Remote host	*/
	    filesize = atoi(strtok(NULL, " \0"));	    /* Filesize		*/
	    p = strtok(NULL, " \0");			    /* Filename		*/
	    if (p == NULL)
		break;

	    snprintf(base, PATH_MAX, "%s", p);
	    if (date_ok) {
                /*
		 * So far it seems that the file is possible downloaded from the bbs.
		 * Now search the download area and filerecord.
		 */
		Syslog('f', "%s %s %d", rfcdate(filedate), base, filesize);
		count_download(base, filedate, filesize, (char *)"FTP");
	    }
	}
    }

    free(base);
    free(file);
    free(date);
    free(temp);
}
Beispiel #4
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 #5
0
void Masterlist()
{
    FILE	    *fp, *np, *fu, *nu, *pAreas, *pHeader;
    int		    AreaNr = 0, z, x = 0, New;
    unsigned int    AllFiles = 0, AllKBytes = 0, NewFiles = 0, NewKBytes = 0;
    unsigned int    AllAreaFiles, AllAreaBytes, popdown, down, NewAreaFiles, NewAreaBytes;
    char	    *sAreas, temp[PATH_MAX], pop[81];
    struct _fdbarea *fdb_area = NULL;

    sAreas	= calloc(PATH_MAX, sizeof(char));

    IsDoing("Create Allfiles list");

    snprintf(sAreas, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));

    if(( pAreas = fopen (sAreas, "r")) == NULL) {
	WriteError("Can't open File Areas File: %s", sAreas);
	mbse_colour(LIGHTGRAY, BLACK);
	die(MBERR_GENERAL);
    }
    fread(&areahdr, sizeof(areahdr), 1, pAreas);

    if (!do_quiet)
	printf("Processing file areas\n");

    if ((fp = fopen("allfiles.tmp", "a+")) == NULL) {
 	WriteError("$Can't open allfiles.tmp");
	die(MBERR_GENERAL);
    }
    if ((np = fopen("newfiles.tmp", "a+")) == NULL) {
	WriteError("$Can't open newfiles.tmp");
	fclose(fp);
	die(MBERR_GENERAL);
    }
    if ((fu = fopen("allfiles.ump", "a+")) == NULL) {
	WriteError("$Can't open allfiles.ump");
	fclose(fp);
	fclose(np);
	die(MBERR_GENERAL);
    }
    if ((nu = fopen("newfiles.ump", "a+")) == NULL) {
	WriteError("$Can't open newfiles.ump");
	fclose(fp);
	fclose(np);
	fclose(fu);
	die(MBERR_GENERAL);
    }

    chartran_init((char *)"CP437", (char *)"UTF-8", 'B');

    TopBox(fp, fu, TRUE);
    TopBox(np, nu, TRUE);
    snprintf(temp, 81, "All available files at %s", CFG.bbs_name);
    MidLine(temp, fp, fu, TRUE);
    snprintf(temp, 81, "New available files since %d days at %s", CFG.newdays, CFG.bbs_name);
    MidLine(temp, np, nu, TRUE);
    BotBox(fp, fu, TRUE);
    BotBox(np, nu, TRUE);

    snprintf(temp, PATH_MAX, "%s/etc/header.txt", getenv("MBSE_ROOT"));
    if (( pHeader = fopen(temp, "r")) != NULL) {
	Syslog('+', "Inserting %s", temp);

	while( fgets(temp, 80 ,pHeader) != NULL) {
	    Striplf(temp);
	    fprintf(fp, "%s\r\n", temp);
	    fprintf(np, "%s\r\n", temp);
	    fprintf(fu, "%s\r\n", chartran(temp));
	    fprintf(nu, "%s\r\n", chartran(temp));
	}
	fclose(pHeader);
    }

    while (fread(&area, areahdr.recsize, 1, pAreas) == 1) {
	AreaNr++;
	AllAreaFiles = 0;
	AllAreaBytes = 0;
	NewAreaFiles = 0;
	NewAreaBytes = 0;

	if (area.Available && (area.LTSec.level <= CFG.security.level)) {

	    Nopper();

	    if ((fdb_area = mbsedb_OpenFDB(AreaNr, 30)) == 0) {
		WriteError("Can't open Area %d (%s)! Skipping ...", AreaNr, area.Name);
	    } else {
		popdown = 0;
		while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
		    if (!fdb.Deleted) {
			/*
			 * The next is to reduce system load.
			 */
			x++;
			if (CFG.slow_util && do_quiet && ((x % 3) == 0))
			    msleep(1);
			AllFiles++;
			AllAreaFiles++;
			AllAreaBytes += fdb.Size;
			down = fdb.TimesDL;
			if (down > popdown) {
			    popdown = down;
			    snprintf(pop, 81, "%s", fdb.Name);
			}
			if (((t_start - fdb.UploadDate) / 84400) <= CFG.newdays) {
			    NewFiles++;
			    NewAreaFiles++;
			    NewAreaBytes += fdb.Size;
			}
		    }
		}

		AllKBytes += AllAreaBytes / 1024;
		NewKBytes += NewAreaBytes / 1024;
				
		/*
		 * If there are files to report do it.
		 */
		if (AllAreaFiles) {
		    TopBox(fp, fu, TRUE);
		    TopBox(np, nu, NewAreaFiles);

		    snprintf(temp, 81, "Area %d - %s", AreaNr, area.Name);
		    MidLine(temp, fp, fu, TRUE);
		    MidLine(temp, np, nu, NewAreaFiles);

		    snprintf(temp, 81, "File Requests allowed");
		    MidLine(temp, fp, fu, area.FileReq);
		    MidLine(temp, np, nu, area.FileReq && NewAreaFiles);

		    snprintf(temp, 81, "%d KBytes in %d files", AllAreaBytes / 1024, AllAreaFiles);
		    MidLine(temp, fp, fu, TRUE);
		    snprintf(temp, 81, "%d KBytes in %d files", NewAreaBytes / 1024, NewAreaFiles);
		    MidLine(temp, np, nu, NewAreaFiles);
		    if (popdown) {
			snprintf(temp, 81, "Most popular file is %s", pop);
			MidLine(temp, fp, fu, TRUE);
		    }

		    BotBox(fp, fu, TRUE);
		    BotBox(np, nu, NewAreaFiles);

		    fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET);
		    while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) {
			if (!fdb.Deleted) {
			    New = (((t_start - fdb.UploadDate) / 84400) <= CFG.newdays);

			    snprintf(temp, 81, "%s", fdb.LName);
			    WriteFiles(fp, fu, np, nu, New, temp);

			    snprintf(temp, 81, "%-12s%10u K %s [%04d] Uploader: %s", 
				fdb.Name, (int)(fdb.Size / 1024), StrDateDMY(fdb.UploadDate), fdb.TimesDL, 	 
				strlen(fdb.Uploader)?fdb.Uploader:"");
			    WriteFiles(fp, fu, np, nu, New, temp);

			    for (z = 0; z < 25; z++) {
				if (strlen(fdb.Desc[z])) {
				    if ((fdb.Desc[z][0] == '@') && (fdb.Desc[z][1] == 'X')) {
					snprintf(temp, 81, "                         %s", fdb.Desc[z]+4);
				    } else {
					snprintf(temp, 81, "                         %s", fdb.Desc[z]);
				    }
				    WriteFiles(fp, fu, np, nu, New, temp);
				}
			    }

			    if (strlen(fdb.Magic)) {
				snprintf(temp, 81, "                         Magic filerequest: %s", fdb.Magic);
				WriteFiles(fp, fu, np, nu, New, temp);
			    }
			    WriteFiles(fp, fu, np, nu, New, (char *)"");
			}
		    }
		}
		mbsedb_CloseFDB(fdb_area);
    		}
	}
    } /* End of While Loop Checking for Areas Done */

    fclose(pAreas);

    TopBox(fp, fu, TRUE);
    TopBox(np, nu, TRUE);
    snprintf(temp, 81, "Total %d files, %d KBytes", AllFiles, AllKBytes);
    MidLine(temp, fp, fu, TRUE);
    snprintf(temp, 81, "Total %d files, %d KBytes", NewFiles, NewKBytes);
    MidLine(temp, np, nu, TRUE);

    MidLine((char *)"", fp, fu, TRUE);
    MidLine((char *)"", np, nu, TRUE);

    snprintf(temp, 81, "Created by MBSE BBS v%s (%s-%s) at %s", VERSION, OsName(), OsCPU(), StrDateDMY(t_start));
    MidLine(temp, fp, fu, TRUE);
    MidLine(temp, np, nu, TRUE);

    BotBox(fp, fu, TRUE);
    BotBox(np, nu, TRUE);

    snprintf(temp, PATH_MAX, "%s/etc/footer.txt", getenv("MBSE_ROOT"));
    if(( pHeader = fopen(temp, "r")) != NULL) {
	Syslog('+', "Inserting %s", temp);

	while( fgets(temp, 80 ,pHeader) != NULL) {
	    Striplf(temp);
	    fprintf(fp, "%s\r\n", temp);
	    fprintf(np, "%s\r\n", temp);
	    fprintf(fu, "%s\r\n", chartran(temp));
	    fprintf(nu, "%s\r\n", chartran(temp));
	}
	fclose(pHeader);
    }

    fclose(fp);
    fclose(np);
    fclose(fu);
    fclose(nu);
    chartran_close();

    if ((rename("allfiles.tmp", "allfiles.txt")) == 0)
	unlink("allfiles.tmp");
    if ((rename("newfiles.tmp", "newfiles.txt")) == 0)
	unlink("newfiles.tmp");
    if ((rename("allfiles.ump", "allfiles.utf")) == 0)
	unlink("allfiles.ump");
    if ((rename("newfiles.ump", "newfiles.utf")) == 0)
	unlink("newfiles.ump");

    Syslog('+', "Allfiles: %ld, %ld MBytes", AllFiles, AllKBytes / 1024);
    Syslog('+', "Newfiles: %ld, %ld MBytes", NewFiles, NewKBytes / 1024);
    free(sAreas);
}
Beispiel #6
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;
}
Beispiel #7
0
/*
 *  Input a RFC message.
 */
int rfc2ftn(FILE *fp, faddr *recipient)
{
    char            sbe[128], *p, *q, *temp, *origin, newsubj[4 * (MAXSUBJ+1)], *oldsubj, *acup_a = NULL, *charset = NULL;
    int             i, rc, newsmode, seenlen, oldnet, chars_in = FTNC_NONE, chars_out = FTNC_NONE;
    rfcmsg          *msg = NULL, *tmsg, *tmp;
    ftnmsg          *fmsg = NULL;
    FILE            *ofp;
    fa_list         *sbl = NULL, *ptl = NULL, *tmpl;
    faddr           *ta, *fta;
    unsigned int    acup_n = 0;
    int             sot_kludge = FALSE, eot_kludge = FALSE, tinyorigin = FALSE;
    int             needsplit, hdrsize, datasize, splitpart, forbidsplit, rfcheaders;
    time_t          Now;

    temp = calloc(MAXHDRSIZE +1, sizeof(char));
    Syslog('m', "Entering rfc2ftn");
    if (recipient)
	Syslog('m', "Recipient: %s", ascfnode(recipient, 0xff));
    rewind(fp);
    msg = parsrfc(fp);

    newsmode = hdr((char *)"Newsgroups", msg) ?TRUE:FALSE;
    Syslog('m', "RFC message is %s", newsmode ? "news article":"e-mail message");

    if (newsmode) {
	news_in++;
	snprintf(currentgroup, 81, "%s", msgs.Newsgroup);
    } else
	email_in++;
    
    if (!CFG.allowcontrol) {
	if (hdr((char *)"Control",msg)) {
	    Syslog('+', "Rfc2ftn: Control message skipped");
	    tidyrfc(msg);
	    return 1;
	}
    }
    
    if ((fmsg = mkftnhdr(msg, newsmode, recipient)) == NULL) {
	WriteError("Rfc2ftn: unable to create FTN headers from RFC ones, aborting");
	tidyrfc(msg);
	return 1;
    }
    
    if (newsmode)
	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);
	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';
		} 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");
    }

    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;

    chars_in = find_rfc_charset(charset);
    chars_out = msgs.Charset;
    if (chars_in == FTNC_ERROR) {
	/*
	 * Not in standard tables, go ahead with the uppercase name
	 * and see if iconv will take it. It doesn't really matter if
	 * we support the incoming rfc charset,
	 */
	tu(charset);
	Syslog('m', "rfc2ftn: charset in: %s charset out: %s", charset, get_ic_ftn(chars_out));
	chartran_init(charset, get_ic_ftn(chars_out), 'm');
    } else {
	Syslog('m', "rfc2ftn: charset in: %s charset out: %s", get_ic_rfc(chars_in), get_ic_ftn(chars_out));
	chartran_init(get_ic_rfc(chars_in), get_ic_ftn(chars_out), 'm');
    }

    do {
	Syslog('m', "rfc2ftn: split loop, splitpart = %d", splitpart);
	datasize = 0;

	if (splitpart) {
	    snprintf(newsubj,4 * MAXSUBJ,"[part %d] ",splitpart+1);
	    strncat(newsubj,fmsg->subj,MAXSUBJ-strlen(newsubj));
	    Syslog('+', "Rfc2ftn: split message part %d", splitpart);
	} 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("$Rfc2ftn: Can't open second tmpfile");
	    tidyrfc(msg);
	    return 1;
	}

	if (newsmode) {
	    fprintf(ofp, "AREA:%s\n", msgs.Tag);
	} else {
	    if (fmsg->to->point != 0)
		fprintf(ofp, "\001TOPT %d\n", fmsg->to->point);
	    if (fmsg->from->point != 0)
		fprintf(ofp, "\001FMPT %d\n", fmsg->from->point);
		fprintf(ofp, "\001INTL %d:%d/%d %d:%d/%d\n", fmsg->to->zone, fmsg->to->net, fmsg->to->node,
				fmsg->from->zone, fmsg->from->net, fmsg->from->node);
	}

	if ((fmsg->msgid_a == NULL) || (fmsg->msgid_n == 0)) {
	    Syslog('!', "Rfc2ftn: warning, no MSGID %s %08lx", MBSE_SS(fmsg->msgid_a), fmsg->msgid_n);
	}

	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-FIDO %s (%s-%s)\n", VERSION, OsName(), OsCPU());
	    }
	}

	if (CFG.allowcontrol && (!hdr((char *)"X-FTN-ACUPDATE",msg)) && (p=hdr((char *)"Control",msg))) {
	    if (strstr(p,"cancel")) {
		ftnmsgid(p,&acup_a,&acup_n,fmsg->area);
		if (acup_a) {
		    hash_update_s(&acup_n,fmsg->area);
		    hdrsize += 26 + strlen(acup_a);
		    fprintf(ofp,"\1ACUPDATE: DELETE %s %08x\n", acup_a,acup_n);
		}
	    }
	}
	if ((!hdr((char *)"X-FTN-ACUPDATE",msg)) && (p=hdr((char *)"Supersedes",msg))) {
	    ftnmsgid(p,&acup_a,&acup_n,fmsg->area);
	    if (acup_a) {
		hash_update_s(&acup_n,fmsg->area);
		hdrsize += 26 + strlen(acup_a);
		fprintf(ofp,"\1ACUPDATE: MODIFY %s %08x\n", acup_a,acup_n);
	    }
	}
	if (!(hdr((char *)"X-FTN-Tearline", msg)) && !(hdr((char *)"X-FTN-TID", msg))) {
	    snprintf(temp, MAXHDRSIZE, " MBSE-FIDO %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);
		}


	    /*
	     *  Add the Received: header from this system to the mesage.
	     */
	    if (!newsmode) {
		Now = time(NULL);
		fprintf(ofp, "\1RFC-Received: by %s (mbfido) via RFC2FTN; %s\n", CFG.sysdomain, rfcdate(Now));
		hdrsize += 72+strlen(CFG.sysdomain);
	    }

	    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, 128, "%u/%u", CFG.aka[i].net, CFG.aka[i].node);
		    fill_list(&sbl, sbe, NULL);
		}
	    }
	    if (msgs.Aka.point == 0) {
		snprintf(sbe, 128, "%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,128," %u",tmpl->addr->node);
		    else
			snprintf(sbe,128," %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,128," %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,128,"%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,128," %u",tmpl->addr->node);
		    else
			snprintf(sbe,128," %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,128," %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 (newsmode)
	    rc = postecho(NULL, fmsg->from, fmsg->to, origin, fmsg->subj, fmsg->date, fmsg->flags, 0, ofp, FALSE, 0);
	else
	    rc = postnetmail(ofp, fmsg->from, fmsg->to, origin, fmsg->subj, fmsg->date, 
		    fmsg->flags, FALSE, fmsg->from->zone, fmsg->to->zone);

	Syslog('m', "rfc2ftn: message posted rc=%d", rc);

	free(origin);
        fclose(ofp);
    } while (needsplit);

    Syslog('m', "rfc2ftn: out of splitloop");
    chartran_close();

    free(temp);
    if (charset)
	free(charset);
    tidyrfc(msg);
    tidy_ftnmsg(fmsg);

    Syslog('m', "rfc2ftn: memory freed");

    UpdateMsgs();

    return 0;
}
Beispiel #8
0
/*
 * Init files database. Since version 0.51.2 the format is changed.
 * Check this and automagic upgrade the database.
 */
void InitFDB(void)
{
    int			    records, i;
    int			    Area = 0;
    char		    *temp, Magic[21];
    FILE		    *fp1, *fp2, *fil, *ft, *fp;
    DIR			    *dp;
    struct dirent	    *de;
    struct OldFILERecord    old;
    struct stat		    sb;
    struct _fdbarea	    *fdb_area = NULL;

    records = CountFilearea();
    if (records <= 0)
	return;
    
    temp = calloc(PATH_MAX, sizeof(char));
    snprintf(temp, PATH_MAX, "%s/etc/fareas.data", getenv("MBSE_ROOT"));
    if ((fil = fopen(temp, "r")) != NULL) {
	fread(&areahdr, sizeof(areahdr), 1, fil);

	while (fread(&area, areahdr.recsize, 1, fil)) {
	    Area++;
	    if (area.Available) {
		snprintf(temp, PATH_MAX, "%s/var/fdb/fdb%d.data", getenv("MBSE_ROOT"), Area);
		if ((fp1 = fopen(temp, "r")) != NULL) {
		    /*
		     * Old area available, upgrade.
		     */
		    snprintf(temp, PATH_MAX, "%s/var/fdb/file%d.data", getenv("MBSE_ROOT"), Area);
		    if ((fp2 = fopen(temp, "w+")) == NULL) {
			WriteError("$Can't create %s", temp);
		    } else {
			fdbhdr.hdrsize = sizeof(fdbhdr);
			fdbhdr.recsize = sizeof(fdb);
			fwrite(&fdbhdr, sizeof(fdbhdr), 1, fp2);

			while (fread(&old, sizeof(old), 1, fp1)) {
			    Nopper();
			    memset(&fdb, 0, fdbhdr.recsize);
			    strncpy(fdb.Name, old.Name, sizeof(fdb.Name) -1);
			    strncpy(fdb.LName, old.LName, sizeof(fdb.LName) -1);
			    snprintf(temp, PATH_MAX, "%s/etc/tic.data", getenv("MBSE_ROOT"));
			    if ((ft = fopen(temp, "r")) != NULL) {
				fread(&tichdr, sizeof(tichdr), 1, ft);
				while (fread(&tic, tichdr.recsize, 1, ft)) {
				    if (StringCRC32(tic.Name) == old.TicAreaCRC) {
					strncpy(fdb.TicArea, tic.Name, sizeof(fdb.TicArea) -1);
					break;
				    }
				    fseek(ft, tichdr.syssize, SEEK_CUR);
				}
				fclose(ft);
			    }
			    fdb.Size = old.Size;
			    fdb.Crc32 = old.Crc32;
			    strncpy(fdb.Uploader, old.Uploader, sizeof(fdb.Uploader) -1);
			    fdb.UploadDate = old.UploadDate;
			    fdb.FileDate = old.FileDate;
			    fdb.LastDL = old.LastDL;
			    fdb.TimesDL = old.TimesDL + old.TimesFTP + old.TimesReq;
			    strncpy(fdb.Password, old.Password, sizeof(fdb.Password) -1);
			    for (i = 0; i < 25; i++)
				strncpy(fdb.Desc[i], old.Desc[i], 48);

			    /*
			     * Search the magic directory to see if this file is a magic file.
			     */
			    snprintf(temp, 81, "%s", CFG.req_magic);
			    if ((dp = opendir(temp)) != NULL) {
				while ((de = readdir(dp))) {
				    if (de->d_name[0] != '.') {
					snprintf(temp, PATH_MAX, "%s/%s", CFG.req_magic, de->d_name);
					/*
					 * Only regular files without execute permission are magic requests.
					 */
					if ((lstat(temp, &sb) != -1) && (S_ISREG(sb.st_mode)) && (! (sb.st_mode & S_IXUSR))) {
					    if ((fp = fopen(temp, "r"))) {
						fgets(Magic, sizeof(Magic) -1, fp);
						Striplf(Magic);
						if ((strcasecmp(Magic, fdb.Name) == 0) || (strcasecmp(Magic, fdb.LName) == 0)) {
						    strncpy(fdb.Magic, de->d_name, sizeof(fdb.Magic) -1);
						}
						fclose(fp);
					    }
					}
				    }
				}
				closedir(dp);
			    } else {
				WriteError("$Can't open directory %s", temp);
			    }
			    fdb.Deleted = old.Deleted;
			    fdb.NoKill = old.NoKill;
			    fdb.Announced = old.Announced;
			    fdb.Double = old.Double;
			    fwrite(&fdb, fdbhdr.recsize, 1, fp2);
			}
			fclose(fp2);
			Syslog('+', "Upgraded file area database %d", Area);
		    }
		    fclose(fp1);
		    snprintf(temp, PATH_MAX, "%s/var/fdb/fdb%d.data", getenv("MBSE_ROOT"), Area);
		    unlink(temp);
		} // Old area type upgrade.

		/*
		 * Current area, check
		 */
		if ((fdb_area = mbsedb_OpenFDB(Area, 30)) == NULL)
		    WriteError("InitFDB(): database area %d might be corrupt", Area);
		else
		    mbsedb_CloseFDB(fdb_area);
	    }
	}
	fclose(fil);
    }
    free(temp);
}
Beispiel #9
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 #10
0
/*
 *  Save the message to disk.
 */
int Save_Email(int IsReply)
{
    int             i;
    char            *p, *temp;
    unsigned int    crc = -1;
    int		    id;
    FILE	    *fp;

    if (Line < 2)
	return TRUE;

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

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

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

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

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

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

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

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

    do_mailout = TRUE;
    LC_Wrote = TRUE;

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

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

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

    free(temp);
    Close_Msgbase(sMailpath);

    return TRUE;
}
Beispiel #11
0
void ImportOneline(void)
{
    FILE    *Imp, *pOneline;
    int	    recno = 0, skipped = 0;
    struct  tm *l_date;
    char    *temp, buf[12];
    time_t  Time;

    clr_index();
    set_color(WHITE, BLACK);
    ftnd_mvprintw(5, 6, "8.7.3  IMPORT ONELINERS");
    set_color(CYAN, BLACK);
    temp = calloc(PATH_MAX, sizeof(char));
    memset(temp, 0, sizeof(temp));
    strcpy(temp, edit_str(21, 6,64, temp, (char *)"The ^full path and filename^ of the file to import"));
    if (strlen(temp) == 0) {
	free(temp);
	return;
    }

    working(1, 0, 0);
    if (config_read() == -1) {
	working(2, 0, 0);
	free(temp);
	return;
    }

    if ((Imp = fopen(temp, "r")) == NULL) {
	working(2, 0, 0);
	ftnd_mvprintw(21, 6, temp);
	readkey(22, 6, LIGHTGRAY, BLACK);
	free(temp);
	return;
    }

    snprintf(temp, PATH_MAX, "%s/etc/oneline.data", getenv("FTND_ROOT"));

    /*
     * Check if database exists, if not create a new one
     */
    if ((pOneline = fopen(temp, "r" )) == NULL) {
	if ((pOneline = fopen(temp, "w")) != NULL) {
	    olhdr.hdrsize = sizeof(olhdr);
	    olhdr.recsize = sizeof(ol);
	    fwrite(&olhdr, sizeof(olhdr), 1, pOneline);
	    fclose(pOneline);
	}
    } else
	fclose(pOneline);

    /*
     * Open database for appending
     */
    if ((pOneline = fopen(temp, "a+")) == NULL) {
	working(2, 0, 0);
	fclose(Imp);
	ftnd_mvprintw(21, 6, temp);
	readkey(22, 6, LIGHTGRAY, BLACK);
	free(temp);
	return;
    }

    Time = time(NULL);
    l_date = localtime(&Time);
    snprintf(buf, 12, "%02d-%02d-%04d", l_date->tm_mday, l_date->tm_mon+1, l_date->tm_year+1900);

    while ((fgets(temp, 80, Imp)) != NULL) {
	Striplf(temp);
	if ((strlen(temp) > 0) && (strlen(temp) < 69)) {
	    memset(&ol, 0, sizeof(ol));
	    strcpy(ol.Oneline, temp);
	    strcpy(ol.UserName, CFG.sysop_name);
	    strcpy(ol.DateOfEntry, buf);
	    ol.Available = TRUE;
	    fwrite(&ol, sizeof(ol), 1, pOneline);
	    recno++;
	} else {
	    skipped++;
	}
    }

    fclose(Imp);
    fclose(pOneline);

    snprintf(temp, 81, "Imported %d oneliners, skipped %d long/empty lines", recno, skipped);
    Syslog('+', temp);
    ftnd_mvprintw(21, 6, temp);
    readkey(21, 7 + strlen(temp), LIGHTGRAY, BLACK);
    free(temp);
}
Beispiel #12
0
/*
 * Import 1 message, forward if needed.
 * pkt_from, from, to, subj, orig, mdate, flags, cost, file
 *
 *  0 - All Seems Well.
 *  1 - Can't access messagebase.
 *  2 - Cannot open mareas.data
 *  3 - Echomail without Origin line.
 *  4 - Echomail from unknown node or disconnected node.
 *  5 - Locking error.
 *  6 - Unknown echomail area.
 *
 */
int importmsg(faddr *p_from, faddr *f, faddr *t, char *orig, char *subj, time_t mdate, 
	int flags, int cost, FILE *fp, unsigned int tzone)
{
    char	*buf, *marea = NULL;
    int		echomail = FALSE, rc = 0, bad = 0, FirstLine, size = 0;
    sysconnect	Link;

    if (CFG.slow_util && do_quiet)
	msleep(1);

    memset(&Link, 0, sizeof(Link));

    /*
     * Increase uplink's statistic counter.
     */
    Link.aka.zone  = p_from->zone;
    Link.aka.net   = p_from->net;
    Link.aka.node  = p_from->node;
    Link.aka.point = p_from->point;
    if (SearchNode(Link.aka)) {
	StatAdd(&nodes.MailRcvd, 1);
	UpdateNode();
	SearchNode(Link.aka);
    }

    buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
    marea = NULL;

    /*
     * First read the message for kludges we need.
     */
    rewind(fp);

    FirstLine = TRUE;
    while ((fgets(buf, MAX_LINE_LENGTH, fp)) != NULL) {

	size += strlen(buf);
	Striplf(buf);

	/*
	 * Check if message is echomail and if the areas exists.
	 */
	if (FirstLine && (!strncmp(buf, "AREA:", 5))) {

	    marea = xstrcpy(tu(buf + 5));

	    if (orig == NULL) {
		Syslog('!', "Echomail without Origin line");
		echo_bad++;
		echo_in++;
		bad = 3;
		free(buf);
		free(marea);
		return 3;
	    }

	    if (!SearchMsgs(marea)) {
		UpdateNode();
		Syslog('m', "Unknown echo area %s", marea);
		if (!create_msgarea(marea, p_from)) {
		    WriteError("Create echomail area %s failed", marea);
		    bad = 6;
		}
		if (bad == 0) {	
		    SearchNode(Link.aka);
		    if (!SearchMsgs(marea)) {
			WriteError("Unknown echo area %s", marea);
			echo_bad++;
			echo_in++;
			bad = 4;
			free(marea);
			free(buf);
			return 4;
		    }
		}	    
	    }
	    echomail = TRUE;
	    free(marea);
	}
	if (*buf != '\001')
	    FirstLine = FALSE;
    } /* end of checking kludges */

    if (size >= 32768) {
	if (echomail) {
	    Syslog('!', "WARNING: Echo area %s from \"%s\" subj \"%s\" size %d", msgs.Tag, f->name, subj, size);
	} else {
	    Syslog('!', "WARNING: Net from \"%s\" subj \"%s\" size %d", f->name, subj, size);
	}
    }

    if (echomail) {
	if (bad) {
	    /*
	     * Bad, load the badmail record
	     */
	    if ((strlen(CFG.badboard) == 0) && !SearchBadBoard()) {
		Syslog('+', "No badmail area, killing message");
		free(buf);
		return 6;
	    }
	    UpdateMsgs();
	}
	/*
	 * At this point, the destination zone is not yet set.
	 */
	if (!t->zone)
	    t->zone = tzone;
	rc = postecho(p_from, f, t, orig, subj, mdate, flags, cost, fp, TRUE, bad);
    } else
	rc = postnetmail(fp, f, t, orig, subj, mdate, flags, TRUE, p_from->zone, tzone);

    free(buf);
    return rc;
}
Beispiel #13
0
/*
 *  Post netmail message for temp file. The tempfile is an FTN style message.
 *
 *  0 - All seems well.
 *  1 - Can't access messagebase.
 *  2 - Can't find netmail board.
 *
 */
int postnetmail(FILE *fp, faddr *f, faddr *t, char *orig, char *subject, time_t mdate, 
	int flags, int DoPing, unsigned int fzone, unsigned int tzone)
{
    char    	*p, *msgid = NULL, *reply = NULL, *flagstr = NULL;
    char    	name[37], *buf, *l, *r, *q, System[37], ext[4];
    int		result = 1, email = FALSE, fmpt = 0, topt = 0;
    faddr	*ta, *ra;
    fidoaddr	na, routeto, Orig;
    FILE	*sfp, *net;
    time_t	now;
    struct tm	*tm;

    Syslog('m', "Post netmail from: %s", ascfnode(f, 0xff));
    Syslog('m', "Post netmail to  : %s", ascfnode(t, 0xff));
    Syslog('m', "Post netmail subj: %s", MBSE_SS(subject));
    net_in++;

    /*
     *  Extract MSGID and REPLY kludges from this netmail.
     */
    buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
    rewind(fp);
    while ((fgets(buf, MAX_LINE_LENGTH, fp)) != NULL) {
	Striplf(buf);
	Syslogp('M', printable(buf, 0));
	if (!strncmp(buf, "\001MSGID: ", 8)) {
	    msgid = xstrcpy(buf + 8);
	    /*
	     *  Extra test to see if the mail comes from a pointaddress.
	     */
	    l = strtok(buf," \n");
	    l = strtok(NULL," \n");
	    if ((ta = parsefnode(l))) {
		if (ta->net == f->net && ta->node == f->node && !fmpt && ta->point) {
		    Syslog('m', "Setting pointinfo (%d) from MSGID", ta->point);
		    fmpt = f->point = ta->point;
		}
		if ((ta->net == f->net) && (ta->node == f->node) && (f->zone == 0)) {
		    /*
		     * Missing zone info, maybe later we will see a INTL kludge or so, but for
		     * now, just in case we fix it. And we need that for some Aka collecting
		     * sysop who doesn't know how to configure his system right.
		     */
		    Syslog('m', "No from zone set, setting zone %d from MSGID", ta->zone);
		    f->zone = ta->zone;
		    /*
		     * 99.9 % chance that the destination zone is also missing.
		     */
		    if (t->zone == 0) {
			t->zone = ta->zone;
			Syslog('m', "No dest zone set, setting zone %d from MSGID", ta->zone);
		    }
		}
		tidy_faddr(ta);
	    }
	    if (msgid)
		free(msgid);
	    msgid = NULL;
	}
	if (!strncmp(buf, "\001FMPT", 5)) {
	    p = strtok(buf, " \n");
	    p = strtok(NULL, " \n");
	    fmpt = atoi(p);
	}
	if (!strncmp(buf, "\001TOPT", 5)) {
	    p = strtok(buf, " \n");
	    p = strtok(NULL, " \n");
	    topt = atoi(p);
	}
	if (!strncmp(buf, "\001REPLY: ", 8))
	    reply = xstrcpy(buf + 8);

	/*
	 * Check DOMAIN and INTL kludges
	 */
	if (!strncmp(buf, "\001DOMAIN", 7)) {
	    l = strtok(buf," \n");
	    l = strtok(NULL," \n");
	    p = strtok(NULL," \n");
	    r = strtok(NULL," \n");
	    q = strtok(NULL," \n");
	    if ((ta = parsefnode(p))) {
		t->point = ta->point;
		t->node = ta->node;
		t->net = ta->net;
		t->zone = ta->zone;
		tidy_faddr(ta);
	    }
	    t->domain = xstrcpy(l);
	    if ((ta = parsefnode(q))) {
		f->point = ta->point;
		f->node = ta->node;
		f->net = ta->net;
		f->zone = ta->zone;
		tidy_faddr(ta);
	    }
	    f->domain = xstrcpy(r);
	} else {
	    if (!strncmp(buf, "\001INTL", 5)) {
		l = strtok(buf," \n");
		l = strtok(NULL," \n");
		r = strtok(NULL," \n");
		if ((ta = parsefnode(l))) {
		    t->point = ta->point;
		    t->node = ta->node;
		    t->net = ta->net;
		    t->zone = ta->zone;
		    if (ta->domain) {
			if (t->domain)
			    free(t->domain);
			t->domain = ta->domain;
			ta->domain = NULL;
		    }
		    tidy_faddr(ta);
		}
		if ((ta = parsefnode(r))) {
		    f->point = ta->point;
		    f->node = ta->node;
		    f->net = ta->net;
		    f->zone = ta->zone;
		    if (ta->domain) {
			if (f->domain)
			    free(f->domain);
			f->domain = ta->domain;
			ta->domain = NULL;
		    }
		    tidy_faddr(ta);
		}
	    }
	}

	/*
	 * Check FLAGS kludge
	 */
	if (!strncmp(buf, "\001FLAGS ", 7)) {
	    flagstr = xstrcpy(buf + 7);
	    Syslog('m', "^aFLAGS %s", flagstr);
	}
	if (!strncmp(buf, "\001FLAGS: ", 8)) {
	    flagstr = xstrcpy(buf + 8);
	    Syslog('m', "^aFLAGS: %s", flagstr);
	}

	/*
	 * Check for X-FTN- kludges, this could be gated email.
	 * This should be impossible.
	 */
	if (!strncmp(buf, "\001X-FTN-", 7)) {
	    email = TRUE;
	    Syslog('?', "Warning: detected ^aX-FTN- kludge in netmail");
	}
    }
    free(buf);

    /*
     *  Only set point info if there was any info.
     *  GoldED doesn't set FMPT and TOPT kludges.
     */
    if (fmpt)
	f->point = fmpt;
    if (topt)
	t->point = topt;

    /*
     * If zone info is still missing, set the defaults which came from the
     * original mail packet addressing.
     */
    if (fzone && (f->zone == 0))
	f->zone = fzone;
    if (tzone && (t->zone == 0))
	t->zone = tzone;

    l = xstrcpy(ascfnode(f, 0xff));
    r = xstrcpy(ascfnode(t, 0xff));
    Syslog('+', "Netmail from \"%s\" to \"%s\"", l, r);
    free(l);
    free(r);

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

    switch(TrackMail(na, &routeto)) {
	case R_LOCAL:
	    /*
	     *  Check the To: field.
	     */
	    if (strchr(t->name, '@') != NULL) {
		snprintf(name, 36, "%s", strtok(t->name, "@"));
		snprintf(System, 36, "%s", strtok(NULL, "\000"));
		email = TRUE;
	    } else {
		snprintf(name, 36, "%s", t->name);
		snprintf(System, 36, "%s", CFG.sysdomain);
	    }

	    if (email) {
		/*
		 * Send this netmail via ftn2rfc -> postemail.
		 */
		return result = ftn2rfc(f, t, subject, orig, mdate, flags, fp);
	    }

	    /*
	     * If message to "sysop" or "postmaster" replace it
	     * with the sysops real name.
	     */
	    if ((strncasecmp(name, "sysop", 5) == 0) || 
		(strcasecmp(name, "postmaster") == 0) ||
		(strcasecmp(name, "coordinator") == 0)) {
		Syslog('+', "  Readdress from %s to %s", name, CFG.sysop_name);
		snprintf(name, 36, "%s", CFG.sysop_name);
	    }

	    /*
	     * If the message is a service message, check the
	     * services database to see what action is needed.
	     * First make sure that the right noderecord is loaded.
	     */
	    (void)noderecord(f);
	    p = calloc(PATH_MAX, sizeof(char));
	    snprintf(p, PATH_MAX, "%s/etc/service.data", getenv("MBSE_ROOT"));
	    if ((sfp = fopen(p, "r")) == NULL) {
		WriteError("$Can't open %s", p);
	    } else {
		fread(&servhdr, sizeof(servhdr), 1, sfp);
		while (fread(&servrec, servhdr.recsize, 1, sfp) == 1) {
		    if ((strncasecmp(servrec.Service, name, strlen(servrec.Service)) == 0) && servrec.Active) {
			switch (servrec.Action) {
			    case AREAMGR:   result = AreaMgr(f, t, msgid, subject, mdate, flags, fp);
					    break;
			    case FILEMGR:   result = FileMgr(f, t, msgid, subject, mdate, flags, fp);
					    break;
			    case EMAIL:     result = ftn2rfc(f, t, subject, orig, mdate, flags, fp);
					    if (result) {
						if (result == 2)
						    Bounce(f, t, fp, (char *)"Could not post email");
						else
						    Bounce(f, t, fp, (char *)"Could not convert to email");
					    }
					    break;
			}
			Syslog('m', "Handled service %s, rc=%d", servrec.Service, result);
			fclose(sfp);
			return result;
		    }
		}
		fclose(sfp);
	    }
	    free(p);

	    /*
	     * Ping function
	     */
	    if (!strcasecmp(name, (char *)"ping") && DoPing) {
		return Ping(f, t, fp, FALSE);
	    }

	    /*
	     * Check userlist real names, handles, unix names.
	     * Import if one fits.
	     */
	    if (SearchUser(name)) {
		return storenet(f, t, mdate, flags, subject, msgid, reply, fp, flagstr);
	    }

	    Syslog('+', "  \"%s\" is not a known BBS user", name);
	    /*
	     *  Unknown, readdress it to the sysop.
	     */
	    net_bad++;
	    Syslog('+', "  Readdress from %s to %s", name, CFG.sysop_name);
	    snprintf(name, 36, "%s", CFG.sysop_name);
	    if (SearchUser(name)) {
		return storenet(f, t, mdate, flags, subject, msgid, reply, fp, flagstr);
	    } else {
		WriteError("Readdress import failed, sysop doesn't exist. CHECK YOUR SETUP");
		return 0;
	    }
	    break;

	case R_DIRECT:
	case R_ROUTE:
	    Syslog('+', "Route netmail via %s", aka2str(routeto));
            if (!strcasecmp(t->name, (char *)"ping") && DoPing) {
                Syslog('+', "In transit \"Ping\" message detected");
                Ping(f, t, fp, TRUE);
                (void)noderecord(f);
            }

	    /*
	     * Forward this message. Will not work for unknown
	     * direct links.
	     */
	    if (SearchNode(routeto)) {
		memset(&Orig, 0, sizeof(Orig));
		ra = fido2faddr(routeto);
		ta = bestaka_s(ra);
		Orig.zone  = ta->zone;
		Orig.net   = ta->net;
		Orig.node  = ta->node;
		Orig.point = ta->point;
		tidy_faddr(ra);
		tidy_faddr(ta);

		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 ((net = OpenPkt(Orig , routeto, (char *)ext)) == NULL) {
		    net_bad++;
		    WriteError("Can't create netmail");
		    return 0;
		}
	    } else {
		/*
		 * If it's not a direct link, create a outbound
		 * .pkt anyway, better then that this mail is 
		 * lost. It gets the normal status, it might
		 * get delivered during ZMH this way.
		 */
		Syslog('!', "Warning: not a direct link, check setup");
		memset(&Orig, 0, sizeof(Orig));
		ra = fido2faddr(routeto);
		ta = bestaka_s(ra);
		Orig.zone  = ta->zone;
		Orig.net   = ta->net;
		Orig.node  = ta->node;
		Orig.point = ta->point;
		tidy_faddr(ra);
		tidy_faddr(ta);

		if ((net = OpenPkt(Orig , routeto, (char *)"nnn")) == NULL) {
		    net_bad++;
		    WriteError("Can't create netmail");
		    return 0;
		}
	    }

	    /*
	     * Now start forward.
	     */
	    Syslog('m', "Net from  %s", ascfnode(f, 0xff));
	    Syslog('m', "Net to    %s", ascfnode(t, 0xff));
	    Syslog('m', "Net flags %08x", flags);
	    Syslog('m', "Net subj  %s", subject);

	    if (AddMsgHdr(net, f, t, flags, 0, mdate, t->name, f->name, subject)) {
		WriteError("Can't write message header");
		net_bad++;
		return 0;
	    }
	    rewind(fp);

	    /*
	     * Copy all text including kludges, when
	     * finished, insert our ^aVia line.
	     */
	    buf = calloc(MAX_LINE_LENGTH +1, sizeof(char));
	    while ((fgets(buf, MAX_LINE_LENGTH, fp)) != NULL)
		fprintf(net, "%s\r", buf);

	    now = time(NULL);
	    tm = gmtime(&now);
	    ta = bestaka_s(t);
	    fprintf(net, "\001Via %s @%d%02d%02d.%02d%02d%02d.UTC mbfido %s\r", 
		ascfnode(ta, 0x1f), tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
		tm->tm_hour, tm->tm_min, tm->tm_sec, VERSION);
	    tidy_faddr(ta);

	    putc(0, net);
	    fclose(net);
	    free(buf);
	    net_out++;
	    Syslog('m', "Forward done.");
	    return 0;

	default:
	    /*
	     * If we came this far, there's definitly something wrong
	     * with this netmail.
	     */
	    WriteError("No ROUTE for this netmail");
	    net_bad++;
	    flags |= M_ORPHAN;
	    return storenet(f, t, mdate, flags, subject, msgid, reply, fp, flagstr);
	    break;
    }

    /* Never reached */
    return result;
}
Beispiel #14
0
void flush_dir(char *ndir)
{
    struct dirent   *de;
    DIR		    *dp;
    FILE	    *fp, *inf, *ouf;
    faddr	    noden, *bestaka;
    fidoaddr	    nodenr;
    int		    flavor, mode, Attach, fage, first, bread, rc;
    int		    fsize;
    char	    *p, *temp, *fname, *arcfile, *pktfile, *ext, maxnr, nr, oldnr, *buf;
    time_t	    Now;
    struct tm	    *ptm;
    struct stat	    sbuf;
    fd_list	    *fdl = NULL;

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

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

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

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

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

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

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

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

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

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

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

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

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

    closedir(dp);
    sort_fdlist(&fdl);

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

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

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

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

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

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

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

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

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

	fsize = file_size(arcfile);

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

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

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

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

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

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

    closedir(dp);
    sort_fdlist(&fdl);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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