mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +00:00
Minor tweaks plus added method for parsing mime headers.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@26109 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e8e914434d
commit
9168f3c85d
7 changed files with 164 additions and 95 deletions
|
@ -3,6 +3,12 @@
|
||||||
* Source/Additions/Unicode.m:
|
* Source/Additions/Unicode.m:
|
||||||
* Headers/Additions/GNUstepBase/GSVersionMacros.h:
|
* Headers/Additions/GNUstepBase/GSVersionMacros.h:
|
||||||
Minor tweaks for building under leopard.
|
Minor tweaks for building under leopard.
|
||||||
|
* Source/NSPathUtilities.m: minor thread safety fix.
|
||||||
|
* Source/NSSocketPort.m: remove bogus comment
|
||||||
|
* Source/NSMessagePort.m: remove bogus comment
|
||||||
|
* Source/Additions/Unicode.m: add lockign for nl_langinfo
|
||||||
|
* Source/Additions/GSMime.m: New method to parse headers
|
||||||
|
* Headers/Additions/GNUstepBase/GSMime.h: ditto
|
||||||
|
|
||||||
2008-02-19 Nicola Pero <nicola.pero@meta-innovation.com>
|
2008-02-19 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,7 @@ extern "C" {
|
||||||
- (BOOL) isInHeaders;
|
- (BOOL) isInHeaders;
|
||||||
- (GSMimeDocument*) mimeDocument;
|
- (GSMimeDocument*) mimeDocument;
|
||||||
- (BOOL) parse: (NSData*)d;
|
- (BOOL) parse: (NSData*)d;
|
||||||
|
- (BOOL) parseHeaders: (NSData*)d remaining: (NSData**)body;
|
||||||
- (BOOL) parseHeader: (NSString*)aHeader;
|
- (BOOL) parseHeader: (NSString*)aHeader;
|
||||||
- (BOOL) scanHeaderBody: (NSScanner*)scanner into: (GSMimeHeader*)info;
|
- (BOOL) scanHeaderBody: (NSScanner*)scanner into: (GSMimeHeader*)info;
|
||||||
- (NSString*) scanName: (NSScanner*)scanner;
|
- (NSString*) scanName: (NSScanner*)scanner;
|
||||||
|
|
|
@ -1361,101 +1361,19 @@ wordData(NSString *word)
|
||||||
*/
|
*/
|
||||||
- (BOOL) parse: (NSData*)d
|
- (BOOL) parse: (NSData*)d
|
||||||
{
|
{
|
||||||
unsigned l = [d length];
|
|
||||||
|
|
||||||
if (flags.complete == 1)
|
if (flags.complete == 1)
|
||||||
{
|
{
|
||||||
return NO; /* Already completely parsed! */
|
return NO; /* Already completely parsed! */
|
||||||
}
|
}
|
||||||
if (l > 0)
|
if ([d length] > 0)
|
||||||
{
|
{
|
||||||
NSDebugMLLog(@"GSMime", @"Parse %u bytes - '%*.*s'", l, l, l, [d bytes]);
|
|
||||||
if (flags.inBody == 0)
|
if (flags.inBody == 0)
|
||||||
{
|
{
|
||||||
[data appendBytes: [d bytes] length: [d length]];
|
if ([self parseHeaders: d remaining: &d] == YES)
|
||||||
bytes = (unsigned char*)[data mutableBytes];
|
{
|
||||||
dataEnd = [data length];
|
return YES;
|
||||||
|
}
|
||||||
while (flags.inBody == 0)
|
}
|
||||||
{
|
|
||||||
if ([self _unfoldHeader] == NO)
|
|
||||||
{
|
|
||||||
return YES; /* Needs more data to fill line. */
|
|
||||||
}
|
|
||||||
if (flags.inBody == 0)
|
|
||||||
{
|
|
||||||
NSString *header;
|
|
||||||
|
|
||||||
header = [self _decodeHeader];
|
|
||||||
if (header == nil)
|
|
||||||
{
|
|
||||||
return NO; /* Couldn't handle words. */
|
|
||||||
}
|
|
||||||
if ([self parseHeader: header] == NO)
|
|
||||||
{
|
|
||||||
flags.hadErrors = 1;
|
|
||||||
return NO; /* Header not parsed properly. */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NSDebugMLLog(@"GSMime", @"Parsed end of headers", "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* All headers have been parsed, so we empty our internal buffer
|
|
||||||
* (which we will now use to store decoded data) and place unused
|
|
||||||
* information back in the incoming data object to act as input.
|
|
||||||
*/
|
|
||||||
d = AUTORELEASE([data copy]);
|
|
||||||
[data setLength: 0];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we have finished parsing the headers, we may have http
|
|
||||||
* continuation header(s), in which case, we must start parsing
|
|
||||||
* headers again.
|
|
||||||
*/
|
|
||||||
if (flags.inBody == 1)
|
|
||||||
{
|
|
||||||
NSDictionary *info;
|
|
||||||
GSMimeHeader *hdr;
|
|
||||||
|
|
||||||
info = [[document headersNamed: @"http"] lastObject];
|
|
||||||
if (info != nil && flags.isHttp == 1)
|
|
||||||
{
|
|
||||||
NSString *val;
|
|
||||||
|
|
||||||
val = [info objectForKey: NSHTTPPropertyStatusCodeKey];
|
|
||||||
if (val != nil)
|
|
||||||
{
|
|
||||||
int v = [val intValue];
|
|
||||||
|
|
||||||
if (v >= 100 && v < 200)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* This is an intermediary response ... so we have
|
|
||||||
* to restart the parsing operation!
|
|
||||||
*/
|
|
||||||
NSDebugMLLog(@"GSMime",
|
|
||||||
@"Parsed http continuation", "");
|
|
||||||
flags.inBody = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* If there is a zero content length, parsing is complete.
|
|
||||||
*/
|
|
||||||
hdr = [document headerNamed: @"content-length"];
|
|
||||||
if (hdr != nil && [[hdr value] intValue] == 0)
|
|
||||||
{
|
|
||||||
[document setContent: @""];
|
|
||||||
flags.inBody = 0;
|
|
||||||
flags.complete = 1;
|
|
||||||
return NO; // No more data needed
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([d length] > 0)
|
if ([d length] > 0)
|
||||||
{
|
{
|
||||||
if (flags.inBody == 1)
|
if (flags.inBody == 1)
|
||||||
|
@ -1499,6 +1417,136 @@ wordData(NSString *word)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (BOOL) parseHeaders: (NSData*)d remaining: (NSData**)body
|
||||||
|
{
|
||||||
|
NSDictionary *info;
|
||||||
|
GSMimeHeader *hdr;
|
||||||
|
unsigned l = [d length];
|
||||||
|
|
||||||
|
if (flags.complete == 1 || flags.inBody == 1)
|
||||||
|
{
|
||||||
|
return NO; /* Headers already parsed! */
|
||||||
|
}
|
||||||
|
if (body != 0)
|
||||||
|
{
|
||||||
|
*body = nil;
|
||||||
|
}
|
||||||
|
if (l == 0)
|
||||||
|
{
|
||||||
|
/* Add a CRLF to either end the current header line or act as
|
||||||
|
* the blank linme terminating the headers.
|
||||||
|
*/
|
||||||
|
if ([self parseHeaders: [NSData dataWithBytes: "\r\n" length: 2]
|
||||||
|
remaining: body] == YES)
|
||||||
|
{
|
||||||
|
/* Still in headers ... so we add a CRLF to terminate them.
|
||||||
|
*/
|
||||||
|
[self parseHeaders: [NSData dataWithBytes: "\r\n" length: 2]
|
||||||
|
remaining: body];
|
||||||
|
}
|
||||||
|
flags.wantEndOfLine = 0;
|
||||||
|
flags.inBody = 0;
|
||||||
|
flags.complete = 1; /* Finished parsing */
|
||||||
|
return NO; /* Want no more data */
|
||||||
|
}
|
||||||
|
|
||||||
|
NSDebugMLLog(@"GSMime", @"Parse %u bytes - '%*.*s'", l, l, l, [d bytes]);
|
||||||
|
|
||||||
|
[data appendBytes: [d bytes] length: [d length]];
|
||||||
|
bytes = (unsigned char*)[data mutableBytes];
|
||||||
|
dataEnd = [data length];
|
||||||
|
|
||||||
|
while (flags.inBody == 0)
|
||||||
|
{
|
||||||
|
if ([self _unfoldHeader] == NO)
|
||||||
|
{
|
||||||
|
return YES; /* Needs more data to fill line. */
|
||||||
|
}
|
||||||
|
if (flags.inBody == 0)
|
||||||
|
{
|
||||||
|
NSString *header;
|
||||||
|
|
||||||
|
header = [self _decodeHeader];
|
||||||
|
if (header == nil)
|
||||||
|
{
|
||||||
|
flags.hadErrors = 1;
|
||||||
|
return NO; /* Couldn't handle words. */
|
||||||
|
}
|
||||||
|
if ([self parseHeader: header] == NO)
|
||||||
|
{
|
||||||
|
flags.hadErrors = 1;
|
||||||
|
return NO; /* Header not parsed properly. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSDebugMLLog(@"GSMime", @"Parsed end of headers", "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* All headers have been parsed, so we empty our internal buffer
|
||||||
|
* (which we will now use to store decoded data) and place unused
|
||||||
|
* information back in the incoming data object to act as input.
|
||||||
|
*/
|
||||||
|
d = AUTORELEASE([data copy]);
|
||||||
|
if (body != 0)
|
||||||
|
{
|
||||||
|
*body = d;
|
||||||
|
}
|
||||||
|
[data setLength: 0];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We have finished parsing the headers, but we may have http
|
||||||
|
* continuation header(s), in which case, we must start parsing
|
||||||
|
* headers again.
|
||||||
|
*/
|
||||||
|
info = [[document headersNamed: @"http"] lastObject];
|
||||||
|
if (info != nil && flags.isHttp == 1)
|
||||||
|
{
|
||||||
|
NSString *val;
|
||||||
|
|
||||||
|
val = [info objectForKey: NSHTTPPropertyStatusCodeKey];
|
||||||
|
if (val != nil)
|
||||||
|
{
|
||||||
|
int v = [val intValue];
|
||||||
|
|
||||||
|
if (v >= 100 && v < 200)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This is an intermediary response ... so we have
|
||||||
|
* to restart the parsing operation!
|
||||||
|
*/
|
||||||
|
NSDebugMLLog(@"GSMime",
|
||||||
|
@"Parsed http continuation", "");
|
||||||
|
flags.inBody = 0;
|
||||||
|
if ([d length] == 0)
|
||||||
|
{
|
||||||
|
/* We need more data, so we have to return YES
|
||||||
|
* to ask our caller to provide it.
|
||||||
|
*/
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
return [self parseHeaders: d remaining: body];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there is a zero content length, all parsing is complete,
|
||||||
|
* not just header parsing.
|
||||||
|
*/
|
||||||
|
hdr = [document headerNamed: @"content-length"];
|
||||||
|
if (hdr != nil && [[hdr value] intValue] == 0)
|
||||||
|
{
|
||||||
|
[document setContent: @""];
|
||||||
|
flags.inBody = 0;
|
||||||
|
flags.complete = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO; // No more data needed
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* This method is called to parse a header line <em>for the
|
* This method is called to parse a header line <em>for the
|
||||||
|
|
|
@ -2022,6 +2022,9 @@ GSPrivateDefaultCStringEncoding()
|
||||||
if (defEnc == GSUndefinedEncoding)
|
if (defEnc == GSUndefinedEncoding)
|
||||||
{
|
{
|
||||||
char *encoding;
|
char *encoding;
|
||||||
|
#if HAVE_LANGINFO_CODESET
|
||||||
|
char encbuf[BUFSIZ];
|
||||||
|
#endif
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
|
|
||||||
GSSetupEncodingTable();
|
GSSetupEncodingTable();
|
||||||
|
@ -2035,10 +2038,16 @@ GSPrivateDefaultCStringEncoding()
|
||||||
|
|
||||||
if (natEnc == GSUndefinedEncoding)
|
if (natEnc == GSUndefinedEncoding)
|
||||||
{
|
{
|
||||||
|
|
||||||
/* Encoding not set */
|
/* Encoding not set */
|
||||||
#if HAVE_LANGINFO_CODESET
|
#if HAVE_LANGINFO_CODESET
|
||||||
/* Take it from the system locale information. */
|
/* Take it from the system locale information. */
|
||||||
encoding = nl_langinfo(CODESET);
|
[gnustep_global_lock lock];
|
||||||
|
strncpy(encbuf, nl_langinfo(CODESET), sizeof(encbuf)-1);
|
||||||
|
[gnustep_global_lock unlock];
|
||||||
|
encbuf[sizeof(encbuf)-1] = '\0';
|
||||||
|
encoding = encbuf;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First handle the fallback response from nl_langinfo() ...
|
* First handle the fallback response from nl_langinfo() ...
|
||||||
* if we are getting the default value we can't assume that
|
* if we are getting the default value we can't assume that
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h> /* for gethostname() */
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <sys/param.h> /* for MAXHOSTNAMELEN */
|
#include <sys/param.h> /* for MAXHOSTNAMELEN */
|
||||||
|
|
|
@ -1349,10 +1349,10 @@ NSUserName(void)
|
||||||
if (theUserName == nil || uid != olduid)
|
if (theUserName == nil || uid != olduid)
|
||||||
{
|
{
|
||||||
const char *loginName = 0;
|
const char *loginName = 0;
|
||||||
|
char buf[BUFSIZ*10];
|
||||||
#if defined(HAVE_GETPWUID_R)
|
#if defined(HAVE_GETPWUID_R)
|
||||||
struct passwd pwent;
|
struct passwd pwent;
|
||||||
struct passwd *p;
|
struct passwd *p;
|
||||||
char buf[BUFSIZ*10];
|
|
||||||
|
|
||||||
if (getpwuid_r(uid, &pwent, buf, sizeof(buf), &p) == 0)
|
if (getpwuid_r(uid, &pwent, buf, sizeof(buf), &p) == 0)
|
||||||
{
|
{
|
||||||
|
@ -1360,8 +1360,13 @@ NSUserName(void)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#if defined(HAVE_GETPWUID)
|
#if defined(HAVE_GETPWUID)
|
||||||
struct passwd *pwent = getpwuid (uid);
|
struct passwd *pwent;
|
||||||
loginName = pwent->pw_name;
|
|
||||||
|
[gnustep_global_lock lock];
|
||||||
|
pwent = getpwuid (uid);
|
||||||
|
strcpy(buf, pwent->pw_name);
|
||||||
|
[gnustep_global_lock unlock];
|
||||||
|
loginName = buf;
|
||||||
#endif /* HAVE_GETPWUID */
|
#endif /* HAVE_GETPWUID */
|
||||||
#endif /* HAVE_GETPWUID_R */
|
#endif /* HAVE_GETPWUID_R */
|
||||||
olduid = uid;
|
olduid = uid;
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifdef HAVE_UNISTD_H
|
#ifdef HAVE_UNISTD_H
|
||||||
#include <unistd.h> /* for gethostname() */
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue