Mercurial > noffle
view src/protocol.c @ 58:b4e6f7f96135 noffle
[svn] Add some intermediate variables for easier debugging in needsMark().
It seems that thread mode is sometimes not working.
Changed some variable types and used some casts to avoid compiler
warnings about signedness. In general, int should be used for parameters
for allowing a signedness assertion in the function.
author | enz |
---|---|
date | Fri, 12 May 2000 17:52:07 +0100 |
parents | 125d79c9e586 |
children | e612b263934f |
line wrap: on
line source
/* protocol.c $Id: protocol.c 60 2000-05-09 22:28:38Z uh1763 $ */ #if HAVE_CONFIG_H #include <config.h> #endif #include <stdio.h> #include <ctype.h> #include <netdb.h> #include <sys/types.h> #include <sys/utsname.h> #include "common.h" #include "dynamicstring.h" #include "log.h" #include "over.h" #include "util.h" #include "protocol.h" #include "portable.h" Bool Prt_getLn( Str line, FILE *f ) { size_t len; /* We also accept lines ending with "\n" instead of "\r\n", some clients wrongly send such lines. */ if ( ! fgets( line, MAXCHAR, f ) ) { Log_dbg( "Prt_getLine failed" ); return FALSE; } len = strlen( line ); if ( line[ len - 1 ] == '\n' ) { line[ len - 1 ] = '\0'; if ( line[ len - 2 ] == '\r' ) line[ len - 2 ] = '\0'; } Log_dbg( "[R] %s", line ); return TRUE; } Bool Prt_getTxtLn( Str line, Bool *err, FILE *f ) { Str buf; if ( ! Prt_getLn( buf, f ) ) { Log_err( "Cannot get text line" ); *err = TRUE; return FALSE; } *err = FALSE; if ( buf[ 0 ] == '.' ) { if ( buf[ 1 ] == 0 ) return FALSE; else strcpy( line, buf + 1 ); } else strcpy( line, buf ); return TRUE; } Bool Prt_putTxtLn( const char* line, FILE *f ) { if ( line[ 0 ] == '.' ) { Log_dbg( "[S] .%s", line ); return ( fprintf( f, ".%s\r\n", line ) == strlen( line ) + 3 ); } else { Log_dbg( "[S] %s", line ); return ( fprintf( f, "%s\r\n", line ) == strlen( line ) + 2 ); } } Bool Prt_putEndOfTxt( FILE *f ) { Log_dbg( "[S] ." ); return ( fprintf( f, ".\r\n" ) == 3 ); } /* Write text buffer of lines each ending with '\n'. Replace '\n' by "\r\n". */ Bool Prt_putTxtBuf( const char *buf, FILE *f ) { Str line; const char *pBuf; char *pLn; pBuf = buf; pLn = line; while ( *pBuf != '\0' ) { if ( *pBuf == '\n' ) { *pLn = '\0'; if ( ! Prt_putTxtLn( line, f ) ) return FALSE; pLn = line; ++pBuf; } else if ( pLn - line >= MAXCHAR - 1 ) { /* Put it out raw to prevent String overflow */ Log_err( "Writing VERY long line" ); *pLn = '\0'; if ( fprintf( f, "%s", line ) != strlen( line ) ) return FALSE; pLn = line; } else *(pLn++) = *(pBuf++); } return TRUE; } Bool Prt_getField( Str resultField, Str resultValue, const char* line ) { char *dst; const char *p; Str lineLower, t; Utl_cpyStr( lineLower, line ); Utl_toLower( lineLower ); p = Utl_stripWhiteSpace( lineLower ); dst = resultField; while ( ! isspace( *p ) && *p != ':' && *p != '\0' ) *(dst++) = *(p++); *dst = '\0'; while ( isspace( *p ) ) ++p; if ( *p == ':' ) { ++p; strcpy( t, line + ( p - lineLower ) ); p = Utl_stripWhiteSpace( t ); strcpy( resultValue, p ); return TRUE; } return FALSE; } Bool Prt_searchHeader( const char *artTxt, const char *which, Str result ) { const char *src, *p; char *dst; Str line, whichLower, field; int len; Utl_cpyStr( whichLower, which ); Utl_toLower( whichLower ); src = artTxt; while ( TRUE ) { dst = line; len = 0; while ( *src != '\n' && len < MAXCHAR ) { if ( *src == '\0' ) return FALSE; *(dst++) = *(src++); ++len; } if ( *src == '\n' ) ++src; *dst = '\0'; p = Utl_stripWhiteSpace( line ); if ( *p == '\0' ) break; if ( Prt_getField( field, result, line ) && strcmp( field, whichLower ) == 0 ) return TRUE; } return FALSE; } static Bool getFQDN( Str result ) { struct hostent *myHostEnt; struct utsname myName; if ( uname( &myName ) >= 0 && ( myHostEnt = gethostbyname( myName.nodename ) ) ) { Utl_cpyStr( result, myHostEnt->h_name ); return TRUE; } return FALSE; } static void getDomain( Str domain, const char *from ) { const char *addTopLevel, *p1, *p2, *p, *domainStart; Str myDomain; if ( getFQDN( myDomain ) ) { p = strstr( myDomain, "." ); if ( p != NULL ) domainStart = p + 1; else domainStart = myDomain; } else /* Take domain of From field */ { myDomain[ 0 ] = '\0'; p1 = strstr( from, "@" ); if ( p1 != NULL ) { p2 = strstr( p1, ">" ); if ( p2 != NULL ) Utl_cpyStrN( myDomain, p1 + 1, p2 - p1 - 1 ); } if ( myDomain[ 0 ] == '\0' ) Utl_cpyStr( myDomain, "unknown" ); domainStart = myDomain; } /* If domain contains no dot (and is probably invalid anyway), we add ".local", because some servers insist on domainnames with dot in message ID. */ addTopLevel = strstr( domainStart, "." ) == NULL ? ".local" : ""; snprintf( domain, MAXCHAR, "%s%s", myDomain, addTopLevel ); } /* See RFC 850, section 2.1.7 */ Bool Prt_isValidMsgId( const char *msgId ) { Str head, domain; int len, headLen; const char *p; len = strlen( msgId ); p = strstr( msgId, "@" ); if ( msgId[ 0 ] != '<' || msgId[ len - 1 ] != '>' || p == NULL ) return FALSE; strcpy( domain, p + 1 ); domain[ strlen( domain ) - 1 ] = '\0'; headLen = p - msgId - 1; Utl_cpyStrN( head, msgId + 1, headLen ); head[ headLen ] = '\0'; /* To do: check for special characters in head and domain (non-printable or '@', '<', '>'). Maybe compare domain with a config option and replace it by the config option, if not equal. */ if ( strstr( domain, "." ) == NULL ) return FALSE; return TRUE; } void Prt_genMsgId( Str msgId, const char *from, const char *suffix ) { Str domain, date; time_t t; getDomain( domain, from ); time( &t ); strftime( date, MAXCHAR, "%Y%m%d%H%M%S", gmtime( &t ) ); srand( time( NULL ) ); snprintf( msgId, MAXCHAR, "<%s.%X.%s@%s>", date, rand(), suffix, domain ); ASSERT( Prt_isValidMsgId( msgId ) ); }