Index: ObjXMPP.xcodeproj/project.pbxproj ================================================================== --- ObjXMPP.xcodeproj/project.pbxproj +++ ObjXMPP.xcodeproj/project.pbxproj @@ -35,11 +35,10 @@ 4BD0AB16134129B900445289 /* ObjOpenSSL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4BD0AB15134129B900445289 /* ObjOpenSSL.framework */; }; 4BD9BF59134003F700DAB43A /* XMPPRosterItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BD9BF57134003F700DAB43A /* XMPPRosterItem.h */; }; 4BD9BF5A134003F700DAB43A /* XMPPRosterItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */; }; 4BDEF8071340B240000156D1 /* XMPPRoster.h in Headers */ = {isa = PBXBuildFile; fileRef = 4BDEF8051340B240000156D1 /* XMPPRoster.h */; }; 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 */ /* Begin PBXCopyFilesBuildPhase section */ 4B1295DE1337BD2D00154B25 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; @@ -82,11 +81,10 @@ 4BD0AB15134129B900445289 /* ObjOpenSSL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ObjOpenSSL.framework; path = ../ObjOpenSSL/build/Debug/ObjOpenSSL.framework; sourceTree = ""; }; 4BD9BF57134003F700DAB43A /* XMPPRosterItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = XMPPRosterItem.h; path = src/XMPPRosterItem.h; 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; }; 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 */ /* Begin PBXFrameworksBuildPhase section */ 4B1295DD1337BD2D00154B25 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -164,11 +162,10 @@ 4BC559E61337AC0900E345C7 /* XMPPPLAINAuth.h */, 4BC559E71337AC0900E345C7 /* XMPPPLAINAuth.m */, 4BC559E81337AC0900E345C7 /* XMPPPresence.h */, 4BC559E91337AC0900E345C7 /* XMPPPresence.m */, 4BDEF8051340B240000156D1 /* XMPPRoster.h */, - 4BF459B81340DE3600701BCC /* XMPPRoster_private.h */, 4BDEF8061340B240000156D1 /* XMPPRoster.m */, 4BD9BF57134003F700DAB43A /* XMPPRosterItem.h */, 4BD9BF58134003F700DAB43A /* XMPPRosterItem.m */, 4BC559EA1337AC0900E345C7 /* XMPPSCRAMAuth.h */, 4BC559FD1337AC1800E345C7 /* XMPPSCRAMAuth.m */, @@ -204,11 +201,10 @@ 4BC559FA1337AC0900E345C7 /* XMPPPresence.h in Headers */, 4BC559FC1337AC0900E345C7 /* XMPPSCRAMAuth.h in Headers */, 4BC55A011337AC1800E345C7 /* XMPPStanza.h in Headers */, 4BD9BF59134003F700DAB43A /* XMPPRosterItem.h in Headers */, 4BDEF8071340B240000156D1 /* XMPPRoster.h in Headers */, - 4BF459B91340DE3600701BCC /* XMPPRoster_private.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -1,6 +1,6 @@ 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 clean: rm -f *.o *.so *.dylib *.dll Index: src/XMPPAuthenticator.h ================================================================== --- src/XMPPAuthenticator.h +++ src/XMPPAuthenticator.h @@ -25,20 +25,23 @@ /** * \brief A base class for classes implementing authentication mechanisms */ @interface XMPPAuthenticator: OFObject { - /// The authzid to get authorization for OFString *authzid; - /// The authcid to authenticate with OFString *authcid; - /// The password to authenticate with OFString *password; } + +#ifdef OF_HAVE_PROPERTIES +/// The authzid to get authorization for @property (copy) OFString *authzid; +/// The authcid to authenticate with @property (copy) OFString *authcid; +/// The password to authenticate with @property (copy) OFString *password; +#endif /** * Initializes an already allocated XMPPAuthenticator with an authcid * and password. * @@ -77,6 +80,13 @@ * Checks whether the servers final message was valid * * \param message The servers final message */ - (void)parseServerFinalMessage: (OFDataArray*)message; + +- (void)setAuthzid: (OFString*)authzid; +- (OFString*)authzid; +- (void)setAuthcid: (OFString*)authcid; +- (OFString*)authcid; +- (void)setPassword: (OFString*)password; +- (OFString*)password; @end Index: src/XMPPAuthenticator.m ================================================================== --- src/XMPPAuthenticator.m +++ src/XMPPAuthenticator.m @@ -21,14 +21,10 @@ */ #import "XMPPAuthenticator.h" @implementation XMPPAuthenticator -@synthesize authzid; -@synthesize authcid; -@synthesize password; - - initWithAuthcid: (OFString*)authcid_ password: (OFString*)password_ { return [self initWithAuthzid: nil authcid: authcid_ @@ -54,10 +50,46 @@ [authcid release]; [password release]; [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 { @throw [OFNotImplementedException newWithClass: isa selector: _cmd]; Index: src/XMPPConnection.h ================================================================== --- src/XMPPConnection.h +++ src/XMPPConnection.h @@ -39,11 +39,16 @@ #define XMPP_NS_STANZAS @"urn:ietf:params:xml:ns:xmpp-stanzas" #define XMPP_NS_SESSION @"urn:ietf:params:xml:ns:xmpp-session" #define XMPP_NS_STREAM @"http://etherx.jabber.org/streams" @protocol XMPPConnectionDelegate +#ifndef XMPP_CONNECTION_M + +#endif +#ifdef OF_HAVE_OPTIONAL_PROTOCOLS @optional +#endif - (void)connectionWasAuthenticated: (XMPPConnection*)conn; - (void)connection: (XMPPConnection*)conn wasBoundToJID: (XMPPJID*)jid; - (void)connectionDidReceiveRoster: (XMPPConnection*)conn; - (BOOL)connection: (XMPPConnection*)conn @@ -56,12 +61,14 @@ @end /** * \brief A class which abstracts a connection to an XMPP service. */ -@interface XMPPConnection: OFObject +@interface XMPPConnection: OFObject +#ifdef OF_HAVE_OPTONAL_PROTOCOLS + +#endif { OFTCPSocket *sock; OFXMLParser *parser; OFXMLElementBuilder *elementBuilder; OFString *username, *password, *server, *resource; @@ -73,15 +80,17 @@ unsigned int lastID; OFString *bindID, *sessionID, *rosterID; XMPPRoster *roster; } +#ifdef OF_HAVE_PROPERTIES @property (copy) OFString *username, *password, *server, *resource; @property (copy, readonly) XMPPJID *JID; @property (assign) uint16_t port; @property (retain) id delegate; @property (readonly, retain) XMPPRoster *roster; +#endif /** * Connects to the XMPP service. */ - (void)connect; @@ -107,6 +116,37 @@ /** * Requests the roster. */ - (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 )delegate; +- (id )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) @end Index: src/XMPPConnection.m ================================================================== --- src/XMPPConnection.m +++ src/XMPPConnection.m @@ -19,10 +19,12 @@ * 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. */ +#define XMPP_CONNECTION_M + #include #include #include @@ -35,32 +37,14 @@ #import "XMPPJID.h" #import "XMPPIQ.h" #import "XMPPMessage.h" #import "XMPPPresence.h" #import "XMPPRoster.h" -#import "XMPPRoster_private.h" #import "XMPPRosterItem.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 -@synthesize JID, port, delegate, roster; - - init { self = [super init]; @try { @@ -68,12 +52,12 @@ parser = [[OFXMLParser alloc] init]; elementBuilder = [[OFXMLElementBuilder alloc] init]; port = 5222; - parser.delegate = self; - elementBuilder.delegate = self; + [parser setDelegate: self]; + [elementBuilder setDelegate: self]; roster = [[XMPPRoster alloc] initWithConnection: self]; } @catch (id e) { [self release]; @throw e; @@ -164,14 +148,14 @@ Idna_rc rc; if ((rc = idna_to_ascii_8z([server_ cString], &srv, IDNA_USE_STD3_ASCII_RULES)) != IDNA_SUCCESS) @throw [XMPPIDNATranslationFailedException - newWithClass: isa - connection: self - operation: @"ToASCII" - string: server_]; + newWithClass: isa + connection: self + operation: @"ToASCII" + string: server_]; @try { server = [[OFString alloc] initWithCString: srv]; } @finally { free(srv); @@ -256,36 +240,39 @@ withPrefix: (OFString*)prefix namespace: (OFString*)ns attributes: (OFArray*)attrs { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFEnumerator *enumerator; + OFXMLAttribute *attr; if (![name isEqual: @"stream"] || ![prefix isEqual: @"stream"] || ![ns isEqual: XMPP_NS_STREAM]) { of_log(@"Did not get expected stream start!"); assert(0); } - for (OFXMLAttribute *attr in attrs) { - if ([attr.name isEqual: @"from"] && - ![attr.stringValue isEqual: server]) { + enumerator = [attrs objectEnumerator]; + while ((attr = [enumerator nextObject]) != nil) { + if ([[attr name] isEqual: @"from"] && + ![[attr stringValue] isEqual: server]) { of_log(@"Got invalid from in stream start!"); assert(0); } } - parser.delegate = elementBuilder; + [parser setDelegate: elementBuilder]; [pool release]; } - (void)elementBuilder: (OFXMLElementBuilder*)b didBuildElement: (OFXMLElement*)elem { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - elem.defaultNamespace = XMPP_NS_CLIENT; + [elem setDefaultNamespace: XMPP_NS_CLIENT]; [elem setPrefix: @"stream" forNamespace: XMPP_NS_STREAM]; of_log(@"In: %@", elem); @@ -303,64 +290,64 @@ @"version='1.0'>", server]; } - (void)XMPP_handleStanza: (OFXMLElement*)elem { - if ([elem.namespace isEqual: XMPP_NS_CLIENT]) { - if ([elem.name isEqual: @"iq"]) { + if ([[elem namespace] isEqual: XMPP_NS_CLIENT]) { + if ([[elem name] isEqual: @"iq"]) { [self XMPP_handleIQ: [XMPPIQ stanzaWithElement: elem]]; return; } - if ([elem.name isEqual: @"message"]) { + if ([[elem name] isEqual: @"message"]) { [self XMPP_handleMessage: [XMPPMessage stanzaWithElement: elem]]; return; } - if ([elem.name isEqual: @"presence"]) { + if ([[elem name] isEqual: @"presence"]) { [self XMPP_handlePresence: [XMPPPresence stanzaWithElement: elem]]; return; } assert(0); } - if ([elem.namespace isEqual: XMPP_NS_STREAM]) { - if ([elem.name isEqual: @"features"]) { + if ([[elem namespace] isEqual: XMPP_NS_STREAM]) { + if ([[elem name] isEqual: @"features"]) { [self XMPP_handleFeatures: elem]; return; } assert(0); } - if ([elem.namespace isEqual: XMPP_NS_STARTTLS]) { - if ([elem.name isEqual: @"proceed"]) { + if ([[elem namespace] isEqual: XMPP_NS_STARTTLS]) { + if ([[elem name] isEqual: @"proceed"]) { /* FIXME: Catch errors here */ sock = [[SSLSocket alloc] initWithSocket: sock]; /* Stream restart */ - parser.delegate = self; + [parser setDelegate: self]; [self XMPP_startStream]; return; } - if ([elem.name isEqual: @"failure"]) + if ([[elem name] isEqual: @"failure"]) /* TODO: Find/create an exception to throw here */ @throw [OFException newWithClass: isa]; assert(0); } - if ([elem.namespace isEqual: XMPP_NS_SASL]) { - if ([elem.name isEqual: @"challenge"]) { + if ([[elem namespace] isEqual: XMPP_NS_SASL]) { + if ([[elem name] isEqual: @"challenge"]) { OFXMLElement *responseTag; OFDataArray *challenge = [OFDataArray dataArrayWithBase64EncodedString: - [elem.children.firstObject stringValue]]; + [[[elem children] firstObject] stringValue]]; OFDataArray *response = [authModule calculateResponseWithChallenge: challenge]; responseTag = [OFXMLElement elementWithName: @"response" @@ -371,32 +358,32 @@ [self sendStanza: responseTag]; return; } - if ([elem.name isEqual: @"success"]) { + if ([[elem name] isEqual: @"success"]) { [authModule parseServerFinalMessage: [OFDataArray dataArrayWithBase64EncodedString: - [elem.children.firstObject stringValue]]]; + [[[elem children] firstObject] stringValue]]]; if ([delegate respondsToSelector: @selector(connectionWasAuthenticated:)]) [delegate connectionWasAuthenticated: self]; /* Stream restart */ - parser.delegate = self; + [parser setDelegate: self]; [self XMPP_startStream]; return; } - if ([elem.name isEqual: @"failure"]) { + if ([[elem name] isEqual: @"failure"]) { of_log(@"Auth failed!"); // FIXME: Do more parsing/handling @throw [XMPPAuthFailedException newWithClass: isa connection: self - reason: elem.stringValue]; + reason: [elem stringValue]]; } assert(0); } @@ -405,38 +392,37 @@ - (void)XMPP_handleIQ: (XMPPIQ*)iq { BOOL handled = NO; - if ([iq.ID isEqual: bindID]) { + if ([[iq ID] isEqual: bindID]) { [self XMPP_handleResourceBind: iq]; return; } - if ([iq.ID isEqual: sessionID]) { + if ([[iq ID] isEqual: sessionID]) { [self XMPP_handleSession: iq]; return; } - if ([iq.ID isEqual: rosterID]) { + if ([[iq ID] isEqual: rosterID]) { [self XMPP_handleRoster: iq]; return; } if ([delegate respondsToSelector: @selector(connection:didReceiveIQ:)]) handled = [delegate connection: self didReceiveIQ: iq]; if (!handled) { - XMPPJID *from = iq.from; - XMPPJID *to = iq.to; + XMPPJID *from = [iq from]; + XMPPJID *to = [iq to]; OFXMLElement *error; [iq setType: @"error"]; - - iq.to = from; - iq.from = to; + [iq setTo: from]; + [iq setFrom: to]; error = [OFXMLElement elementWithName: @"error"]; [error addAttributeWithName: @"type" stringValue: @"cancel"]; [error addChild: @@ -465,17 +451,17 @@ } - (void)XMPP_handleFeatures: (OFXMLElement*)elem { OFXMLElement *starttls = - [elem elementsForName: @"starttls" - namespace: XMPP_NS_STARTTLS].firstObject; - OFXMLElement *bind = [elem elementsForName: @"bind" - namespace: XMPP_NS_BIND].firstObject; + [[elem elementsForName: @"starttls" + namespace: XMPP_NS_STARTTLS] firstObject]; + OFXMLElement *bind = [[elem elementsForName: @"bind" + namespace: XMPP_NS_BIND] firstObject]; OFXMLElement *session = - [elem elementsForName: @"session" - namespace: XMPP_NS_SESSION].firstObject; + [[elem elementsForName: @"session" + namespace: XMPP_NS_SESSION] firstObject]; OFArray *mechs = [elem elementsForName: @"mechanisms" namespace: XMPP_NS_SASL]; OFMutableArray *mechanisms = [OFMutableArray array]; if (starttls != nil) { @@ -483,14 +469,18 @@ [OFXMLElement elementWithName: @"starttls" namespace: XMPP_NS_STARTTLS]]; return; } - if (mechs.count > 0) { - for (OFXMLElement *mech in [mechs.firstObject children]) + if ([mechs count] > 0) { + OFEnumerator *enumerator; + OFXMLElement *mech; + + enumerator = [[[mechs firstObject] children] objectEnumerator]; + while ((mech = [enumerator nextObject]) != nil) [mechanisms addObject: - [mech.children.firstObject stringValue]]; + [[[mech children] firstObject] stringValue]]; if ([mechanisms containsObject: @"SCRAM-SHA-1"]) { authModule = [[XMPPSCRAMAuth alloc] initWithAuthcid: username password: password @@ -559,22 +549,22 @@ - (void)XMPP_handleResourceBind: (XMPPIQ*)iq { OFXMLElement *bindElem; OFXMLElement *jidElem; - if (![iq.type isEqual: @"result"]) + if (![[iq type] isEqual: @"result"]) assert(0); - bindElem = iq.children.firstObject; + bindElem = [[iq children] firstObject]; - if (![bindElem.name isEqual: @"bind"] || - ![bindElem.namespace isEqual: XMPP_NS_BIND]) + if (![[bindElem name] isEqual: @"bind"] || + ![[bindElem namespace] isEqual: XMPP_NS_BIND]) assert(0); - jidElem = bindElem.children.firstObject; + jidElem = [[bindElem children] firstObject]; JID = [[XMPPJID alloc] initWithString: - [jidElem.children.firstObject stringValue]]; + [[[jidElem children] firstObject] stringValue]]; [bindID release]; bindID = nil; if (needsSession) { @@ -599,11 +589,11 @@ [self sendStanza: iq]; } - (void)XMPP_handleSession: (XMPPIQ*)iq { - if (![iq.type isEqual: @"result"]) + if (![[iq type] isEqual: @"result"]) assert(0); if ([delegate respondsToSelector: @selector(connection:wasBoundToJID:)]) [delegate connection: self wasBoundToJID: JID]; @@ -628,43 +618,50 @@ } - (void)XMPP_handleRoster: (XMPPIQ*)iq { OFXMLElement *rosterElem; - - if (![iq.type isEqual: @"result"]) - assert(0); - - rosterElem = iq.children.firstObject; - - if (![rosterElem.name isEqual: @"query"] || - ![rosterElem.namespace isEqual: XMPP_NS_ROSTER]) - assert(0); - - for (OFXMLElement *elem in rosterElem.children) { - XMPPRosterItem *rosterItem; - OFMutableArray *groups = [OFMutableArray array]; - - if (![elem.name isEqual: @"item"] || - ![elem.ns isEqual: XMPP_NS_ROSTER]) + OFEnumerator *enumerator; + OFXMLElement *elem; + + if (![[iq type] isEqual: @"result"]) + assert(0); + + rosterElem = [[iq children] firstObject]; + + if (![[rosterElem name] isEqual: @"query"] || + ![[rosterElem namespace] isEqual: XMPP_NS_ROSTER]) + assert(0); + + enumerator = [[rosterElem children] objectEnumerator]; + while ((elem = [enumerator nextObject]) != nil) { + XMPPRosterItem *rosterItem; + OFMutableArray *groups = [OFMutableArray array]; + OFEnumerator *groupEnumerator; + OFXMLElement *groupElem; + + if (![[elem name] isEqual: @"item"] || + ![[elem namespace] isEqual: XMPP_NS_ROSTER]) continue; rosterItem = [XMPPRosterItem rosterItem]; - rosterItem.JID = [XMPPJID JIDWithString: - [elem attributeForName: @"jid"].stringValue]; - rosterItem.name = [elem attributeForName: @"name"].stringValue; - rosterItem.subscription = - [elem attributeForName: @"subscription"].stringValue; - - for (OFXMLElement *groupElem in - [elem elementsForName: @"group" - namespace: XMPP_NS_ROSTER]) + [rosterItem setJID: [XMPPJID JIDWithString: + [[elem attributeForName: @"jid"] stringValue]]]; + [rosterItem setName: + [[elem attributeForName: @"name"] stringValue]]; + [rosterItem setSubscription: + [[elem attributeForName: @"subscription"] stringValue]]; + + groupEnumerator = + [[elem elementsForName: @"group" + namespace: XMPP_NS_ROSTER] objectEnumerator]; + while ((groupElem = [groupEnumerator nextObject]) != nil) [groups addObject: - [groupElem.children.firstObject stringValue]]; + [[[groupElem children] firstObject] stringValue]]; - if (groups.count > 0) - rosterItem.groups = groups; + if ([groups count] > 0) + [rosterItem setGroups: groups]; [roster XMPP_addRosterItem: rosterItem]; } if ([delegate respondsToSelector: @@ -672,6 +669,73 @@ [delegate connectionDidReceiveRoster: self]; [rosterID release]; rosterID = nil; } + +- (XMPPJID*)JID +{ + return [[JID copy] autorelease]; +} + +- (void)setPort: (uint16_t)port_ +{ + port = port_; +} + +- (uint16_t)port +{ + return port; +} + +- (void)setDelegate: (id )delegate_ +{ + id old = delegate; + delegate = [(id)delegate_ retain]; + [old release]; +} + +- (id )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 Index: src/XMPPExceptions.h ================================================================== --- src/XMPPExceptions.h +++ src/XMPPExceptions.h @@ -28,63 +28,77 @@ @interface XMPPException: OFException { XMPPConnection *connection; } +#ifdef OF_HAVE_PROPERTIES @property (readonly, nonatomic) XMPPConnection *connection; +#endif + newWithClass: (Class)class_ connection: (XMPPConnection*)conn; - initWithClass: (Class)class_ connection: (XMPPConnection*)conn; +- (XMPPConnection*)connection; @end @interface XMPPStringPrepFailedException: XMPPException { OFString *profile; OFString *string; } +#ifdef OF_HAVE_PROPERTIES @property (readonly, nonatomic) OFString *profile, *string; +#endif + newWithClass: (Class)class_ connection: (XMPPConnection*)conn profile: (OFString*)profile string: (OFString*)string; - initWithClass: (Class)class_ connection: (XMPPConnection*)conn profile: (OFString*)profile string: (OFString*)string; +- (OFString*)profile; +- (OFString*)string; @end @interface XMPPIDNATranslationFailedException: XMPPException { OFString *operation; OFString *string; } +#ifdef OF_HAVE_PROPERTIES @property (readonly, nonatomic) OFString *operation, *string; +#endif + newWithClass: (Class)class_ connection: (XMPPConnection*)conn operation: (OFString*)operation string: (OFString*)string; - initWithClass: (Class)class_ connection: (XMPPConnection*)conn operation: (OFString*)operation string: (OFString*)string; +- (OFString*)operation; +- (OFString*)string; @end @interface XMPPAuthFailedException: XMPPException { OFString *reason; } +#ifdef OF_HAVE_PROPERTIES @property (readonly, nonatomic) OFString *reason; +#endif + newWithClass: (Class)class_ connection: (XMPPConnection*)conn reason: (OFString*)reason_; - initWithClass: (Class)class_ connection: (XMPPConnection*)conn reason: (OFString*)reason_; +- (OFString*)reason; @end Index: src/XMPPExceptions.m ================================================================== --- src/XMPPExceptions.m +++ src/XMPPExceptions.m @@ -21,12 +21,10 @@ */ #import "XMPPExceptions.h" @implementation XMPPException -@synthesize connection; - + newWithClass: (Class)class_ connection: (XMPPConnection*)conn { return [[self alloc] initWithClass: class_ connection: conn]; @@ -70,15 +68,18 @@ description = [[OFString alloc] initWithFormat: @"An exception occurred in class %@!", inClass]; return description; } + +- (XMPPConnection*)connection +{ + return connection; +} @end @implementation XMPPStringPrepFailedException -@synthesize profile, string; - + newWithClass: (Class)class_ connection: (XMPPConnection*)conn profile: (OFString*)profile string: (OFString*)string { @@ -133,15 +134,23 @@ @"Stringprep with profile %@ failed on string '%@'!", profile, string]; return description; } + +- (OFString*)profile +{ + return profile; +} + +- (OFString*)string +{ + return string; +} @end @implementation XMPPIDNATranslationFailedException -@synthesize operation, string; - + newWithClass: (Class)class_ connection: (XMPPConnection*)conn operation: (OFString*)operation string: (OFString*)string { @@ -195,15 +204,23 @@ description = [[OFString alloc] initWithFormat: @"IDNA operation %@ failed on string '%@'!", operation, string]; return description; } + +- (OFString*)operation +{ + return operation; +} + +- (OFString*)string +{ + return string; +} @end @implementation XMPPAuthFailedException -@synthesize reason; - + newWithClass: (Class)class_ connection: (XMPPConnection*)conn reason: (OFString*)reason_; { return [[self alloc] initWithClass: class_ @@ -252,6 +269,11 @@ description = [[OFString alloc] initWithFormat: @"Authentication failed. Reason: %@!", reason]; return description; } + +- (OFString*)reason +{ + return reason; +} @end Index: src/XMPPJID.h ================================================================== --- src/XMPPJID.h +++ src/XMPPJID.h @@ -26,21 +26,23 @@ /** * \brief A class for easy handling of JIDs. */ @interface XMPPJID: OFObject { - /// The JID's localpart OFString *node; - /// The JID's domainpart OFString *domain; - /// The JID's resourcepart OFString *resource; } +#ifdef OF_HAVE_PROPERTIES +/// The JID's localpart @property (copy) OFString *node; +/// The JID's domainpart @property (copy) OFString *domain; +/// The JID's resourcepart @property (copy) OFString *resource; +#endif /** * Creates a new autoreleased XMPPJID. * * \return A new autoreleased XMPPJID @@ -70,6 +72,13 @@ /** * \return An OFString containing the full JID */ - (OFString*)fullJID; + +- (void)setNode: (OFString*)node; +- (OFString*)node; +- (void)setDomain: (OFString*)domain; +- (OFString*)domain; +- (void)setResource: (OFString*)resource; +- (OFString*)resource; @end Index: src/XMPPRoster.h ================================================================== --- src/XMPPRoster.h +++ src/XMPPRoster.h @@ -30,11 +30,12 @@ XMPPConnection *connection; OFMutableDictionary *groups; } - initWithConnection: (XMPPConnection*)conn; +- (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem; - (OFArray*)groups; - (OFArray*)rosterItemsInGroup: (OFString*)group; - (void)addRosterItem: (XMPPRosterItem*)rosterItem; - (void)updateRosterItem: (XMPPRosterItem*)rosterItem; - (void)deleteRosterItem: (XMPPRosterItem*)rosterItem; @end Index: src/XMPPRoster.m ================================================================== --- src/XMPPRoster.m +++ src/XMPPRoster.m @@ -19,11 +19,10 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ #import "XMPPRoster.h" -#import "XMPPRoster_private.h" #import "XMPPRosterItem.h" #import "XMPPConnection.h" #import "XMPPIQ.h" #import "XMPPJID.h" @@ -50,12 +49,16 @@ [super dealloc]; } - (void)XMPP_addRosterItem: (XMPPRosterItem*)rosterItem { - if (rosterItem.groups.count > 0) { - for (OFString *group in rosterItem.groups) { + if ([[rosterItem groups] count] > 0) { + OFEnumerator *enumerator; + OFString *group; + + enumerator = [[rosterItem groups] objectEnumerator]; + while ((group = [enumerator nextObject]) != nil) { OFMutableArray *rosterGroup = [groups objectForKey: group]; if (rosterGroup == nil) { rosterGroup = [OFMutableArray array]; @@ -79,12 +82,15 @@ } - (OFArray*)groups { 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->isa = [OFArray class]; return ret; } @@ -108,18 +114,21 @@ ID: [connection generateStanzaID]]; OFXMLElement *query = [OFXMLElement elementWithName: @"query" namespace: XMPP_NS_ROSTER]; OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPP_NS_ROSTER]; + OFEnumerator *enumerator; + OFString *group; [item addAttributeWithName: @"jid" - stringValue: rosterItem.JID.bareJID]; - if (rosterItem.name != nil) + stringValue: [[rosterItem JID] bareJID]]; + if ([rosterItem name] != nil) [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" namespace: XMPP_NS_ROSTER stringValue: group]]; [query addChild: item]; @@ -136,15 +145,15 @@ namespace: XMPP_NS_ROSTER]; OFXMLElement *item = [OFXMLElement elementWithName: @"item" namespace: XMPP_NS_ROSTER]; [item addAttributeWithName: @"jid" - stringValue: rosterItem.JID.bareJID]; + stringValue: [[rosterItem JID] bareJID]]; [item addAttributeWithName: @"subscription" stringValue: @"remove"]; [query addChild: item]; [iq addChild: query]; [connection sendStanza: iq]; } @end Index: src/XMPPRosterItem.h ================================================================== --- src/XMPPRosterItem.h +++ src/XMPPRosterItem.h @@ -30,12 +30,22 @@ OFString *name; OFString *subscription; OFArray *groups; } +#ifdef OF_HAVE_PROPERTIES @property (copy) XMPPJID *JID; @property (copy) OFString *name; @property (copy) OFString *subscription; @property (copy) OFArray *groups; +#endif + 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 Index: src/XMPPRosterItem.m ================================================================== --- src/XMPPRosterItem.m +++ src/XMPPRosterItem.m @@ -21,16 +21,24 @@ */ #import "XMPPRosterItem.h" @implementation XMPPRosterItem -@synthesize JID, name, subscription, groups; - + rosterItem { return [[[self alloc] init] autorelease]; } + +- (void)dealloc +{ + [JID release]; + [name release]; + [subscription release]; + [groups release]; + + [super dealloc]; +} - copy { XMPPRosterItem *new = [[XMPPRosterItem alloc] init]; @@ -51,6 +59,54 @@ { return [OFString stringWithFormat: @"", 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 DELETED src/XMPPRoster_private.h Index: src/XMPPRoster_private.h ================================================================== --- src/XMPPRoster_private.h +++ src/XMPPRoster_private.h @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2011, Jonathan Schleifer - * - * 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 Index: src/XMPPSCRAMAuth.h ================================================================== --- src/XMPPSCRAMAuth.h +++ src/XMPPSCRAMAuth.h @@ -86,6 +86,13 @@ */ - initWithAuthzid: (OFString*)authzid authcid: (OFString*)authcid password: (OFString*)password 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 Index: src/XMPPSCRAMAuth.m ================================================================== --- src/XMPPSCRAMAuth.m +++ src/XMPPSCRAMAuth.m @@ -31,19 +31,10 @@ #ifndef HAVE_ARC4RANDOM_UNIFORM extern uint32_t arc4random_uniform(uint32_t); #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 + SCRAMAuthWithAuthcid: (OFString*)authcid password: (OFString*)password hash: (Class)hash; { @@ -170,10 +161,12 @@ intmax_t iterCount; OFHash *hash; OFDataArray *ret, *authMessage, *tmpArray, *salt, *saltedPassword; OFString *tmpString, *sNonce; OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFEnumerator *enumerator; + OFString *comp; enum { GOT_SNONCE, GOT_SALT, GOT_ITERCOUNT } got = 0; hash = [[[hashType alloc] init] autorelease]; @@ -182,11 +175,13 @@ OFString *chal = [OFString stringWithCString: [challenge cArray] length: [challenge count] * [challenge itemSize]]; - for (OFString *comp in [chal componentsSeparatedByString: @","]) { + enumerator = + [[chal componentsSeparatedByString: @","] objectEnumerator]; + while ((comp = [enumerator nextObject]) != nil) { OFString *entry = [comp substringFromIndex: 2 toIndex: [comp length]]; if ([comp hasPrefix: @"r="]) { if (![entry hasPrefix: cNonce]) @@ -371,18 +366,18 @@ OFDataArray *k = [OFDataArray dataArrayWithItemSize: 1]; size_t i, kSize, blockSize = [hashType blockSize]; uint8_t *kCArray, *kI = NULL, *kO = NULL; OFHash *hash; - if (key.itemSize * key.count > blockSize) { + if ([key itemSize] * [key count] > blockSize) { hash = [[[hashType alloc] init] autorelease]; [hash updateWithBuffer: [key cArray] - ofSize: key.itemSize * key.count]; + ofSize: [key itemSize] * [key count]]; [k addNItems: [hashType digestSize] fromCArray: [hash digest]]; } else - [k addNItems: key.itemSize * key.count + [k addNItems: [key itemSize] * [key count] fromCArray: [key cArray]]; @try { kI = [self allocMemoryWithSize: blockSize * sizeof(uint8_t)]; memset(kI, HMAC_IPAD, blockSize * sizeof(uint8_t)); @@ -389,25 +384,25 @@ kO = [self allocMemoryWithSize: blockSize * sizeof(uint8_t)]; memset(kO, HMAC_OPAD, blockSize * sizeof(uint8_t)); kCArray = [k cArray]; - kSize = k.count; + kSize = [k count]; for (i = 0; i < kSize; i++) { kI[i] ^= kCArray[i]; kO[i] ^= kCArray[i]; } k = [OFDataArray dataArrayWithItemSize: 1]; [k addNItems: blockSize fromCArray: kI]; - [k addNItems: data.itemSize * data.count + [k addNItems: [data itemSize] * [data count] fromCArray: [data cArray]]; hash = [[[hashType alloc] init] autorelease]; [hash updateWithBuffer: [k cArray] - ofSize: k.count]; + ofSize: [k count]]; k = [OFDataArray dataArrayWithItemSize: 1]; [k addNItems: blockSize fromCArray: kO]; [k addNItems: [hashType digestSize] fromCArray: [hash digest]]; @@ -416,11 +411,11 @@ [self freeMemory: kO]; } hash = [[[hashType alloc] init] autorelease]; [hash updateWithBuffer: [k cArray] - ofSize: k.count]; + ofSize: [k count]]; [hash retain]; [pool release]; return [hash digest]; Index: src/XMPPStanza.h ================================================================== --- src/XMPPStanza.h +++ src/XMPPStanza.h @@ -28,24 +28,26 @@ /** * \brief A class describing an XMPP Stanza. */ @interface XMPPStanza: OFXMLElement { - /// The value of the stanza's from attribute XMPPJID *from; - /// The value of the stanza's to attribute XMPPJID *to; - /// The value of the stanza's type attribute OFString *type; - /// The value of the stanza's id attribute OFString *ID; } +#ifdef OF_HAVE_PROPERTIES +/// The value of the stanza's from attribute @property (copy) XMPPJID *from; +/// The value of the stanza's to attribute @property (copy) XMPPJID *to; +/// The value of the stanza's type attribute @property (copy) OFString *type; +/// The value of the stanza's id attribute @property (copy) OFString *ID; +#endif /** * Creates a new autoreleased XMPPStanza with the specified name. * * \param name The stanza's name (one of iq, message or presence) @@ -139,6 +141,15 @@ * * \param elem The element to base the XMPPStanza on * \return A initialized XMPPStanza */ - 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 Index: src/XMPPStanza.m ================================================================== --- src/XMPPStanza.m +++ src/XMPPStanza.m @@ -93,14 +93,14 @@ @throw [OFInvalidArgumentException newWithClass: isa selector: _cmd]; [self setDefaultNamespace: @"jabber:client"]; - if (type_) + if (type_ != nil) [self setType: type_]; - if (ID_) + if (ID_ != nil) [self setID: ID_]; } @catch (id e) { [self release]; @throw e; } @@ -108,30 +108,36 @@ return self; } - initWithElement: (OFXMLElement*)elem { - self = [super initWithName: elem.name - namespace: elem.namespace]; + self = [super initWithName: [elem name] + namespace: [elem namespace]]; @try { - for (OFXMLAttribute *attr in elem.attributes) { - if ([attr.name isEqual: @"from"]) + OFEnumerator *enumerator; + OFXMLAttribute *attr; + OFXMLElement *el; + + enumerator = [[elem attributes] objectEnumerator]; + while ((attr = [enumerator nextObject]) != nil) { + if ([[attr name] isEqual: @"from"]) [self setFrom: [XMPPJID JIDWithString: [attr stringValue]]]; - else if ([attr.name isEqual: @"to"]) + else if ([[attr name] isEqual: @"to"]) [self setTo: [XMPPJID JIDWithString: [attr stringValue]]]; - else if ([attr.name isEqual: @"type"]) + else if ([[attr name] isEqual: @"type"]) [self setType: [attr stringValue]]; - else if ([attr.name isEqual: @"id"]) + else if ([[attr name] isEqual: @"id"]) [self setID: [attr stringValue]]; else [self addAttribute: attr]; } - for (OFXMLElement *el in elem.children) + enumerator = [[elem children] objectEnumerator]; + while ((el = [enumerator nextObject]) != nil) [self addChild: el]; } @catch (id e) { [self release]; @throw e; } @@ -157,11 +163,11 @@ [self removeAttributeForName: @"from"]; if (from_ != nil) [self addAttributeWithName: @"from" - stringValue: from_.fullJID]; + stringValue: [from_ fullJID]]; } - (XMPPJID*)from { return [[from copy] autorelease]; @@ -175,11 +181,11 @@ [self removeAttributeForName: @"to"]; if (to_ != nil) [self addAttributeWithName: @"to" - stringValue: to_.fullJID]; + stringValue: [to_ fullJID]]; } - (XMPPJID*)to { return [[to copy] autorelease]; Index: tests/test.m ================================================================== --- tests/test.m +++ tests/test.m @@ -31,11 +31,14 @@ #import "XMPPIQ.h" #import "XMPPMessage.h" #import "XMPPPresence.h" #import "XMPPRoster.h" -@interface AppDelegate: OFObject +@interface AppDelegate: OFObject +#ifdef OF_HAVE_OPTIONAL_PROTOCOLS + +#endif @end OF_APPLICATION_DELEGATE(AppDelegate) @implementation AppDelegate @@ -46,57 +49,60 @@ XMPPPresence *pres = [XMPPPresence presence]; [pres addShow: @"chat"]; [pres addStatus: @"Bored"]; [pres addPriority: 20]; - pres.to = [XMPPJID JIDWithString: @"alice@example.com"]; - pres.from = [XMPPJID JIDWithString: @"bob@example.org"]; + [pres setTo: [XMPPJID JIDWithString: @"alice@example.com"]]; + [pres setFrom: [XMPPJID JIDWithString: @"bob@example.org"]]; assert([[pres stringValue] isEqual: @"chat" @"Bored20" @""]); XMPPMessage *msg = [XMPPMessage messageWithType: @"chat"]; [msg addBody: @"Hello everyone"]; - msg.to = [XMPPJID JIDWithString: @"jdev@conference.jabber.org"]; - msg.from = [XMPPJID JIDWithString: @"alice@example.com"]; + [msg setTo: [XMPPJID JIDWithString: @"jdev@conference.jabber.org"]]; + [msg setFrom: [XMPPJID JIDWithString: @"alice@example.com"]]; assert([[msg stringValue] isEqual: @"Hello everyone" @""]); XMPPIQ *iq = [XMPPIQ IQWithType: @"set" ID: @"128"]; - iq.to = [XMPPJID JIDWithString: @"juliet@capulet.lit"]; - iq.from = [XMPPJID JIDWithString: @"romeo@montague.lit"]; + [iq setTo: [XMPPJID JIDWithString: @"juliet@capulet.lit"]]; + [iq setFrom: [XMPPJID JIDWithString: @"romeo@montague.lit"]]; assert([[iq stringValue] isEqual: @""]); OFXMLElement *elem = [OFXMLElement elementWithName: @"iq"]; - [elem addAttributeWithName: @"from" stringValue: @"bob@localhost"]; - [elem addAttributeWithName: @"to" stringValue: @"alice@localhost"]; - [elem addAttributeWithName: @"type" stringValue: @"get"]; - [elem addAttributeWithName: @"id" stringValue: @"42"]; + [elem addAttributeWithName: @"from" + stringValue: @"bob@localhost"]; + [elem addAttributeWithName: @"to" + stringValue: @"alice@localhost"]; + [elem addAttributeWithName: @"type" + stringValue: @"get"]; + [elem addAttributeWithName: @"id" + stringValue: @"42"]; XMPPStanza *stanza = [XMPPStanza stanzaWithElement: elem]; assert([[elem stringValue] isEqual: [stanza stringValue]]); assert(([[OFString stringWithFormat: @"%@, %@, %@, %@", - stanza.from.fullJID, stanza.to.fullJID, stanza.type, stanza.ID] - isEqual: @"bob@localhost, alice@localhost, get, 42"])); + [[stanza from] fullJID], [[stanza to] fullJID], [stanza type], + [stanza ID]] isEqual: @"bob@localhost, alice@localhost, get, 42"])); 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!"); [OFApplication terminateWithStatus: 1]; } [conn setServer: [arguments objectAtIndex: 0]]; [conn setUsername: [arguments objectAtIndex: 1]]; [conn setPassword: [arguments objectAtIndex: 2]]; [conn setResource: @"ObjXMPP"]; - [conn setUseTLS: NO]; [conn connect]; @try { [conn handleConnection]; } @catch (id e) { @@ -118,15 +124,18 @@ } - (void)connectionDidReceiveRoster :(XMPPConnection*)conn { XMPPPresence *pres; + OFEnumerator *enumerator; + OFString *group; - of_log(@"Got roster! Groups: %@", conn.roster.groups); - for (OFString *group in conn.roster.groups) + of_log(@"Got roster! Groups: %@", [[conn roster] groups]); + enumerator = [[[conn roster] groups] objectEnumerator]; + while ((group = [enumerator nextObject]) != nil) of_log(@"Group %@: %@", group, - [conn.roster rosterItemsInGroup: group]); + [[conn roster] rosterItemsInGroup: group]); pres = [XMPPPresence presence]; [pres addPriority: 10]; [pres addStatus: @"ObjXMPP test is working!"];