void formatTime(const GregorianDateTime &t, DateConversionBuffer& buffer)
{
    int offset = abs(gmtoffset(t));
    char timeZoneName[70];
    struct tm gtm = t;
    strftime(timeZoneName, sizeof(timeZoneName), "%Z", &gtm);

    if (timeZoneName[0]) {
        snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d (%s)",
            t.hour, t.minute, t.second,
            gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, timeZoneName);
    } else {
        snprintf(buffer, DateConversionBufferSize, "%02d:%02d:%02d GMT%c%02d%02d",
            t.hour, t.minute, t.second,
            gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
    }
}
Example #2
0
bool DateInstance::getTime(GregorianDateTime& t, int& offset) const
{
    double milli = internalNumber();
    if (isnan(milli))
        return false;
    
    msToGregorianDateTime(milli, false, t);
    offset = gmtoffset(t);
    return true;
}
Example #3
0
UString formatTime(const GregorianDateTime &t, bool utc)
{
    char buffer[100];
    if (utc) {
        snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT", t.hour, t.minute, t.second);
    } else {
        int offset = abs(gmtoffset(t));
        char tzname[70];
        struct tm gtm = t;
        strftime(tzname, sizeof(tzname), "%Z", &gtm);

        if (tzname[0]) {
            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d (%s)",
                     t.hour, t.minute, t.second,
                     gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60, tzname);
        } else {
            snprintf(buffer, sizeof(buffer), "%02d:%02d:%02d GMT%c%02d%02d",
                     t.hour, t.minute, t.second,
                     gmtoffset(t) < 0 ? '-' : '+', offset / (60*60), (offset / 60) % 60);
        }
    }
    return UString(buffer);
}
JSValue JSC_HOST_CALL dateProtoFuncGetTimezoneOffset(ExecState* exec, JSObject*, JSValue thisValue, const ArgList&)
{
    if (!thisValue.isObject(&DateInstance::info))
        return throwError(exec, TypeError);

    const bool utc = false;

    DateInstance* thisDateObj = asDateInstance(thisValue); 
    double milli = thisDateObj->internalNumber();
    if (isnan(milli))
        return jsNaN(exec);

    GregorianDateTime t;
    thisDateObj->msToGregorianDateTime(milli, utc, t);
    return jsNumber(exec, -gmtoffset(t) / minutesPerHour);
}
Example #5
0
/*==============================================================================================================
 *
 *   NAME
 *	wake_builtin_date - Formats a date.
 *
 *   PROTOTYPE
 *	$(<date> [ format [, time] ] )
 *	$(<gmdate> [ format [, time] ] )
 *
 *   DESCRIPTION
 *	Formats a time value.
 *
 *   PARAMETERS
 *	format -
 *		A format string, that accepts the same specifiers than the PHP date() function.
 *		If not specified, the default format is 'Y-m-d H:i:s'.
 * 
 *	time -
 *		A time value. If not specified, the current Unix time is used.
 *
 *==============================================================================================================*/
static char *	__wake_builtin_date ( char *  output, char * format, time_t  time_value, int  is_localtime )
   {
	struct tm *	tm		=  ( is_localtime ) ?  localtime ( & time_value ) : gmtime ( & time_value ) ;
	char *		p		=  format ;
	int		ap_hour ;
	char		buffer [128] ;
	char *		buffer_p ;
	int		iso_year, iso_week ;
	int		iso_values_set	=  0,
			tz_set		=  0 ;


	tm -> tm_year		+=  1900 ;
	ap_hour			 =  ( tm -> tm_hour  %  12 ) ?  tm -> tm_hour % 12 : 12 ; 

	while  ( * p )
	   {
		buffer_p	=  NULL ;
		* buffer	=  0 ;

		switch ( * p )
		   {
			// 'a' : lowercase "am" or "pm"
			case	'a' :
				buffer_p	=  ( tm -> tm_hour  >=  12 ) ?  "pm" : "am" ;
				break ;

			// 'A' : uppercase "AM" or "PM"
			case	'A' :
				buffer_p	=  ( tm -> tm_hour  >=  12 ) ?  "PM" : "AM" ;
				break ;

			// 'B' : internet Swatch hour
			case	'B' :
			   {
				int	result		=
				   (
				      (
					 (
					    time_value -
						( time_value - 
						   (
						     ( time_value % 86400 ) + 3600
						    )
						 )
					  ) * 10
				       ) / 864
				    ) ;

				while  ( result  <  0 )
					result	+=  1000 ;

				result	%=  1000 ;
				sprintf ( buffer, "%03d", result ) ;
				break ;
			    }

			// 'c' : Full date, in ISO8601 format
			case	'c' :
				sprintf ( buffer, "%04d-%02d-%02dT%02d:%02d:%02d%s",
						tm -> tm_year, tm -> tm_mon + 1, tm -> tm_mday,
						tm -> tm_hour, tm -> tm_min, tm -> tm_sec,
						gmtoffset ( is_localtime, tm -> tm_gmtoff, 1 ) 
					 ) ;
				break ;

			// 'd' : day of month, as a two-digits number
			case	'd' : 
				sprintf ( buffer, "%02d", tm -> tm_mday ) ;
				break ;
			
			// 'D' : short day name
			case	'D' :
				buffer_p	=  short_day_names [ tm -> tm_wday ] ;
				break ;

			// 'e' : Timezone name
			case	'e' :
				if  ( ! tz_set )
					tzset ( ) ;

				buffer_p	=  tzname [0] ;
				break ;

			// 'F' : Long month name
			case	'F' :
				buffer_p	=  long_month_names [ tm -> tm_mon ] ;
				break ;

			// 'g' : Hour without leading zero (1..12)
			case	'g' :
				sprintf ( buffer, "%d", ap_hour ) ;
				break ;

			// 'G' : Hour without leading zero (0..23)
			case	'G' :
				sprintf ( buffer, "%d", tm -> tm_hour ) ;
				break ;
			
			// 'h' : Hour with leading zero (01..12)
			case	'h' :
				sprintf ( buffer, "%02d", ap_hour ) ;
				break ;

			// 'H' : Hour with leading zero (00..23)
			case	'H' :
				sprintf ( buffer, "%02d", tm -> tm_hour ) ;
				break ;
			
			// 'i' : Minute, with leading zero (00..59)
			case	'i' :
				sprintf ( buffer, "%02d", tm -> tm_min ) ;
				break ;

			// 'I' : 1 if daylight savings time is active, 0 otherwise
			case	'I' :
				sprintf ( buffer, "%d", tm -> tm_isdst ) ;
				break ;

			// 'j' : day of month, without the leading zero
			case	'j' : 
				sprintf ( buffer, "%d", tm -> tm_mday ) ;
				break ;

			// 'l' : Long day name
			case	'l' :
				buffer_p	=  long_day_names [ tm -> tm_wday ] ;
				break ;

			// 'L' : 1 is the year is leap, 0 otherwise
			case	'L' :
				sprintf ( buffer, "%d", IS_LEAP ( tm -> tm_year ) ) ;
				break ;

			// 'M' : short month name 
			case	'M' :
				buffer_p	=  short_month_names [ tm -> tm_mon ] ;
				break ;

			// 'm' : month of year, as a two-digits number
			case	'm' :
				sprintf ( buffer, "%02d", tm -> tm_mon + 1 ) ;
				break ;
			
			// 'n' : month of year, without the leading zero
			case	'n' :
				sprintf ( buffer, "%d", tm -> tm_mon + 1 ) ;
				break ;
			
			// 'N' : day of week, from 1 (monday) to 7 (sunday)
			case	'N' :
				sprintf ( buffer, "%d", ( tm -> tm_wday ) ?  tm -> tm_wday : 7 ) ;
				break ;

			// 'o' : ISO8601 year
			case	'o' :
				if  ( ! iso_values_set )
				   {
					isoweek_from_date ( tm -> tm_year, tm -> tm_mon, tm -> tm_mday, & iso_week, & iso_year ) ;
					iso_values_set	=  1 ;
				    }

				sprintf ( buffer, "%d", iso_year ) ;
				break ;

			// 'O' : GMT offset in ISO8601 format (+0200)
			case	'O' :
				buffer_p	=  gmtoffset ( is_localtime, tm -> tm_gmtoff, 0 ) ;
				break ;

			// 'P' : GMT offset in RFC822 format (+02:00)
			case	'P' :
				buffer_p	=  gmtoffset ( is_localtime, tm -> tm_gmtoff, 1 ) ;
				break ;

			// 'r' : RFC822 date
			case	'r' :
				sprintf ( buffer, "%3s %02d %3s %04d %02d:%02d:%02d %s", 
						short_day_names [ tm -> tm_wday ],
						tm -> tm_mday,
						short_month_names [ tm -> tm_mon ],
						tm -> tm_year,
						tm -> tm_hour, tm -> tm_min, tm -> tm_sec,
						gmtoffset ( is_localtime, tm -> tm_gmtoff, 0 ) 
					 ) ;
				break ;

			// 's' : Seconds, with leading zero (00..59)
			case	's' :
				sprintf ( buffer, "%02d", tm -> tm_sec ) ;
				break ;

			// 'S' : 2-letters english suffix for a day of month
			case	'S' :
				buffer_p	=  english_suffix ( tm -> tm_mday ) ;
				break ;

			// 't' : month length
			case	't' :
				sprintf ( buffer, "%d", MONTH_LENGTH ( tm -> tm_year, tm -> tm_mon ) ) ;
				break ;

			// 'T' : Timezone abbreviation
			case	'T' :
				if  ( ! tz_set )
					tzset ( ) ;

				buffer_p	=  tzname [1] ;
				break ;

			// 'u' : microsecond time. Always return '000000' since we accept an integer value as time
			case	'u' :
				buffer_p	=  "000000" ;
				break ;

			// 'U' : Unix time
			case	'U' :
				sprintf ( buffer, "%d", ( int ) time_value ) ;
				break ;

			// 'w' : day of week, from 0 (sunday) to 6 (saturday)
			case	'w' :
				sprintf ( buffer, "%d", tm -> tm_wday ) ;
				break ;

			// 'W' : ISO8601 week number (were weeks start on monday)
			case	'W' :
				if  ( ! iso_values_set )
				   {
					isoweek_from_date ( tm -> tm_year, tm -> tm_mon, tm -> tm_mday, & iso_week, & iso_year ) ;
					iso_values_set	=  1 ;
				    }

				sprintf ( buffer, "%d", iso_week ) ;
				break ;

			// 'y' : 2-digits year
			case	'y' :
				sprintf ( buffer, "%02d", ( tm -> tm_year % 100 ) ) ;
				break ;

			// 'Y' : 4-digits year
			case	'Y' :
				sprintf ( buffer, "%04d", tm -> tm_year ) ;
				break ;

			// 'z' : day of year, from 0 to 365
			case	'z' :
				sprintf ( buffer, "%d", tm -> tm_yday ) ;
				break ;

			// 'Z' : GMT offset in seconds
			case	'Z' :
				sprintf ( buffer, "%d", ( int ) tm -> tm_gmtoff ) ;
				break ;

			// Escape character : copy the next one without interpretation unless this is the last one
			case	'\\' :
				if  ( * ( p + 1 ) )
					p ++ ;
				/* Intentionally fall through the default case */

			// Other characters : copy as is
			default :
				buffer [0]	=  * p ;
				buffer [1]	=  0 ;
				break ;
		    }

		if  ( buffer_p  ==  NULL )
			buffer_p	=  buffer ;

		output	=  variable_buffer_output ( output, buffer_p, strlen ( buffer_p ) ) ;
		p ++ ;	
	    }	

	return ( output ) ;
    }
Example #6
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;
}
Example #7
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;
}
Example #8
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;
}
Example #9
0
static void processNewArchiveRecord (HTML_WORK *work, WVIEW_MSG_ARCHIVE_NOTIFY *armsg)
{
    HISTORY_DATA        data;
    ARCHIVE_PKT         arcRecord;
    int                 currHour, currDay, currMonth, currYear;
    float               gmtOffsetHours;
    int                 startmin, starthour, startday, startmonth, startyear;
    int                 i, DSTFlag;
    int16_t             tempShort;
    time_t              ntime, baseTime;
    struct tm           locTime;
    int                 deltaArchiveIntervals;

    //  ... generate the mesonet file
    htmlgenMesonetFile (work->mgrId, armsg);

    //  ... check to see if a DST change has occured
    DSTFlag = wvutilsDetectDSTChange();
    if (DSTFlag != WVUTILS_DST_NO_CHANGE)
    {
        radMsgLog (PRI_STATUS, "DST change: updating astronomical times for new local time...");

        ntime = time (NULL);
        localtime_r (&ntime, &locTime);
        currDay     = locTime.tm_mday;
        currMonth   = locTime.tm_mon + 1;
        currYear    = locTime.tm_year + 1900;

#ifdef HAVE_TM_GMTOFF
        gmtOffsetHours = locTime.tm_gmtoff/(60.0*60.0);
#else
        gmtOffsetHours = gmtoffset()/(60.0*60.0);
#endif

        //  ... update the sun times:
        sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                               (float)work->mgrId->stationLatitude/10,
                               (float)work->mgrId->stationLongitude/10,
                               RS_TYPE_SUN,
                               &work->mgrId->sunrise,
                               &work->mgrId->sunset);
        sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                               (float)work->mgrId->stationLatitude/10,
                               (float)work->mgrId->stationLongitude/10,
                               RS_TYPE_CIVIL,
                               &work->mgrId->civilrise,
                               &work->mgrId->civilset);
        sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                               (float)work->mgrId->stationLatitude/10,
                               (float)work->mgrId->stationLongitude/10,
                               RS_TYPE_ASTRO,
                               &work->mgrId->astrorise,
                               &work->mgrId->astroset);
        sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                               (float)work->mgrId->stationLatitude/10,
                               (float)work->mgrId->stationLongitude/10,
                               RS_TYPE_MIDDAY,
                               &work->mgrId->midday,
                               &tempShort);
        work->mgrId->dayLength = 
                sunTimesGetDayLength (currYear, currMonth, currDay,
                                      (float)work->mgrId->stationLatitude/10,
                                      (float)work->mgrId->stationLongitude/10);

        GetMoonRiseSetTimes (currYear, currMonth, currDay,
                             (float)gmtOffsetHours,
                             (float)work->mgrId->stationLatitude/10,
                             (float)work->mgrId->stationLongitude/10,
                             &work->mgrId->moonrise,
                             NULL,
                             &work->mgrId->moonset,
                             NULL);

        // restart the generation timer as the change may leave it in limbo
        radProcessTimerStart (work->timer, 5000L);
    }

    baseTime = time (NULL);

    //  ... update our data by adding the new sample

    //// Interval change:

    //  ... determine time to start for last sample
    startmin    = wvutilsGetMin(armsg->dateTime);
    starthour   = wvutilsGetHour(armsg->dateTime);
    startday    = wvutilsGetDay(armsg->dateTime);
    startmonth  = wvutilsGetMonth(armsg->dateTime);
    startyear   = wvutilsGetYear(armsg->dateTime);

    currHour    = starthour;
    currDay     = startday;
    currMonth   = startmonth;
    currYear    = startyear;

    if (work->LastArchiveDateTime != 0)
    {
        // compute the number of archive intervals since the last good record
        deltaArchiveIntervals = armsg->dateTime - work->LastArchiveDateTime;
        deltaArchiveIntervals /= 60;
        if (deltaArchiveIntervals < work->archiveInterval)
        {
            // this is odd, report and bail out
            radMsgLog (PRI_MEDIUM, "processNewArchiveRecord: "
                                   "minutes since last archive record (%d) "
                                   "less than archive interval (%d) - "
                                   "ignoring record...",
                                   deltaArchiveIntervals,
                                   work->archiveInterval);
            return;
        }

        deltaArchiveIntervals /= work->archiveInterval;
    }
    else
    {
        deltaArchiveIntervals = 1;
    }

    work->LastArchiveDateTime = armsg->dateTime;

    if (dbsqliteArchiveGetAverages (work->mgrId->isMetricUnits,
                                    work->archiveInterval,
                                    &data,
                                    armsg->dateTime,
                                    1)
        <= 0)
    {
        // populate history data with ARCHIVE_VALUE_NULL
        for (i = 0; i < DATA_INDEX_MAX(work->isExtendedData); i ++)
        {
            data.values[i] = ARCHIVE_VALUE_NULL;
            data.samples[i] = 0;
        }
        radMsgLog (PRI_MEDIUM, "no data found for sample...");
    }

    wvutilsLogEvent (PRI_STATUS, "Adding %d minute sample for %4.4d-%2.2d-%2.2d %2.2d:%2.2d...", 
                     work->archiveInterval, startyear, startmonth, startday, starthour, startmin);

    //  ... set the archiveAvailable flag for generation...
    work->mgrId->newArchiveMask |= NEW_ARCHIVE_SAMPLE;

    // add the RX check value to the data here
    data.values[DATA_INDEX_rxCheckPercent] = armsg->rxPercent;

    htmlmgrAddSampleValue (work->mgrId, &data, deltaArchiveIntervals);
        
    // generate an ASCII entry in the day's browser file (if enabled)
    if (dbsqliteArchiveGetRecord(armsg->dateTime, &arcRecord) == OK)
    {
        arcrecGenerate(&arcRecord, work->mgrId->isMetricUnits);
    }


    //// Hour change?
    if (work->histLastHour != currHour)
    {
        // determine times to start for last hour:
        ntime = time (NULL);
        localtime_r (&ntime, &locTime);
        locTime.tm_sec   = 0;
        locTime.tm_min   = work->archiveInterval;
        locTime.tm_hour  = currHour;
        locTime.tm_mday  = currDay;
        locTime.tm_mon   = currMonth - 1;
        locTime.tm_year  = currYear - 1900;
        locTime.tm_isdst = -1;

        ntime = mktime (&locTime);
        ntime -= WV_SECONDS_IN_HOUR;
        localtime_r (&ntime, &locTime);

        starthour = locTime.tm_hour;

        if (dbsqliteArchiveGetAverages (work->mgrId->isMetricUnits,
                                        work->archiveInterval,
                                        &data,
                                        ntime,
                                        WV_SECONDS_IN_HOUR/SECONDS_IN_INTERVAL(work->archiveInterval))
            <= 0)
        {
            // populate history data with ARCHIVE_VALUE_NULL
            for (i = 0; i < DATA_INDEX_MAX(work->isExtendedData); i ++)
            {
                data.values[i] = ARCHIVE_VALUE_NULL;
                data.samples[i] = 0;
            }
            radMsgLog (PRI_MEDIUM, "no data found for last hour...");
        }

        wvutilsLogEvent (PRI_STATUS, "Adding hour sample...");

        //  ... set the archiveAvailable flag for generation...
        work->mgrId->newArchiveMask |= NEW_ARCHIVE_HOUR;

        htmlmgrAddHourValue (work->mgrId, &data);

        work->histLastHour = currHour;
    }

    //// Day change?
    if (work->histLastDay != currDay)
    {
        // determine times to start for last day:
        // normalize packed time:
        ntime = time (NULL);
        localtime_r (&ntime, &locTime);
        locTime.tm_sec   = 0;
        locTime.tm_min   = work->archiveInterval;
        locTime.tm_hour  = 0;
        locTime.tm_mday  = currDay;
        locTime.tm_mon   = currMonth - 1;
        locTime.tm_year  = currYear - 1900;
        locTime.tm_isdst = -1;
#ifdef HAVE_TM_GMTOFF
        gmtOffsetHours = locTime.tm_gmtoff/(60.0*60.0);
#else   
        gmtOffsetHours = gmtoffset()/(60.0*60.0);
#endif

        ntime = mktime (&locTime);
        ntime -= WV_SECONDS_IN_DAY;
        localtime_r (&ntime, &locTime);

        if (dbsqliteArchiveGetAverages (work->mgrId->isMetricUnits,
                                        work->archiveInterval,
                                        &data,
                                        ntime,
                                        WV_SECONDS_IN_DAY/SECONDS_IN_INTERVAL(work->archiveInterval))
            <= 0)
        {
            // populate history data with ARCHIVE_VALUE_NULL
            for (i = 0; i < DATA_INDEX_MAX(work->isExtendedData); i ++)
            {
                data.values[i] = ARCHIVE_VALUE_NULL;
                data.samples[i] = 0;
            }
            radMsgLog (PRI_MEDIUM, "no data found for last day...");
        }
        else
        {
            // Add a day history record:
            wvutilsLogEvent(PRI_STATUS, "Storing day history for %s", ctime(&ntime));
            dbsqliteHistoryInsertDay(&data);
        }

        //  ... set the archiveAvailable flag for generation...
        work->mgrId->newArchiveMask |= NEW_ARCHIVE_DAY;

        wvutilsLogEvent(PRI_STATUS, "Adding day sample...");
        htmlmgrAddDayValue (work->mgrId, &data);

        work->histLastDay = currDay;

        //  Start the timeout to do NOAA updates:
        radProcessTimerStart(work->noaaTimer, HTML_NOAA_UPDATE_DELAY);

        //  ... update the sun times
        sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                               (float)work->mgrId->stationLatitude/10,
                               (float)work->mgrId->stationLongitude/10,
                               RS_TYPE_SUN,
                               &work->mgrId->sunrise,
                               &work->mgrId->sunset);
        sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                               (float)work->mgrId->stationLatitude/10,
                               (float)work->mgrId->stationLongitude/10,
                               RS_TYPE_CIVIL,
                               &work->mgrId->civilrise,
                               &work->mgrId->civilset);
        sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                               (float)work->mgrId->stationLatitude/10,
                               (float)work->mgrId->stationLongitude/10,
                               RS_TYPE_ASTRO,
                               &work->mgrId->astrorise,
                               &work->mgrId->astroset);
        sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                               (float)work->mgrId->stationLatitude/10,
                               (float)work->mgrId->stationLongitude/10,
                               RS_TYPE_MIDDAY,
                               &work->mgrId->midday,
                               &tempShort);
        work->mgrId->dayLength = 
                sunTimesGetDayLength (currYear, currMonth, currDay,
                                      (float)work->mgrId->stationLatitude/10,
                                      (float)work->mgrId->stationLongitude/10);

        GetMoonRiseSetTimes (currYear, currMonth, currDay,
                             (float)gmtOffsetHours,
                             (float)work->mgrId->stationLatitude/10,
                             (float)work->mgrId->stationLongitude/10,
                             &work->mgrId->moonrise,
                             NULL,
                             &work->mgrId->moonset,
                             NULL);

    }

    return;
}
Example #10
0
int htmlStationInfoState (int state, void *stimulus, void *data)
{
    STIM                        *stim = (STIM *)stimulus;
    HTML_WORK                   *work = (HTML_WORK *)data;
    int                         seconds;
    WVIEW_MSG_STATION_INFO      *msg = (WVIEW_MSG_STATION_INFO *)stim->msg;
    time_t                      ntime;
    struct tm                   locTime;
    long                        offset, msOffset;
    long                        oldSecs, newSecs;
    int                         currDay, currMonth, currYear;
    float                       gmtOffsetHours;
    int16_t                     tempShort;
    FILE*                       indicateFile;

    ntime = time (NULL);
    localtime_r (&ntime, &locTime);
    currDay     = locTime.tm_mday;
    currMonth   = locTime.tm_mon + 1;
    currYear    = locTime.tm_year + 1900;
#ifdef HAVE_TM_GMTOFF
    gmtOffsetHours = locTime.tm_gmtoff/(60.0*60.0);
#else
    gmtOffsetHours = gmtoffset()/(60.0*60.0);    
#endif

    switch (stim->type)
    {
    case STIM_QMSG:
        if (stim->msgType == WVIEW_MSG_TYPE_STATION_INFO)
        {
            radMsgRouterMessageDeregister(WVIEW_MSG_TYPE_STATION_INFO);
            ntime = msg->lastArcTime;
            localtime_r (&ntime, &locTime);
            radMsgLog (PRI_STATUS, 
                       "received station info from wviewd: "
                       "%4.4d%2.2d%2.2d %2.2d:%2.2d:%2.2d",
                       locTime.tm_year + 1900,
                       locTime.tm_mon + 1,
                       locTime.tm_mday,
                       locTime.tm_hour,
                       locTime.tm_min,
                       locTime.tm_sec);

            work->archiveInterval = msg->archiveInterval;
            
            // Initialize the archive database interface:
            if (dbsqliteArchiveInit() == ERROR)
            {
                radMsgLog (PRI_HIGH, "dbsqliteArchiveInit failed");
                statusUpdateMessage("dbsqliteArchiveInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }


            // initialize the htmlMgr now that we know the archive interval:
            work->mgrId = htmlmgrInit (WVIEW_CONFIG_DIR, 
                                       work->isMetricUnits,
                                       work->imagePath,
                                       work->htmlPath,
                                       work->archiveInterval,
                                       work->isExtendedData,
                                       work->stationName,
                                       work->stationCity,
                                       work->stationState,
                                       msg->elevation,
                                       msg->latitude,
                                       msg->longitude,
                                       work->mphaseIncrease,
                                       work->mphaseDecrease,
                                       work->mphaseFull,
                                       work->radarURL,
                                       work->forecastURL,
                                       work->dateFormat,
                                       work->isDualUnits);
            if (work->mgrId == NULL)
            {
                radMsgLog (PRI_HIGH, "htlmgrInit failed!");
                statusUpdateMessage("htlmgrInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }
        
            wvstrncpy (work->mgrId->stationType,
                       msg->stationType,
                       sizeof(work->mgrId->stationType));

            //  ... initialize the sun times now
            sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                                   (float)work->mgrId->stationLatitude/10,
                                   (float)work->mgrId->stationLongitude/10,
                                   RS_TYPE_SUN,
                                   &work->mgrId->sunrise,
                                   &work->mgrId->sunset);
            sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                                   (float)work->mgrId->stationLatitude/10,
                                   (float)work->mgrId->stationLongitude/10,
                                   RS_TYPE_CIVIL,
                                   &work->mgrId->civilrise,
                                   &work->mgrId->civilset);
            sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                                   (float)work->mgrId->stationLatitude/10,
                                   (float)work->mgrId->stationLongitude/10,
                                   RS_TYPE_ASTRO,
                                   &work->mgrId->astrorise,
                                   &work->mgrId->astroset);
            sunTimesGetSunRiseSet (currYear, currMonth, currDay,
                                   (float)work->mgrId->stationLatitude/10,
                                   (float)work->mgrId->stationLongitude/10,
                                   RS_TYPE_MIDDAY,
                                   &work->mgrId->midday,
                                   &tempShort);
            work->mgrId->dayLength = 
                    sunTimesGetDayLength (currYear, currMonth, currDay,
                                          (float)work->mgrId->stationLatitude/10,
                                          (float)work->mgrId->stationLongitude/10);

            GetMoonRiseSetTimes (currYear, currMonth, currDay,
                                 (float)gmtOffsetHours,
                                 (float)work->mgrId->stationLatitude/10,
                                 (float)work->mgrId->stationLongitude/10,
                                 &work->mgrId->moonrise,
                                 NULL,
                                 &work->mgrId->moonset,
                                 NULL);



            //  ... initialize the barometric pressure trend algorithm:
            radMsgLog (PRI_STATUS, "initializing barometric pressure trend");        
            if (htmlmgrBPTrendInit (work->mgrId, work->timerInterval/60000)
                == ERROR)
            {
                radMsgLog (PRI_HIGH, "htmlmgrBPTrendInit failed!");
                statusUpdateMessage("htmlmgrBPTrendInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

           
            //  ... load up our historical stores for the history charts:
            radMsgLog (PRI_STATUS, "initializing historical stores (this may take some time...)");  
            if (htmlmgrHistoryInit (work->mgrId) == ERROR)
            {
                radMsgLog (PRI_HIGH, "htmlStationInfoState: htmlmgrHistoryInit failed!");
                statusUpdateMessage("htmlmgrHistoryInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

            // store the "last" values
            ntime = time(NULL);
            localtime_r (&ntime, &locTime);
            work->histLastHour = locTime.tm_hour;
            work->histLastDay = locTime.tm_mday;

            
            // Initialize the HILOW database interface:
            // (this cannot occur before wviewd sends us the archive time)
            if (dbsqliteHiLowInit(FALSE) == ERROR)
            {
                radMsgLog (PRI_CATASTROPHIC, "dbsqliteHiLowInit failed!");
                statusUpdateMessage("dbsqliteHiLowInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

            // initialize the NOAA database:
            if (dbsqliteNOAAInit() == ERROR)
            {
                radMsgLog (PRI_CATASTROPHIC, "dbsqliteNOAAInit failed!");
                statusUpdateMessage("dbsqliteNOAAInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

            // initialize the NOAA report generator
            radMsgLog (PRI_STATUS, "NOAA: initializing reports (this may take some time...)");  
            work->noaaId = noaaGenerateInit (work->mgrId->imagePath,
                                             work->isMetricUnits,
                                             msg->latitude,
                                             msg->longitude,
                                             msg->elevation,
                                             work->stationName,
                                             work->stationCity,
                                             work->stationState,
                                             msg->lastArcTime);
            if (work->noaaId == NULL)
            {
                radMsgLog (PRI_CATASTROPHIC, "noaaGenerateInit failed!");
                statusUpdateMessage("noaaGenerateInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }


            // initialize the archive record browser generator
            radMsgLog (PRI_STATUS, "ARCREC: initializing archive browser files (this may take some time...)");  
            if (arcrecGenerateInit (work->mgrId->imagePath,
                                    work->arcrecDaysToKeep,
                                    work->isMetricUnits,
                                    work->archiveInterval)
                == ERROR)
            {
                radMsgLog (PRI_CATASTROPHIC, "arcrecGenerateInit failed!");
                statusUpdateMessage("arcrecGenerateInit failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }


            // initial data request then start the data acquisition timer
            if (requestDataPackets (work) == ERROR)
            {
                radMsgLog (PRI_HIGH, "htmlStationInfoState: requestDataPackets failed!");
                statusUpdateMessage("requestDataPackets failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }

            radProcessTimerStart (work->rxTimer, HTML_RX_PACKETS_TIMEOUT);

            // wait here until a new second arrives
            ntime = time (NULL);
            localtime_r (&ntime, &locTime);
            oldSecs = newSecs = locTime.tm_sec;
            while (oldSecs == newSecs)
            {
                ntime = time (NULL);
                localtime_r (&ntime, &locTime);
                newSecs = locTime.tm_sec;
            }
            
            
            /*  ... start the data timer to go off at the next 5 minute
                ... interval plus the user offset
            */
            ntime = time (NULL);
            localtime_r (&ntime, &locTime);
            seconds = locTime.tm_sec - 10L;         // start at 10 secs past

            offset = locTime.tm_min % 5L;           // where are we in period?
            offset = 5 - offset;                    // how many mins to get to "0"?
            offset %= 5;                            // don't want "5"
            offset += work->startOffset;            // user start in period
            if (offset == 0L)                       // prevent negative timeout
                seconds -= 60L;                     // make neg so timeout is pos

            if (seconds < -60L)
            {
                offset += 1L;
                seconds += 60L;
            }

            radMsgLog (PRI_STATUS,
                       "starting html generation in %d mins %d secs",
                       ((seconds > 0L) ? ((offset > 0L) ? offset - 1L : offset) : offset),
                               (seconds > 0L) ? 60L - seconds : (-1L) * seconds);

            work->nextGenerationTime.tv_sec = (long)ntime + ((offset * 60L) - seconds);
            work->nextGenerationTime.tv_usec = 250L * 1000L;
            
            msOffset = 250L;                        // land on 250 ms mark

            radProcessTimerStart (work->timer,
                                  ((((offset * 60L) - seconds) * 1000L)) + msOffset);


            // 20041224 - Add an immediate generation cycle so longer 
            // duration archive intervals don't have to wait up to 30 minutes
            // for the first generation
            radMsgLog (PRI_STATUS, "doing initial html generation now...");
            work->numDataReceived = 0;

            statusUpdate(STATUS_RUNNING);
            statusUpdateMessage("Normal operation");

            // Save an indicator in the run directory so web apps know when we are up:
            indicateFile = fopen (work->indicateFile, "w");
            if (indicateFile == NULL)
            {
                radMsgLog (PRI_CATASTROPHIC, "indicator file create failed!");
                statusUpdateMessage("indicator file create failed!");
                statusUpdate(STATUS_ERROR);
                return HTML_STATE_ERROR;
            }
            fprintf (indicateFile, "%d", (int)msg->lastArcTime);
            fclose (indicateFile);

            return HTML_STATE_DATA;
        }

        break;
    }

    return state;
}
Example #11
0
File: post.c Project: ftnapps/FTNd
int Post(char *To, int Area, char *Subj, char *File, char *Flavor)
{
    int		    i, rc = FALSE, has_tear = FALSE, has_origin = FALSE;
    char	    *aka, *temp, *sAreas;
    FILE	    *fp, *tp;
    unsigned int    crc = -1;
    time_t	    tt;
    struct tm	    *t;

    ftnd_CleanSubject(Subj);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

	case ECHOMAIL:
			Msg.Echomail = TRUE;
			break;

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

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

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

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

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

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

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

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

	MsgText_Add2(temp);
	free(aka);
    }

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

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

    free(temp);
    Msg_Close();

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

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

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

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

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

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

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

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

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

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

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

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

	/*
	 * Add MSGID, REPLY and PID
	 */
	fprintf(qp, "\001MSGID: %s %08x\r", aka2str(Orig), sequencer());
	if (reply != NULL)
		fprintf(qp, "\001REPLY: %s\r", reply);
	fprintf(qp, "\001PID: MBSE-FIDO %s (%s-%s)\r", VERSION, OsName(), OsCPU());
	fprintf(qp, "\001TZUTC: %s\r", gmtoffset(Now));
	return qp;
}