Port to ObjC 1.

This commit is contained in:
Jonathan Schleifer 2011-03-29 03:46:20 +02:00
parent 50012ba975
commit 5b16eaa1f0
19 changed files with 468 additions and 204 deletions

View file

@ -37,7 +37,6 @@
4BD9BF5A134003F700DAB43A /* XMPPRosterItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */; }; 4BD9BF5A134003F700DAB43A /* XMPPRosterItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */; };
4BDEF8071340B240000156D1 /* XMPPRoster.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDEF8051340B240000156D1 /* XMPPRoster.h */; }; 4BDEF8071340B240000156D1 /* XMPPRoster.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDEF8051340B240000156D1 /* XMPPRoster.h */; };
4BDEF8081340B240000156D1 /* XMPPRoster.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDEF8061340B240000156D1 /* XMPPRoster.m */; }; 4BDEF8081340B240000156D1 /* XMPPRoster.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BDEF8061340B240000156D1 /* XMPPRoster.m */; };
4BF459B91340DE3600701BCC /* XMPPRoster_private.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BF459B81340DE3600701BCC /* XMPPRoster_private.h */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */ /* Begin PBXCopyFilesBuildPhase section */
@ -84,7 +83,6 @@
4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMPPRosterItem.m; path = src/XMPPRosterItem.m; sourceTree = SOURCE_ROOT; }; 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMPPRosterItem.m; path = src/XMPPRosterItem.m; sourceTree = SOURCE_ROOT; };
4BDEF8051340B240000156D1 /* XMPPRoster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMPPRoster.h; path = src/XMPPRoster.h; sourceTree = SOURCE_ROOT; }; 4BDEF8051340B240000156D1 /* XMPPRoster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMPPRoster.h; path = src/XMPPRoster.h; sourceTree = SOURCE_ROOT; };
4BDEF8061340B240000156D1 /* XMPPRoster.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMPPRoster.m; path = src/XMPPRoster.m; sourceTree = SOURCE_ROOT; }; 4BDEF8061340B240000156D1 /* XMPPRoster.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = XMPPRoster.m; path = src/XMPPRoster.m; sourceTree = SOURCE_ROOT; };
4BF459B81340DE3600701BCC /* XMPPRoster_private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMPPRoster_private.h; path = src/XMPPRoster_private.h; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -166,7 +164,6 @@
4BC559E81337AC0900E345C7 /* XMPPPresence.h */, 4BC559E81337AC0900E345C7 /* XMPPPresence.h */,
4BC559E91337AC0900E345C7 /* XMPPPresence.m */, 4BC559E91337AC0900E345C7 /* XMPPPresence.m */,
4BDEF8051340B240000156D1 /* XMPPRoster.h */, 4BDEF8051340B240000156D1 /* XMPPRoster.h */,
4BF459B81340DE3600701BCC /* XMPPRoster_private.h */,
4BDEF8061340B240000156D1 /* XMPPRoster.m */, 4BDEF8061340B240000156D1 /* XMPPRoster.m */,
4BD9BF57134003F700DAB43A /* XMPPRosterItem.h */, 4BD9BF57134003F700DAB43A /* XMPPRosterItem.h */,
4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */, 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */,
@ -206,7 +203,6 @@
4BC55A011337AC1800E345C7 /* XMPPStanza.h in Headers */, 4BC55A011337AC1800E345C7 /* XMPPStanza.h in Headers */,
4BD9BF59134003F700DAB43A /* XMPPRosterItem.h in Headers */, 4BD9BF59134003F700DAB43A /* XMPPRosterItem.h in Headers */,
4BDEF8071340B240000156D1 /* XMPPRoster.h in Headers */, 4BDEF8071340B240000156D1 /* XMPPRoster.h in Headers */,
4BF459B91340DE3600701BCC /* XMPPRoster_private.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View file

@ -1,5 +1,5 @@
all: all:
objfw-compile -Wall -g --lib 0.0 -o objxmpp *.m \ objfw-compile -Wall -Werror -g --lib 0.0 -o objxmpp *.m \
`pkg-config --cflags --libs libidn` -lobjopenssl `pkg-config --cflags --libs libidn` -lobjopenssl
clean: clean:

View file

@ -27,16 +27,19 @@
*/ */
@interface XMPPAuthenticator: OFObject @interface XMPPAuthenticator: OFObject
{ {
/// The authzid to get authorization for
OFString *authzid; OFString *authzid;
/// The authcid to authenticate with
OFString *authcid; OFString *authcid;
/// The password to authenticate with
OFString *password; OFString *password;
} }
#ifdef OF_HAVE_PROPERTIES
/// The authzid to get authorization for
@property (copy) OFString *authzid; @property (copy) OFString *authzid;
/// The authcid to authenticate with
@property (copy) OFString *authcid; @property (copy) OFString *authcid;
/// The password to authenticate with
@property (copy) OFString *password; @property (copy) OFString *password;
#endif
/** /**
* Initializes an already allocated XMPPAuthenticator with an authcid * Initializes an already allocated XMPPAuthenticator with an authcid
@ -79,4 +82,11 @@
* \param message The servers final message * \param message The servers final message
*/ */
- (void)parseServerFinalMessage: (OFDataArray*)message; - (void)parseServerFinalMessage: (OFDataArray*)message;
- (void)setAuthzid: (OFString*)authzid;
- (OFString*)authzid;
- (void)setAuthcid: (OFString*)authcid;
- (OFString*)authcid;
- (void)setPassword: (OFString*)password;
- (OFString*)password;
@end @end

View file

@ -23,10 +23,6 @@
#import "XMPPAuthenticator.h" #import "XMPPAuthenticator.h"
@implementation XMPPAuthenticator @implementation XMPPAuthenticator
@synthesize authzid;
@synthesize authcid;
@synthesize password;
- initWithAuthcid: (OFString*)authcid_ - initWithAuthcid: (OFString*)authcid_
password: (OFString*)password_ password: (OFString*)password_
{ {
@ -57,6 +53,42 @@
[super dealloc]; [super dealloc];
} }
- (void)setAuthzid: (OFString*)authzid_
{
OFString *old = authzid;
authzid = [authzid_ copy];
[old release];
}
- (OFString*)authzid
{
return [[authzid copy] autorelease];
}
- (void)setAuthcid: (OFString*)authcid_
{
OFString *old = authcid;
authcid = [authcid_ copy];
[old release];
}
- (OFString*)authcid
{
return [[authcid copy] autorelease];
}
- (void)setPassword: (OFString*)password_
{
OFString *old = password;
password = [password_ copy];
[old release];
}
- (OFString*)password
{
return [[password copy] autorelease];
}
- (OFDataArray*)clientFirstMessage - (OFDataArray*)clientFirstMessage
{ {
@throw [OFNotImplementedException newWithClass: isa @throw [OFNotImplementedException newWithClass: isa

View file

@ -41,7 +41,12 @@
#define XMPP_NS_STREAM @"http://etherx.jabber.org/streams" #define XMPP_NS_STREAM @"http://etherx.jabber.org/streams"
@protocol XMPPConnectionDelegate @protocol XMPPConnectionDelegate
#ifndef XMPP_CONNECTION_M
<OFObject>
#endif
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
@optional @optional
#endif
- (void)connectionWasAuthenticated: (XMPPConnection*)conn; - (void)connectionWasAuthenticated: (XMPPConnection*)conn;
- (void)connection: (XMPPConnection*)conn - (void)connection: (XMPPConnection*)conn
wasBoundToJID: (XMPPJID*)jid; wasBoundToJID: (XMPPJID*)jid;
@ -58,8 +63,10 @@
/** /**
* \brief A class which abstracts a connection to an XMPP service. * \brief A class which abstracts a connection to an XMPP service.
*/ */
@interface XMPPConnection: OFObject <OFXMLParserDelegate, @interface XMPPConnection: OFObject
OFXMLElementBuilderDelegate> #ifdef OF_HAVE_OPTONAL_PROTOCOLS
<OFXMLParserDelegate, OFXMLElementBuilderDelegate>
#endif
{ {
OFTCPSocket *sock; OFTCPSocket *sock;
OFXMLParser *parser; OFXMLParser *parser;
@ -75,11 +82,13 @@
XMPPRoster *roster; XMPPRoster *roster;
} }
#ifdef OF_HAVE_PROPERTIES
@property (copy) OFString *username, *password, *server, *resource; @property (copy) OFString *username, *password, *server, *resource;
@property (copy, readonly) XMPPJID *JID; @property (copy, readonly) XMPPJID *JID;
@property (assign) uint16_t port; @property (assign) uint16_t port;
@property (retain) id <XMPPConnectionDelegate> delegate; @property (retain) id <XMPPConnectionDelegate> delegate;
@property (readonly, retain) XMPPRoster *roster; @property (readonly, retain) XMPPRoster *roster;
#endif
/** /**
* Connects to the XMPP service. * Connects to the XMPP service.
@ -109,4 +118,35 @@
* Requests the roster. * Requests the roster.
*/ */
- (void)requestRoster; - (void)requestRoster;
- (void)setUsername: (OFString*)username;
- (OFString*)username;
- (void)setPassword: (OFString*)password;
- (OFString*)password;
- (void)setServer: (OFString*)server;
- (OFString*)server;
- (void)setResource: (OFString*)resource;
- (OFString*)resource;
- (XMPPJID*)JID;
- (void)setPort: (uint16_t)port;
- (uint16_t)port;
- (void)setDelegate: (id <XMPPConnectionDelegate>)delegate;
- (id <XMPPConnectionDelegate>)delegate;
- (XMPPRoster*)roster;
- (void)XMPP_startStream;
- (void)XMPP_handleStanza: (OFXMLElement*)elem;
- (void)XMPP_sendAuth: (OFString*)name;
- (void)XMPP_handleIQ: (XMPPIQ*)iq;
- (void)XMPP_handleMessage: (XMPPMessage*)msg;
- (void)XMPP_handlePresence: (XMPPPresence*)pres;
- (void)XMPP_handleFeatures: (OFXMLElement*)elem;
- (void)XMPP_sendResourceBind;
- (void)XMPP_handleResourceBind: (XMPPIQ*)iq;
- (void)XMPP_sendSession;
- (void)XMPP_handleSession: (XMPPIQ*)iq;
- (void)XMPP_handleRoster: (XMPPIQ*)iq;
@end
@interface OFObject (XMPPConnectionDelegate) <XMPPConnectionDelegate>
@end @end

View file

@ -21,6 +21,8 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#define XMPP_CONNECTION_M
#include <assert.h> #include <assert.h>
#include <stringprep.h> #include <stringprep.h>
@ -37,28 +39,10 @@
#import "XMPPMessage.h" #import "XMPPMessage.h"
#import "XMPPPresence.h" #import "XMPPPresence.h"
#import "XMPPRoster.h" #import "XMPPRoster.h"
#import "XMPPRoster_private.h"
#import "XMPPRosterItem.h" #import "XMPPRosterItem.h"
#import "XMPPExceptions.h" #import "XMPPExceptions.h"
@interface XMPPConnection ()
- (void)XMPP_startStream;
- (void)XMPP_handleStanza: (OFXMLElement*)elem;
- (void)XMPP_sendAuth: (OFString*)name;
- (void)XMPP_handleIQ: (XMPPIQ*)iq;
- (void)XMPP_handleMessage: (XMPPMessage*)msg;
- (void)XMPP_handlePresence: (XMPPPresence*)pres;
- (void)XMPP_handleFeatures: (OFXMLElement*)elem;
- (void)XMPP_sendResourceBind;
- (void)XMPP_handleResourceBind: (XMPPIQ*)iq;
- (void)XMPP_sendSession;
- (void)XMPP_handleSession: (XMPPIQ*)iq;
- (void)XMPP_handleRoster: (XMPPIQ*)iq;
@end
@implementation XMPPConnection @implementation XMPPConnection
@synthesize JID, port, delegate, roster;
- init - init
{ {
self = [super init]; self = [super init];
@ -70,8 +54,8 @@
port = 5222; port = 5222;
parser.delegate = self; [parser setDelegate: self];
elementBuilder.delegate = self; [elementBuilder setDelegate: self];
roster = [[XMPPRoster alloc] initWithConnection: self]; roster = [[XMPPRoster alloc] initWithConnection: self];
} @catch (id e) { } @catch (id e) {
@ -166,10 +150,10 @@
if ((rc = idna_to_ascii_8z([server_ cString], if ((rc = idna_to_ascii_8z([server_ cString],
&srv, IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS) &srv, IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS)
@throw [XMPPIDNATranslationFailedException @throw [XMPPIDNATranslationFailedException
newWithClass: isa newWithClass: isa
connection: self connection: self
operation: @"ToASCII" operation: @"ToASCII"
string: server_]; string: server_];
@try { @try {
server = [[OFString alloc] initWithCString: srv]; server = [[OFString alloc] initWithCString: srv];
@ -258,6 +242,8 @@
attributes: (OFArray*)attrs attributes: (OFArray*)attrs
{ {
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
OFEnumerator *enumerator;
OFXMLAttribute *attr;
if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] ||
![ns isEqual: XMPP_NS_STREAM]) { ![ns isEqual: XMPP_NS_STREAM]) {
@ -265,15 +251,16 @@
assert(0); assert(0);
} }
for (OFXMLAttribute *attr in attrs) { enumerator = [attrs objectEnumerator];
if ([attr.name isEqual: @"from"] && while ((attr = [enumerator nextObject]) != nil) {
![attr.stringValue isEqual: server]) { if ([[attr name] isEqual: @"from"] &&
![[attr stringValue] isEqual: server]) {
of_log(@"Got invalid from in stream start!"); of_log(@"Got invalid from in stream start!");
assert(0); assert(0);
} }
} }
parser.delegate = elementBuilder; [parser setDelegate: elementBuilder];
[pool release]; [pool release];
} }
@ -283,7 +270,7 @@
{ {
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
elem.defaultNamespace = XMPP_NS_CLIENT; [elem setDefaultNamespace: XMPP_NS_CLIENT];
[elem setPrefix: @"stream" [elem setPrefix: @"stream"
forNamespace: XMPP_NS_STREAM]; forNamespace: XMPP_NS_STREAM];
@ -305,19 +292,19 @@
- (void)XMPP_handleStanza: (OFXMLElement*)elem - (void)XMPP_handleStanza: (OFXMLElement*)elem
{ {
if ([elem.namespace isEqual: XMPP_NS_CLIENT]) { if ([[elem namespace] isEqual: XMPP_NS_CLIENT]) {
if ([elem.name isEqual: @"iq"]) { if ([[elem name] isEqual: @"iq"]) {
[self XMPP_handleIQ: [XMPPIQ stanzaWithElement: elem]]; [self XMPP_handleIQ: [XMPPIQ stanzaWithElement: elem]];
return; return;
} }
if ([elem.name isEqual: @"message"]) { if ([[elem name] isEqual: @"message"]) {
[self XMPP_handleMessage: [self XMPP_handleMessage:
[XMPPMessage stanzaWithElement: elem]]; [XMPPMessage stanzaWithElement: elem]];
return; return;
} }
if ([elem.name isEqual: @"presence"]) { if ([[elem name] isEqual: @"presence"]) {
[self XMPP_handlePresence: [self XMPP_handlePresence:
[XMPPPresence stanzaWithElement: elem]]; [XMPPPresence stanzaWithElement: elem]];
return; return;
@ -326,8 +313,8 @@
assert(0); assert(0);
} }
if ([elem.namespace isEqual: XMPP_NS_STREAM]) { if ([[elem namespace] isEqual: XMPP_NS_STREAM]) {
if ([elem.name isEqual: @"features"]) { if ([[elem name] isEqual: @"features"]) {
[self XMPP_handleFeatures: elem]; [self XMPP_handleFeatures: elem];
return; return;
} }
@ -335,30 +322,30 @@
assert(0); assert(0);
} }
if ([elem.namespace isEqual: XMPP_NS_STARTTLS]) { if ([[elem namespace] isEqual: XMPP_NS_STARTTLS]) {
if ([elem.name isEqual: @"proceed"]) { if ([[elem name] isEqual: @"proceed"]) {
/* FIXME: Catch errors here */ /* FIXME: Catch errors here */
sock = [[SSLSocket alloc] initWithSocket: sock]; sock = [[SSLSocket alloc] initWithSocket: sock];
/* Stream restart */ /* Stream restart */
parser.delegate = self; [parser setDelegate: self];
[self XMPP_startStream]; [self XMPP_startStream];
return; return;
} }
if ([elem.name isEqual: @"failure"]) if ([[elem name] isEqual: @"failure"])
/* TODO: Find/create an exception to throw here */ /* TODO: Find/create an exception to throw here */
@throw [OFException newWithClass: isa]; @throw [OFException newWithClass: isa];
assert(0); assert(0);
} }
if ([elem.namespace isEqual: XMPP_NS_SASL]) { if ([[elem namespace] isEqual: XMPP_NS_SASL]) {
if ([elem.name isEqual: @"challenge"]) { if ([[elem name] isEqual: @"challenge"]) {
OFXMLElement *responseTag; OFXMLElement *responseTag;
OFDataArray *challenge = OFDataArray *challenge =
[OFDataArray dataArrayWithBase64EncodedString: [OFDataArray dataArrayWithBase64EncodedString:
[elem.children.firstObject stringValue]]; [[[elem children] firstObject] stringValue]];
OFDataArray *response = [authModule OFDataArray *response = [authModule
calculateResponseWithChallenge: challenge]; calculateResponseWithChallenge: challenge];
@ -373,28 +360,28 @@
return; return;
} }
if ([elem.name isEqual: @"success"]) { if ([[elem name] isEqual: @"success"]) {
[authModule parseServerFinalMessage: [authModule parseServerFinalMessage:
[OFDataArray dataArrayWithBase64EncodedString: [OFDataArray dataArrayWithBase64EncodedString:
[elem.children.firstObject stringValue]]]; [[[elem children] firstObject] stringValue]]];
if ([delegate respondsToSelector: if ([delegate respondsToSelector:
@selector(connectionWasAuthenticated:)]) @selector(connectionWasAuthenticated:)])
[delegate connectionWasAuthenticated: self]; [delegate connectionWasAuthenticated: self];
/* Stream restart */ /* Stream restart */
parser.delegate = self; [parser setDelegate: self];
[self XMPP_startStream]; [self XMPP_startStream];
return; return;
} }
if ([elem.name isEqual: @"failure"]) { if ([[elem name] isEqual: @"failure"]) {
of_log(@"Auth failed!"); of_log(@"Auth failed!");
// FIXME: Do more parsing/handling // FIXME: Do more parsing/handling
@throw [XMPPAuthFailedException @throw [XMPPAuthFailedException
newWithClass: isa newWithClass: isa
connection: self connection: self
reason: elem.stringValue]; reason: [elem stringValue]];
} }
assert(0); assert(0);
@ -407,17 +394,17 @@
{ {
BOOL handled = NO; BOOL handled = NO;
if ([iq.ID isEqual: bindID]) { if ([[iq ID] isEqual: bindID]) {
[self XMPP_handleResourceBind: iq]; [self XMPP_handleResourceBind: iq];
return; return;
} }
if ([iq.ID isEqual: sessionID]) { if ([[iq ID] isEqual: sessionID]) {
[self XMPP_handleSession: iq]; [self XMPP_handleSession: iq];
return; return;
} }
if ([iq.ID isEqual: rosterID]) { if ([[iq ID] isEqual: rosterID]) {
[self XMPP_handleRoster: iq]; [self XMPP_handleRoster: iq];
return; return;
} }
@ -427,14 +414,13 @@
didReceiveIQ: iq]; didReceiveIQ: iq];
if (!handled) { if (!handled) {
XMPPJID *from = iq.from; XMPPJID *from = [iq from];
XMPPJID *to = iq.to; XMPPJID *to = [iq to];
OFXMLElement *error; OFXMLElement *error;
[iq setType: @"error"]; [iq setType: @"error"];
[iq setTo: from];
iq.to = from; [iq setFrom: to];
iq.from = to;
error = [OFXMLElement elementWithName: @"error"]; error = [OFXMLElement elementWithName: @"error"];
[error addAttributeWithName: @"type" [error addAttributeWithName: @"type"
@ -467,13 +453,13 @@
- (void)XMPP_handleFeatures: (OFXMLElement*)elem - (void)XMPP_handleFeatures: (OFXMLElement*)elem
{ {
OFXMLElement *starttls = OFXMLElement *starttls =
[elem elementsForName: @"starttls" [[elem elementsForName: @"starttls"
namespace: XMPP_NS_STARTTLS].firstObject; namespace: XMPP_NS_STARTTLS] firstObject];
OFXMLElement *bind = [elem elementsForName: @"bind" OFXMLElement *bind = [[elem elementsForName: @"bind"
namespace: XMPP_NS_BIND].firstObject; namespace: XMPP_NS_BIND] firstObject];
OFXMLElement *session = OFXMLElement *session =
[elem elementsForName: @"session" [[elem elementsForName: @"session"
namespace: XMPP_NS_SESSION].firstObject; namespace: XMPP_NS_SESSION] firstObject];
OFArray *mechs = [elem elementsForName: @"mechanisms" OFArray *mechs = [elem elementsForName: @"mechanisms"
namespace: XMPP_NS_SASL]; namespace: XMPP_NS_SASL];
OFMutableArray *mechanisms = [OFMutableArray array]; OFMutableArray *mechanisms = [OFMutableArray array];
@ -485,10 +471,14 @@
return; return;
} }
if (mechs.count > 0) { if ([mechs count] > 0) {
for (OFXMLElement *mech in [mechs.firstObject children]) OFEnumerator *enumerator;
OFXMLElement *mech;
enumerator = [[[mechs firstObject] children] objectEnumerator];
while ((mech = [enumerator nextObject]) != nil)
[mechanisms addObject: [mechanisms addObject:
[mech.children.firstObject stringValue]]; [[[mech children] firstObject] stringValue]];
if ([mechanisms containsObject: @"SCRAM-SHA-1"]) { if ([mechanisms containsObject: @"SCRAM-SHA-1"]) {
authModule = [[XMPPSCRAMAuth alloc] authModule = [[XMPPSCRAMAuth alloc]
@ -561,18 +551,18 @@
OFXMLElement *bindElem; OFXMLElement *bindElem;
OFXMLElement *jidElem; OFXMLElement *jidElem;
if (![iq.type isEqual: @"result"]) if (![[iq type] isEqual: @"result"])
assert(0); assert(0);
bindElem = iq.children.firstObject; bindElem = [[iq children] firstObject];
if (![bindElem.name isEqual: @"bind"] || if (![[bindElem name] isEqual: @"bind"] ||
![bindElem.namespace isEqual: XMPP_NS_BIND]) ![[bindElem namespace] isEqual: XMPP_NS_BIND])
assert(0); assert(0);
jidElem = bindElem.children.firstObject; jidElem = [[bindElem children] firstObject];
JID = [[XMPPJID alloc] initWithString: JID = [[XMPPJID alloc] initWithString:
[jidElem.children.firstObject stringValue]]; [[[jidElem children] firstObject] stringValue]];
[bindID release]; [bindID release];
bindID = nil; bindID = nil;
@ -601,7 +591,7 @@
- (void)XMPP_handleSession: (XMPPIQ*)iq - (void)XMPP_handleSession: (XMPPIQ*)iq
{ {
if (![iq.type isEqual: @"result"]) if (![[iq type] isEqual: @"result"])
assert(0); assert(0);
if ([delegate respondsToSelector: @selector(connection:wasBoundToJID:)]) if ([delegate respondsToSelector: @selector(connection:wasBoundToJID:)])
@ -630,39 +620,46 @@
- (void)XMPP_handleRoster: (XMPPIQ*)iq - (void)XMPP_handleRoster: (XMPPIQ*)iq
{ {
OFXMLElement *rosterElem; OFXMLElement *rosterElem;
OFEnumerator *enumerator;
OFXMLElement *elem;
if (![iq.type isEqual: @"result"]) if (![[iq type] isEqual: @"result"])
assert(0); assert(0);
rosterElem = iq.children.firstObject; rosterElem = [[iq children] firstObject];
if (![rosterElem.name isEqual: @"query"] || if (![[rosterElem name] isEqual: @"query"] ||
![rosterElem.namespace isEqual: XMPP_NS_ROSTER]) ![[rosterElem namespace] isEqual: XMPP_NS_ROSTER])
assert(0); assert(0);
for (OFXMLElement *elem in rosterElem.children) { enumerator = [[rosterElem children] objectEnumerator];
while ((elem = [enumerator nextObject]) != nil) {
XMPPRosterItem *rosterItem; XMPPRosterItem *rosterItem;
OFMutableArray *groups = [OFMutableArray array]; OFMutableArray *groups = [OFMutableArray array];
OFEnumerator *groupEnumerator;
OFXMLElement *groupElem;
if (![elem.name isEqual: @"item"] || if (![[elem name] isEqual: @"item"] ||
![elem.ns isEqual: XMPP_NS_ROSTER]) ![[elem namespace] isEqual: XMPP_NS_ROSTER])
continue; continue;
rosterItem = [XMPPRosterItem rosterItem]; rosterItem = [XMPPRosterItem rosterItem];
rosterItem.JID = [XMPPJID JIDWithString: [rosterItem setJID: [XMPPJID JIDWithString:
[elem attributeForName: @"jid"].stringValue]; [[elem attributeForName: @"jid"] stringValue]]];
rosterItem.name = [elem attributeForName: @"name"].stringValue; [rosterItem setName:
rosterItem.subscription = [[elem attributeForName: @"name"] stringValue]];
[elem attributeForName: @"subscription"].stringValue; [rosterItem setSubscription:
[[elem attributeForName: @"subscription"] stringValue]];
for (OFXMLElement *groupElem in groupEnumerator =
[elem elementsForName: @"group" [[elem elementsForName: @"group"
namespace: XMPP_NS_ROSTER]) namespace: XMPP_NS_ROSTER] objectEnumerator];
while ((groupElem = [groupEnumerator nextObject]) != nil)
[groups addObject: [groups addObject:
[groupElem.children.firstObject stringValue]]; [[[groupElem children] firstObject] stringValue]];
if (groups.count > 0) if ([groups count] > 0)
rosterItem.groups = groups; [rosterItem setGroups: groups];
[roster XMPP_addRosterItem: rosterItem]; [roster XMPP_addRosterItem: rosterItem];
} }
@ -674,4 +671,71 @@
[rosterID release]; [rosterID release];
rosterID = nil; rosterID = nil;
} }
- (XMPPJID*)JID
{
return [[JID copy] autorelease];
}
- (void)setPort: (uint16_t)port_
{
port = port_;
}
- (uint16_t)port
{
return port;
}
- (void)setDelegate: (id <XMPPConnectionDelegate>)delegate_
{
id old = delegate;
delegate = [(id)delegate_ retain];
[old release];
}
- (id <XMPPConnectionDelegate>)delegate
{
return [[delegate retain] autorelease];
}
- (XMPPRoster*)roster
{
return [[roster retain] autorelease];
}
@end
@implementation OFObject (XMPPConnectionDelegate)
- (void)connectionWasAuthenticated: (XMPPConnection*)conn
{
}
- (void)connection: (XMPPConnection*)conn
wasBoundToJID: (XMPPJID*)jid
{
}
- (void)connectionDidReceiveRoster: (XMPPConnection*)conn
{
}
- (BOOL)connection: (XMPPConnection*)conn
didReceiveIQ: (XMPPIQ*)iq
{
return NO;
}
- (void)connection: (XMPPConnection*)conn
didReceivePresence: (XMPPPresence*)pres
{
}
- (void)connection: (XMPPConnection*)conn
didReceiveMessage: (XMPPMessage*)msg
{
}
- (void)connectionWasClosed: (XMPPConnection*)conn
{
}
@end @end

View file

@ -30,12 +30,15 @@
XMPPConnection *connection; XMPPConnection *connection;
} }
#ifdef OF_HAVE_PROPERTIES
@property (readonly, nonatomic) XMPPConnection *connection; @property (readonly, nonatomic) XMPPConnection *connection;
#endif
+ newWithClass: (Class)class_ + newWithClass: (Class)class_
connection: (XMPPConnection*)conn; connection: (XMPPConnection*)conn;
- initWithClass: (Class)class_ - initWithClass: (Class)class_
connection: (XMPPConnection*)conn; connection: (XMPPConnection*)conn;
- (XMPPConnection*)connection;
@end @end
@interface XMPPStringPrepFailedException: XMPPException @interface XMPPStringPrepFailedException: XMPPException
@ -44,7 +47,9 @@
OFString *string; OFString *string;
} }
#ifdef OF_HAVE_PROPERTIES
@property (readonly, nonatomic) OFString *profile, *string; @property (readonly, nonatomic) OFString *profile, *string;
#endif
+ newWithClass: (Class)class_ + newWithClass: (Class)class_
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
@ -54,6 +59,8 @@
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
profile: (OFString*)profile profile: (OFString*)profile
string: (OFString*)string; string: (OFString*)string;
- (OFString*)profile;
- (OFString*)string;
@end @end
@interface XMPPIDNATranslationFailedException: XMPPException @interface XMPPIDNATranslationFailedException: XMPPException
@ -62,7 +69,9 @@
OFString *string; OFString *string;
} }
#ifdef OF_HAVE_PROPERTIES
@property (readonly, nonatomic) OFString *operation, *string; @property (readonly, nonatomic) OFString *operation, *string;
#endif
+ newWithClass: (Class)class_ + newWithClass: (Class)class_
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
@ -72,6 +81,8 @@
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
operation: (OFString*)operation operation: (OFString*)operation
string: (OFString*)string; string: (OFString*)string;
- (OFString*)operation;
- (OFString*)string;
@end @end
@interface XMPPAuthFailedException: XMPPException @interface XMPPAuthFailedException: XMPPException
@ -79,7 +90,9 @@
OFString *reason; OFString *reason;
} }
#ifdef OF_HAVE_PROPERTIES
@property (readonly, nonatomic) OFString *reason; @property (readonly, nonatomic) OFString *reason;
#endif
+ newWithClass: (Class)class_ + newWithClass: (Class)class_
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
@ -87,4 +100,5 @@
- initWithClass: (Class)class_ - initWithClass: (Class)class_
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
reason: (OFString*)reason_; reason: (OFString*)reason_;
- (OFString*)reason;
@end @end

View file

@ -23,8 +23,6 @@
#import "XMPPExceptions.h" #import "XMPPExceptions.h"
@implementation XMPPException @implementation XMPPException
@synthesize connection;
+ newWithClass: (Class)class_ + newWithClass: (Class)class_
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
{ {
@ -72,11 +70,14 @@
return description; return description;
} }
- (XMPPConnection*)connection
{
return connection;
}
@end @end
@implementation XMPPStringPrepFailedException @implementation XMPPStringPrepFailedException
@synthesize profile, string;
+ newWithClass: (Class)class_ + newWithClass: (Class)class_
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
profile: (OFString*)profile profile: (OFString*)profile
@ -135,11 +136,19 @@
return description; return description;
} }
- (OFString*)profile
{
return profile;
}
- (OFString*)string
{
return string;
}
@end @end
@implementation XMPPIDNATranslationFailedException @implementation XMPPIDNATranslationFailedException
@synthesize operation, string;
+ newWithClass: (Class)class_ + newWithClass: (Class)class_
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
operation: (OFString*)operation operation: (OFString*)operation
@ -197,11 +206,19 @@
return description; return description;
} }
- (OFString*)operation
{
return operation;
}
- (OFString*)string
{
return string;
}
@end @end
@implementation XMPPAuthFailedException @implementation XMPPAuthFailedException
@synthesize reason;
+ newWithClass: (Class)class_ + newWithClass: (Class)class_
connection: (XMPPConnection*)conn connection: (XMPPConnection*)conn
reason: (OFString*)reason_; reason: (OFString*)reason_;
@ -254,4 +271,9 @@
return description; return description;
} }
- (OFString*)reason
{
return reason;
}
@end @end

View file

@ -28,17 +28,19 @@
*/ */
@interface XMPPJID: OFObject <OFCopying> @interface XMPPJID: OFObject <OFCopying>
{ {
/// The JID's localpart
OFString *node; OFString *node;
/// The JID's domainpart
OFString *domain; OFString *domain;
/// The JID's resourcepart
OFString *resource; OFString *resource;
} }
#ifdef OF_HAVE_PROPERTIES
/// The JID's localpart
@property (copy) OFString *node; @property (copy) OFString *node;
/// The JID's domainpart
@property (copy) OFString *domain; @property (copy) OFString *domain;
/// The JID's resourcepart
@property (copy) OFString *resource; @property (copy) OFString *resource;
#endif
/** /**
* Creates a new autoreleased XMPPJID. * Creates a new autoreleased XMPPJID.
@ -72,4 +74,11 @@
* \return An OFString containing the full JID * \return An OFString containing the full JID
*/ */
- (OFString*)fullJID; - (OFString*)fullJID;
- (void)setNode: (OFString*)node;
- (OFString*)node;
- (void)setDomain: (OFString*)domain;
- (OFString*)domain;
- (void)setResource: (OFString*)resource;
- (OFString*)resource;
@end @end

View file

@ -32,6 +32,7 @@
} }
- initWithConnection: (XMPPConnection*)conn; - initWithConnection: (XMPPConnection*)conn;
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem;
- (OFArray*)groups; - (OFArray*)groups;
- (OFArray*)rosterItemsInGroup: (OFString*)group; - (OFArray*)rosterItemsInGroup: (OFString*)group;
- (void)addRosterItem: (XMPPRosterItem*)rosterItem; - (void)addRosterItem: (XMPPRosterItem*)rosterItem;

View file

@ -21,7 +21,6 @@
*/ */
#import "XMPPRoster.h" #import "XMPPRoster.h"
#import "XMPPRoster_private.h"
#import "XMPPRosterItem.h" #import "XMPPRosterItem.h"
#import "XMPPConnection.h" #import "XMPPConnection.h"
#import "XMPPIQ.h" #import "XMPPIQ.h"
@ -52,8 +51,12 @@
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem - (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem
{ {
if (rosterItem.groups.count > 0) { if ([[rosterItem groups] count] > 0) {
for (OFString *group in rosterItem.groups) { OFEnumerator *enumerator;
OFString *group;
enumerator = [[rosterItem groups] objectEnumerator];
while ((group = [enumerator nextObject]) != nil) {
OFMutableArray *rosterGroup = OFMutableArray *rosterGroup =
[groups objectForKey: group]; [groups objectForKey: group];
@ -81,8 +84,11 @@
- (OFArray*)groups - (OFArray*)groups
{ {
OFMutableArray *ret = [OFMutableArray array]; OFMutableArray *ret = [OFMutableArray array];
OFEnumerator *enumerator;
OFString *group;
for (OFString *group in groups) enumerator = [groups keyEnumerator];
while ((group = [enumerator nextObject]) != nil)
[ret addObject: group]; [ret addObject: group];
ret->isa = [OFArray class]; ret->isa = [OFArray class];
@ -110,14 +116,17 @@
namespace: XMPP_NS_ROSTER]; namespace: XMPP_NS_ROSTER];
OFXMLElement *item = [OFXMLElement elementWithName: @"item" OFXMLElement *item = [OFXMLElement elementWithName: @"item"
namespace: XMPP_NS_ROSTER]; namespace: XMPP_NS_ROSTER];
OFEnumerator *enumerator;
OFString *group;
[item addAttributeWithName: @"jid" [item addAttributeWithName: @"jid"
stringValue: rosterItem.JID.bareJID]; stringValue: [[rosterItem JID] bareJID]];
if (rosterItem.name != nil) if ([rosterItem name] != nil)
[item addAttributeWithName: @"name" [item addAttributeWithName: @"name"
stringValue: rosterItem.name]; stringValue: [rosterItem name]];
for (OFString *group in rosterItem.groups) enumerator = [[rosterItem groups] objectEnumerator];
while ((group = [enumerator nextObject]) != nil)
[item addChild: [OFXMLElement elementWithName: @"group" [item addChild: [OFXMLElement elementWithName: @"group"
namespace: XMPP_NS_ROSTER namespace: XMPP_NS_ROSTER
stringValue: group]]; stringValue: group]];
@ -138,7 +147,7 @@
namespace: XMPP_NS_ROSTER]; namespace: XMPP_NS_ROSTER];
[item addAttributeWithName: @"jid" [item addAttributeWithName: @"jid"
stringValue: rosterItem.JID.bareJID]; stringValue: [[rosterItem JID] bareJID]];
[item addAttributeWithName: @"subscription" [item addAttributeWithName: @"subscription"
stringValue: @"remove"]; stringValue: @"remove"];

View file

@ -32,10 +32,20 @@
OFArray *groups; OFArray *groups;
} }
#ifdef OF_HAVE_PROPERTIES
@property (copy) XMPPJID *JID; @property (copy) XMPPJID *JID;
@property (copy) OFString *name; @property (copy) OFString *name;
@property (copy) OFString *subscription; @property (copy) OFString *subscription;
@property (copy) OFArray *groups; @property (copy) OFArray *groups;
#endif
+ rosterItem; + rosterItem;
- (void)setJID: (XMPPJID*)JID;
- (XMPPJID*)JID;
- (void)setName: (OFString*)name;
- (OFString*)name;
- (void)setSubscription: (OFString*)subscription;
- (OFString*)subscription;
- (void)setGroups: (OFArray*)groups;
- (OFArray*)groups;
@end @end

View file

@ -23,13 +23,21 @@
#import "XMPPRosterItem.h" #import "XMPPRosterItem.h"
@implementation XMPPRosterItem @implementation XMPPRosterItem
@synthesize JID, name, subscription, groups;
+ rosterItem + rosterItem
{ {
return [[[self alloc] init] autorelease]; return [[[self alloc] init] autorelease];
} }
- (void)dealloc
{
[JID release];
[name release];
[subscription release];
[groups release];
[super dealloc];
}
- copy - copy
{ {
XMPPRosterItem *new = [[XMPPRosterItem alloc] init]; XMPPRosterItem *new = [[XMPPRosterItem alloc] init];
@ -53,4 +61,52 @@
@"subscription=%@, groups=%@>", @"subscription=%@, groups=%@>",
JID, name, subscription, groups]; JID, name, subscription, groups];
} }
- (void)setJID: (XMPPJID*)JID_
{
XMPPJID *old = JID;
JID = [JID_ copy];
[old release];
}
- (XMPPJID*)JID
{
return [[JID copy] autorelease];
}
- (void)setName: (OFString*)name_
{
OFString *old = name;
name = [name_ copy];
[old release];
}
- (OFString*)name
{
return [[name copy] autorelease];
}
- (void)setSubscription: (OFString*)subscription_
{
OFString *old = subscription;
subscription = [subscription_ copy];
[old release];
}
- (OFString*)subscription
{
return [[subscription copy] autorelease];
}
- (void)setGroups: (OFArray*)groups_
{
OFArray *old = groups;
groups = [groups_ copy];
[old release];
}
- (OFArray*)groups
{
return [[groups copy] autorelease];
}
@end @end

View file

@ -1,27 +0,0 @@
/*
* Copyright (c) 2011, Jonathan Schleifer <js@webkeks.org>
*
* https://webkeks.org/hg/objxmpp/
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice is present in all copies.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#import "XMPPRoster.h"
@interface XMPPRoster ()
- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem;
@end

View file

@ -88,4 +88,11 @@
authcid: (OFString*)authcid authcid: (OFString*)authcid
password: (OFString*)password password: (OFString*)password
hash: (Class)hash; hash: (Class)hash;
- (OFString*)XMPP_genNonce;
- (uint8_t*)XMPP_HMACWithKey: (OFDataArray*)key
data: (OFDataArray*)data;
- (OFDataArray*)XMPP_hiWithData: (OFDataArray *)str
salt: (OFDataArray *)salt_
iterationCount: (intmax_t)i;
@end @end

View file

@ -33,15 +33,6 @@
extern uint32_t arc4random_uniform(uint32_t); extern uint32_t arc4random_uniform(uint32_t);
#endif #endif
@interface XMPPSCRAMAuth ()
- (OFString*)XMPP_genNonce;
- (uint8_t*)XMPP_HMACWithKey: (OFDataArray*)key
data: (OFDataArray*)data;
- (OFDataArray*)XMPP_hiWithData: (OFDataArray *)str
salt: (OFDataArray *)salt_
iterationCount: (intmax_t)i;
@end
@implementation XMPPSCRAMAuth @implementation XMPPSCRAMAuth
+ SCRAMAuthWithAuthcid: (OFString*)authcid + SCRAMAuthWithAuthcid: (OFString*)authcid
password: (OFString*)password password: (OFString*)password
@ -172,6 +163,8 @@ extern uint32_t arc4random_uniform(uint32_t);
OFDataArray *ret, *authMessage, *tmpArray, *salt, *saltedPassword; OFDataArray *ret, *authMessage, *tmpArray, *salt, *saltedPassword;
OFString *tmpString, *sNonce; OFString *tmpString, *sNonce;
OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init];
OFEnumerator *enumerator;
OFString *comp;
enum { enum {
GOT_SNONCE, GOT_SALT, GOT_ITERCOUNT GOT_SNONCE, GOT_SALT, GOT_ITERCOUNT
} got = 0; } got = 0;
@ -184,7 +177,9 @@ extern uint32_t arc4random_uniform(uint32_t);
length: [challenge count] * length: [challenge count] *
[challenge itemSize]]; [challenge itemSize]];
for (OFString *comp in [chal componentsSeparatedByString: @","]) { enumerator =
[[chal componentsSeparatedByString: @","] objectEnumerator];
while ((comp = [enumerator nextObject]) != nil) {
OFString *entry = [comp substringFromIndex: 2 OFString *entry = [comp substringFromIndex: 2
toIndex: [comp length]]; toIndex: [comp length]];
@ -373,14 +368,14 @@ extern uint32_t arc4random_uniform(uint32_t);
uint8_t *kCArray, *kI = NULL, *kO = NULL; uint8_t *kCArray, *kI = NULL, *kO = NULL;
OFHash *hash; OFHash *hash;
if (key.itemSize * key.count > blockSize) { if ([key itemSize] * [key count] > blockSize) {
hash = [[[hashType alloc] init] autorelease]; hash = [[[hashType alloc] init] autorelease];
[hash updateWithBuffer: [key cArray] [hash updateWithBuffer: [key cArray]
ofSize: key.itemSize * key.count]; ofSize: [key itemSize] * [key count]];
[k addNItems: [hashType digestSize] [k addNItems: [hashType digestSize]
fromCArray: [hash digest]]; fromCArray: [hash digest]];
} else } else
[k addNItems: key.itemSize * key.count [k addNItems: [key itemSize] * [key count]
fromCArray: [key cArray]]; fromCArray: [key cArray]];
@try { @try {
@ -391,7 +386,7 @@ extern uint32_t arc4random_uniform(uint32_t);
memset(kO, HMAC_OPAD, blockSize * sizeof(uint8_t)); memset(kO, HMAC_OPAD, blockSize * sizeof(uint8_t));
kCArray = [k cArray]; kCArray = [k cArray];
kSize = k.count; kSize = [k count];
for (i = 0; i < kSize; i++) { for (i = 0; i < kSize; i++) {
kI[i] ^= kCArray[i]; kI[i] ^= kCArray[i];
kO[i] ^= kCArray[i]; kO[i] ^= kCArray[i];
@ -400,12 +395,12 @@ extern uint32_t arc4random_uniform(uint32_t);
k = [OFDataArray dataArrayWithItemSize: 1]; k = [OFDataArray dataArrayWithItemSize: 1];
[k addNItems: blockSize [k addNItems: blockSize
fromCArray: kI]; fromCArray: kI];
[k addNItems: data.itemSize * data.count [k addNItems: [data itemSize] * [data count]
fromCArray: [data cArray]]; fromCArray: [data cArray]];
hash = [[[hashType alloc] init] autorelease]; hash = [[[hashType alloc] init] autorelease];
[hash updateWithBuffer: [k cArray] [hash updateWithBuffer: [k cArray]
ofSize: k.count]; ofSize: [k count]];
k = [OFDataArray dataArrayWithItemSize: 1]; k = [OFDataArray dataArrayWithItemSize: 1];
[k addNItems: blockSize [k addNItems: blockSize
fromCArray: kO]; fromCArray: kO];
@ -418,7 +413,7 @@ extern uint32_t arc4random_uniform(uint32_t);
hash = [[[hashType alloc] init] autorelease]; hash = [[[hashType alloc] init] autorelease];
[hash updateWithBuffer: [k cArray] [hash updateWithBuffer: [k cArray]
ofSize: k.count]; ofSize: [k count]];
[hash retain]; [hash retain];
[pool release]; [pool release];

View file

@ -30,20 +30,22 @@
*/ */
@interface XMPPStanza: OFXMLElement @interface XMPPStanza: OFXMLElement
{ {
/// The value of the stanza's from attribute
XMPPJID *from; XMPPJID *from;
/// The value of the stanza's to attribute
XMPPJID *to; XMPPJID *to;
/// The value of the stanza's type attribute
OFString *type; OFString *type;
/// The value of the stanza's id attribute
OFString *ID; OFString *ID;
} }
#ifdef OF_HAVE_PROPERTIES
/// The value of the stanza's from attribute
@property (copy) XMPPJID *from; @property (copy) XMPPJID *from;
/// The value of the stanza's to attribute
@property (copy) XMPPJID *to; @property (copy) XMPPJID *to;
/// The value of the stanza's type attribute
@property (copy) OFString *type; @property (copy) OFString *type;
/// The value of the stanza's id attribute
@property (copy) OFString *ID; @property (copy) OFString *ID;
#endif
/** /**
* Creates a new autoreleased XMPPStanza with the specified name. * Creates a new autoreleased XMPPStanza with the specified name.
@ -141,4 +143,13 @@
* \return A initialized XMPPStanza * \return A initialized XMPPStanza
*/ */
- initWithElement: (OFXMLElement*)elem; - initWithElement: (OFXMLElement*)elem;
- (void)setFrom: (XMPPJID*)from;
- (XMPPJID*)from;
- (void)setTo: (XMPPJID*)to;
- (XMPPJID*)to;
- (void)setType: (OFString*)type;
- (OFString*)type;
- (void)setID: (OFString*)ID;
- (OFString*)ID;
@end @end

View file

@ -95,10 +95,10 @@
[self setDefaultNamespace: @"jabber:client"]; [self setDefaultNamespace: @"jabber:client"];
if (type_) if (type_ != nil)
[self setType: type_]; [self setType: type_];
if (ID_) if (ID_ != nil)
[self setID: ID_]; [self setID: ID_];
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@ -110,26 +110,32 @@
- initWithElement: (OFXMLElement*)elem - initWithElement: (OFXMLElement*)elem
{ {
self = [super initWithName: elem.name self = [super initWithName: [elem name]
namespace: elem.namespace]; namespace: [elem namespace]];
@try { @try {
for (OFXMLAttribute *attr in elem.attributes) { OFEnumerator *enumerator;
if ([attr.name isEqual: @"from"]) OFXMLAttribute *attr;
OFXMLElement *el;
enumerator = [[elem attributes] objectEnumerator];
while ((attr = [enumerator nextObject]) != nil) {
if ([[attr name] isEqual: @"from"])
[self setFrom: [XMPPJID JIDWithString: [self setFrom: [XMPPJID JIDWithString:
[attr stringValue]]]; [attr stringValue]]];
else if ([attr.name isEqual: @"to"]) else if ([[attr name] isEqual: @"to"])
[self setTo: [XMPPJID JIDWithString: [self setTo: [XMPPJID JIDWithString:
[attr stringValue]]]; [attr stringValue]]];
else if ([attr.name isEqual: @"type"]) else if ([[attr name] isEqual: @"type"])
[self setType: [attr stringValue]]; [self setType: [attr stringValue]];
else if ([attr.name isEqual: @"id"]) else if ([[attr name] isEqual: @"id"])
[self setID: [attr stringValue]]; [self setID: [attr stringValue]];
else else
[self addAttribute: attr]; [self addAttribute: attr];
} }
for (OFXMLElement *el in elem.children) enumerator = [[elem children] objectEnumerator];
while ((el = [enumerator nextObject]) != nil)
[self addChild: el]; [self addChild: el];
} @catch (id e) { } @catch (id e) {
[self release]; [self release];
@ -159,7 +165,7 @@
if (from_ != nil) if (from_ != nil)
[self addAttributeWithName: @"from" [self addAttributeWithName: @"from"
stringValue: from_.fullJID]; stringValue: [from_ fullJID]];
} }
- (XMPPJID*)from - (XMPPJID*)from
@ -177,7 +183,7 @@
if (to_ != nil) if (to_ != nil)
[self addAttributeWithName: @"to" [self addAttributeWithName: @"to"
stringValue: to_.fullJID]; stringValue: [to_ fullJID]];
} }
- (XMPPJID*)to - (XMPPJID*)to

View file

@ -33,7 +33,10 @@
#import "XMPPPresence.h" #import "XMPPPresence.h"
#import "XMPPRoster.h" #import "XMPPRoster.h"
@interface AppDelegate: OFObject <OFApplicationDelegate, XMPPConnectionDelegate> @interface AppDelegate: OFObject
#ifdef OF_HAVE_OPTIONAL_PROTOCOLS
<OFApplicationDelegate, XMPPConnectionDelegate>
#endif
@end @end
OF_APPLICATION_DELEGATE(AppDelegate) OF_APPLICATION_DELEGATE(AppDelegate)
@ -48,8 +51,8 @@ OF_APPLICATION_DELEGATE(AppDelegate)
[pres addShow: @"chat"]; [pres addShow: @"chat"];
[pres addStatus: @"Bored"]; [pres addStatus: @"Bored"];
[pres addPriority: 20]; [pres addPriority: 20];
pres.to = [XMPPJID JIDWithString: @"alice@example.com"]; [pres setTo: [XMPPJID JIDWithString: @"alice@example.com"]];
pres.from = [XMPPJID JIDWithString: @"bob@example.org"]; [pres setFrom: [XMPPJID JIDWithString: @"bob@example.org"]];
assert([[pres stringValue] isEqual: @"<presence to='alice@example.com' " assert([[pres stringValue] isEqual: @"<presence to='alice@example.com' "
@"from='bob@example.org'><show>chat</show>" @"from='bob@example.org'><show>chat</show>"
@"<status>Bored</status><priority>20</priority>" @"<status>Bored</status><priority>20</priority>"
@ -57,35 +60,39 @@ OF_APPLICATION_DELEGATE(AppDelegate)
XMPPMessage *msg = [XMPPMessage messageWithType: @"chat"]; XMPPMessage *msg = [XMPPMessage messageWithType: @"chat"];
[msg addBody: @"Hello everyone"]; [msg addBody: @"Hello everyone"];
msg.to = [XMPPJID JIDWithString: @"jdev@conference.jabber.org"]; [msg setTo: [XMPPJID JIDWithString: @"jdev@conference.jabber.org"]];
msg.from = [XMPPJID JIDWithString: @"alice@example.com"]; [msg setFrom: [XMPPJID JIDWithString: @"alice@example.com"]];
assert([[msg stringValue] isEqual: @"<message type='chat' " assert([[msg stringValue] isEqual: @"<message type='chat' "
@"to='jdev@conference.jabber.org' " @"to='jdev@conference.jabber.org' "
@"from='alice@example.com'><body>Hello everyone</body>" @"from='alice@example.com'><body>Hello everyone</body>"
@"</message>"]); @"</message>"]);
XMPPIQ *iq = [XMPPIQ IQWithType: @"set" ID: @"128"]; XMPPIQ *iq = [XMPPIQ IQWithType: @"set" ID: @"128"];
iq.to = [XMPPJID JIDWithString: @"juliet@capulet.lit"]; [iq setTo: [XMPPJID JIDWithString: @"juliet@capulet.lit"]];
iq.from = [XMPPJID JIDWithString: @"romeo@montague.lit"]; [iq setFrom: [XMPPJID JIDWithString: @"romeo@montague.lit"]];
assert([[iq stringValue] isEqual: @"<iq type='set' id='128' " assert([[iq stringValue] isEqual: @"<iq type='set' id='128' "
@"to='juliet@capulet.lit' " @"to='juliet@capulet.lit' "
@"from='romeo@montague.lit'/>"]); @"from='romeo@montague.lit'/>"]);
OFXMLElement *elem = [OFXMLElement elementWithName: @"iq"]; OFXMLElement *elem = [OFXMLElement elementWithName: @"iq"];
[elem addAttributeWithName: @"from" stringValue: @"bob@localhost"]; [elem addAttributeWithName: @"from"
[elem addAttributeWithName: @"to" stringValue: @"alice@localhost"]; stringValue: @"bob@localhost"];
[elem addAttributeWithName: @"type" stringValue: @"get"]; [elem addAttributeWithName: @"to"
[elem addAttributeWithName: @"id" stringValue: @"42"]; stringValue: @"alice@localhost"];
[elem addAttributeWithName: @"type"
stringValue: @"get"];
[elem addAttributeWithName: @"id"
stringValue: @"42"];
XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem]; XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem];
assert([[elem stringValue] isEqual: [stanza stringValue]]); assert([[elem stringValue] isEqual: [stanza stringValue]]);
assert(([[OFString stringWithFormat: @"%@, %@, %@, %@", assert(([[OFString stringWithFormat: @"%@, %@, %@, %@",
stanza.from.fullJID, stanza.to.fullJID, stanza.type, stanza.ID] [[stanza from] fullJID], [[stanza to] fullJID], [stanza type],
isEqual: @"bob@localhost, alice@localhost, get, 42"])); [stanza ID]] isEqual: @"bob@localhost, alice@localhost, get, 42"]));
conn = [[XMPPConnection alloc] init]; conn = [[XMPPConnection alloc] init];
conn.delegate = self; [conn setDelegate: self];
if (arguments.count != 3) { if ([arguments count] != 3) {
of_log(@"Invalid count of command line arguments!"); of_log(@"Invalid count of command line arguments!");
[OFApplication terminateWithStatus: 1]; [OFApplication terminateWithStatus: 1];
} }
@ -94,7 +101,6 @@ OF_APPLICATION_DELEGATE(AppDelegate)
[conn setUsername: [arguments objectAtIndex: 1]]; [conn setUsername: [arguments objectAtIndex: 1]];
[conn setPassword: [arguments objectAtIndex: 2]]; [conn setPassword: [arguments objectAtIndex: 2]];
[conn setResource: @"ObjXMPP"]; [conn setResource: @"ObjXMPP"];
[conn setUseTLS: NO];
[conn connect]; [conn connect];
@try { @try {
@ -120,11 +126,14 @@ OF_APPLICATION_DELEGATE(AppDelegate)
- (void)connectionDidReceiveRoster :(XMPPConnection*)conn - (void)connectionDidReceiveRoster :(XMPPConnection*)conn
{ {
XMPPPresence *pres; XMPPPresence *pres;
OFEnumerator *enumerator;
OFString *group;
of_log(@"Got roster! Groups: %@", conn.roster.groups); of_log(@"Got roster! Groups: %@", [[conn roster] groups]);
for (OFString *group in conn.roster.groups) enumerator = [[[conn roster] groups] objectEnumerator];
while ((group = [enumerator nextObject]) != nil)
of_log(@"Group %@: %@", group, of_log(@"Group %@: %@", group,
[conn.roster rosterItemsInGroup: group]); [[conn roster] rosterItemsInGroup: group]);
pres = [XMPPPresence presence]; pres = [XMPPPresence presence];
[pres addPriority: 10]; [pres addPriority: 10];