Plugins/Bonjour/libezv/Private Classes/AWEzvContactManager.m
author Evan Schoenberg
Sat Oct 31 12:31:33 2009 -0500 (2009-10-31)
changeset 2830 c770142607e4
parent 1572 b2faf3d4b0d4
child 2833 f1b225d54546
permissions -rw-r--r--
If Bonjour disconnects but the user opens a contact window in the moment before the contact disappears from the list, it wass possible to attempt to open with a nil avInstanceName. Furthermore, if Bonjour disconnects, attempting to send a message to a still-open Bonjour chat could try to reference avInstanceName which would previously be nil after disconnect.

There's no reason to be so aggressive with having avInstanceName only be set while logged in; it's a single string, and it doesn't generally change. We'll create it in init and destroy it in dealloc for AWEzvContactManager.

Fixes #11799 fully.
David@0
     1
/*
David@0
     2
 * Project:     Libezv
David@0
     3
 * File:        AWEzvContactManager.m
David@0
     4
 *
David@0
     5
 * Version:     1.0
David@0
     6
 * Author:      Andrew Wellington <proton[at]wiretapped.net>
David@0
     7
 *
David@0
     8
 * License:
David@0
     9
 * Copyright (C) 2004-2005 Andrew Wellington.
David@0
    10
 * All rights reserved.
David@0
    11
 * 
David@0
    12
 * Redistribution and use in source and binary forms, with or without
David@0
    13
 * modification, are permitted provided that the following conditions are met:
David@0
    14
 * 
David@0
    15
 * 1. Redistributions of source code must retain the above copyright notice,
David@0
    16
 * this list of conditions and the following disclaimer.
David@0
    17
 * 2. Redistributions in binary form must reproduce the above copyright notice,
David@0
    18
 * this list of conditions and the following disclaimer in the documentation
David@0
    19
 * and/or other materials provided with the distribution.
David@0
    20
 * 
David@0
    21
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
David@0
    22
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
David@0
    23
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
David@0
    24
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
David@0
    25
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
David@0
    26
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
David@0
    27
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
David@0
    28
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
David@0
    29
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
David@0
    30
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
David@0
    31
 */
David@0
    32
David@0
    33
#import "AWEzvContactManager.h"
David@0
    34
#import "AWEzvContactPrivate.h"
David@559
    35
#import "AWEzvXMLStream.h"
David@0
    36
David@0
    37
@implementation AWEzvContactManager
David@0
    38
David@0
    39
- (id)initWithClient:(AWEzv *)newClient 
David@0
    40
{
David@0
    41
    if ((self = [super init])) {
David@0
    42
		contacts = [[NSMutableDictionary alloc] init];
David@0
    43
		client = newClient;
David@0
    44
		isConnected = NO;
Evan@2830
    45
		
Evan@2830
    46
		/* find username and computer name */
Evan@2830
    47
		CFStringRef consoleUser = SCDynamicStoreCopyConsoleUser(NULL, NULL, NULL);
Evan@2830
    48
		CFStringRef computerName = SCDynamicStoreCopyLocalHostName(NULL);
Evan@2830
    49
		if (!computerName) {
Evan@2830
    50
			/* computerName can return NULL if the computer name is not set or an error occurs */
Evan@2830
    51
			CFUUIDRef	uuid;
Evan@2830
    52
			
Evan@2830
    53
			uuid = CFUUIDCreate(NULL);
Evan@2830
    54
			computerName = CFUUIDCreateString(NULL, uuid);
Evan@2830
    55
			CFRelease(uuid);		
Evan@2830
    56
		}
Evan@2830
    57
		avInstanceName = [[NSString alloc] initWithFormat:@"%@@%@",
Evan@2830
    58
						  (consoleUser ? (NSString *)consoleUser : @""),
Evan@2830
    59
						  (computerName ? (NSString *)computerName : @"")];
Evan@2830
    60
		if (consoleUser) CFRelease(consoleUser);
Evan@2830
    61
		if (computerName) CFRelease(computerName);		
David@0
    62
	}
David@0
    63
David@0
    64
    return self;
David@0
    65
}
David@0
    66
David@0
    67
- (AWEzvContact *)contactForIdentifier:(NSString *)uniqueID {
David@1478
    68
    AWEzvContact *contact = [contacts objectForKey:uniqueID];
David@0
    69
    /* try a case insensitive search if not found */
David@1478
    70
    if (!contact) {
David@1572
    71
		for (contact in [contacts allValues]) {
David@1478
    72
			if ([contact.uniqueID caseInsensitiveCompare:uniqueID] == NSOrderedSame)
David@1478
    73
				break;
David@1478
    74
		}
David@0
    75
	}
David@0
    76
    return contact;
David@0
    77
}
David@0
    78
David@1478
    79
- (void)closeConnections {
David@1572
    80
	for (AWEzvContact *contact in [contacts allValues]) {
David@1478
    81
		if (contact.stream)
David@1478
    82
			[contact.stream endConnection];
David@0
    83
	}
David@0
    84
}
David@0
    85
David@1478
    86
@synthesize client;
David@0
    87
David@0
    88
- (void)dealloc {
David@0
    89
	/* AWEzvContactManagerListener adds an observer; remove it */
David@0
    90
	[[NSNotificationCenter defaultCenter] removeObserver:self];
Evan@2830
    91
Evan@2830
    92
	[userAnnounceData release]; userAnnounceData = nil;
Evan@2830
    93
	[avInstanceName release]; avInstanceName = nil;
David@0
    94
David@0
    95
	[super dealloc];
David@0
    96
}
David@0
    97
David@566
    98
- (NSString *)myInstanceName {
David@566
    99
	NSAssert(NO, @"AWEzvContactManager -myInstanceName: This should not be reached");
David@567
   100
	return nil;
David@566
   101
}
David@566
   102
David@0
   103
@end