Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Connection.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@
22FEB6691680818800BB778B /* KMSTranscriptEntry.m in Sources */ = {isa = PBXBuildFile; fileRef = 22FEB6671680818800BB778B /* KMSTranscriptEntry.m */; };
271059521671334500E20511 /* DAVKit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 27448C371458100D00EB086F /* DAVKit.framework */; };
27105953167143D800E20511 /* CURLHandle.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 220526E8165E96AA00A2BBC9 /* CURLHandle.framework */; };
273605911869A93600A32419 /* CK2Transcript.h in Headers */ = {isa = PBXBuildFile; fileRef = 2736058F1869A93600A32419 /* CK2Transcript.h */; settings = {ATTRIBUTES = (Public, ); }; };
273605921869A93600A32419 /* CK2Transcript.m in Sources */ = {isa = PBXBuildFile; fileRef = 273605901869A93600A32419 /* CK2Transcript.m */; };
27431CA01630381D00F6FB58 /* CK2FileProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 27431C9E1630381D00F6FB58 /* CK2FileProtocol.h */; };
27431CA11630381D00F6FB58 /* CK2FileProtocol.m in Sources */ = {isa = PBXBuildFile; fileRef = 27431C9F1630381D00F6FB58 /* CK2FileProtocol.m */; };
2743E8091622E47600019979 /* CK2FileManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 2743E8071622E47600019979 /* CK2FileManager.h */; settings = {ATTRIBUTES = (Public, ); }; };
Expand Down Expand Up @@ -340,6 +342,8 @@
22FEB6671680818800BB778B /* KMSTranscriptEntry.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KMSTranscriptEntry.m; sourceTree = "<group>"; };
22FEB6681680818800BB778B /* KMSTranscriptEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KMSTranscriptEntry.h; sourceTree = "<group>"; };
2702E4671459D0F50085BBC4 /* libssh2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libssh2.dylib; path = CurlHandle/SFTP/libssh2.dylib; sourceTree = "<group>"; };
2736058F1869A93600A32419 /* CK2Transcript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CK2Transcript.h; sourceTree = "<group>"; };
273605901869A93600A32419 /* CK2Transcript.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CK2Transcript.m; sourceTree = "<group>"; };
27431C9E1630381D00F6FB58 /* CK2FileProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CK2FileProtocol.h; sourceTree = "<group>"; };
27431C9F1630381D00F6FB58 /* CK2FileProtocol.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CK2FileProtocol.m; sourceTree = "<group>"; };
2743E8071622E47600019979 /* CK2FileManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CK2FileManager.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -529,6 +533,8 @@
278D8B78167FF35D00622468 /* CK2Authentication.m */,
27993E8216FCB30D008DC1B0 /* CK2FileOperation.h */,
27993E8316FCB30D008DC1B0 /* CK2FileOperation.m */,
2736058F1869A93600A32419 /* CK2Transcript.h */,
273605901869A93600A32419 /* CK2Transcript.m */,
);
name = Public;
path = ConnectionKit;
Expand Down Expand Up @@ -996,6 +1002,7 @@
79CFD89509F704F400172CDD /* ConnectionKit.h in Headers */,
7983DF8E0B0C0FAC00F5078E /* CKTransferRecord.h in Headers */,
798313C90B0D67E000F5078E /* CKTransferProgressCell.h in Headers */,
273605911869A93600A32419 /* CK2Transcript.h in Headers */,
27D03B421471787000FEA588 /* CKUploader.h in Headers */,
2743E8091622E47600019979 /* CK2FileManager.h in Headers */,
2790A8291627636E000C9D9F /* CK2Protocol.h in Headers */,
Expand Down Expand Up @@ -1429,6 +1436,7 @@
27F394F6162C162900944F43 /* CK2SFTPProtocol.m in Sources */,
27431CA11630381D00F6FB58 /* CK2FileProtocol.m in Sources */,
2288CD76165A99FC00F34E24 /* CK2WebDAVProtocol.m in Sources */,
273605921869A93600A32419 /* CK2Transcript.m in Sources */,
27A2072C1671634800D8284D /* CK2CURLBasedProtocol.m in Sources */,
278D8B7A167FF35D00622468 /* CK2Authentication.m in Sources */,
27993E8516FCB30D008DC1B0 /* CK2FileOperation.m in Sources */,
Expand Down
26 changes: 16 additions & 10 deletions ConnectionKit/CK2CURLBasedProtocol.m
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,19 @@ - (BOOL)shouldEnumerateFilename:(NSString *)name options:(NSDirectoryEnumeration

- (NSError*)processData:(NSMutableData*)data request:(NSURLRequest *)request url:(NSURL*)directoryURL path:(NSString*)directoryPath keys:(NSArray*)keys options:(NSDirectoryEnumerationOptions)mask
{
NSString *listing = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (listing)
{
[self.client protocol:self appendStringToTranscript:listing isCommand:NO];
}
else
{
listing = [[NSString alloc] initWithFormat:@"Unable to stringify listing: %@", data];
[self.client protocol:self appendStringToTranscript:listing isCommand:NO];
}
[listing release];


NSError* result = nil;

// Process the data to make a directory listing
Expand Down Expand Up @@ -685,26 +698,19 @@ - (void)transfer:(CURLTransfer *)transfer didCompleteWithError:(NSError *)error;

- (void)transfer:(CURLTransfer *)transfer didReceiveDebugInformation:(NSString *)string ofType:(curl_infotype)type;
{
CK2TranscriptType ckType;
switch (type)
{
case CURLINFO_HEADER_IN:
ckType = CK2TranscriptHeaderIn;
[self.client protocol:self appendStringToTranscript:string isCommand:NO];
break;

case CURLINFO_HEADER_OUT:
ckType = CK2TranscriptHeaderOut;
break;

case CURLINFO_TEXT:
ckType = CK2TranscriptText;
[self.client protocol:self appendStringToTranscript:string isCommand:YES];
break;

default:
return;
break;
}

[[self client] protocol:self appendString:string toTranscript:ckType];
}

#pragma mark Customization
Expand Down
15 changes: 0 additions & 15 deletions ConnectionKit/CK2FileManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -432,21 +432,6 @@ typedef NS_ENUM(NSInteger, CK2AuthChallengeDisposition) {
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToSend;


typedef NS_ENUM(NSUInteger, CK2TranscriptType) {
CK2TranscriptText,
CK2TranscriptHeaderIn,
CK2TranscriptHeaderOut,
}; // deliberately aligned with curl_infotype for convenience

/**
Reports received transcript info.

@param manager The file manager.
@param info The received transcript line(s). Should end in a newline character.
@param transcript The type of transcript received.
*/
- (void)fileManager:(CK2FileManager *)manager appendString:(NSString *)info toTranscript:(CK2TranscriptType)transcript;

/**
* Sent as the last message related to a specific operation. Error may be
* `nil`, which implies that no error occurred and this operation is finished.
Expand Down
9 changes: 3 additions & 6 deletions ConnectionKit/CK2FileOperation.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import "CK2FileOperation.h"
#import "CK2Protocol.h"
#import "CK2Transcript.h"

#import <AppKit/AppKit.h> // so icon handling can use NSImage and NSWorkspace for now

Expand Down Expand Up @@ -536,16 +537,12 @@ - (void)protocol:(CK2Protocol *)protocol didReceiveChallenge:(NSURLAuthenticatio
// TODO: Cache credentials per protection space
}

- (void)protocol:(CK2Protocol *)protocol appendString:(NSString *)info toTranscript:(CK2TranscriptType)transcript;
- (void)protocol:(CK2Protocol *)protocol appendStringToTranscript:(NSString *)info isCommand:(BOOL)isCommand;
{
NSAssert(protocol == _protocol, @"Message received from unexpected protocol: %@ (should be %@)", protocol, _protocol);


// Pass straight onto delegate and trust it not to take too long handling it
// We used to dispatch off onto one of the global queues, but that does have the nasty downside of messages sometimes arriving out-of-order or concurrently
[self tryToMessageDelegateSelector:@selector(fileManager:appendString:toTranscript:) usingBlock:^(id<CK2FileManagerDelegate> delegate) {
[delegate fileManager:self.fileManager appendString:info toTranscript:transcript];
}];
[[CK2Transcript sharedTranscript] addEntryWithText:info isCommand:isCommand];
}

- (void)protocol:(CK2Protocol *)protocol didDiscoverItemAtURL:(NSURL *)url;
Expand Down
1 change: 0 additions & 1 deletion ConnectionKit/CK2OpenPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,6 @@
- (void)panelSelectionDidChange:(CK2OpenPanel *)sender;

- (void)panel:(CK2OpenPanel *)sender didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(CK2AuthChallengeDisposition, NSURLCredential *))completionHandler;
- (void)panel:(CK2OpenPanel *)sender appendString:(NSString *)info toTranscript:(CK2TranscriptType)transcript;

- (void)panel:(CK2OpenPanel *)sender didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge __attribute((deprecated("implement -panel:didReceiveChallenge:completionHandler instead")));

Expand Down
12 changes: 0 additions & 12 deletions ConnectionKit/CK2OpenPanelController.m
Original file line number Diff line number Diff line change
Expand Up @@ -1215,16 +1215,4 @@ - (void)fileManager:(CK2FileManager *)manager operation:(CK2FileOperation *)oper
}
}

- (void)fileManager:(CK2FileManager *)manager appendString:(NSString *)info toTranscript:(CK2TranscriptType)transcript;
{
id <CK2OpenPanelDelegate> delegate;

delegate = [[self openPanel] delegate];

if ([delegate respondsToSelector:@selector(panel:appendString:toTranscript:)])
{
[delegate panel:[self openPanel] appendString:info toTranscript:transcript];
}
}

@end
2 changes: 1 addition & 1 deletion ConnectionKit/CK2Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@
*/
- (void)protocol:(CK2Protocol *)protocol didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(CK2AuthChallengeDisposition, NSURLCredential*))completionHandler;

- (void)protocol:(CK2Protocol *)protocol appendString:(NSString *)info toTranscript:(CK2TranscriptType)transcript;
- (void)protocol:(CK2Protocol *)protocol appendStringToTranscript:(NSString *)info isCommand:(BOOL)isCommand;


#pragma mark Operation-Specific
Expand Down
12 changes: 11 additions & 1 deletion ConnectionKit/CK2SFTPProtocol.m
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ + (NSString *)pathOfURLRelativeToHomeDirectory:(NSURL *)URL;

#pragma mark Operations

- (id)initForEnumeratingDirectoryWithRequest:(NSURLRequest *)request includingPropertiesForKeys:(NSArray *)keys options:(NSDirectoryEnumerationOptions)mask client:(id<CK2ProtocolClient>)client;
{
if (self = [super initForEnumeratingDirectoryWithRequest:request includingPropertiesForKeys:keys options:mask client:client])
{
NSString *path = [self.class pathOfURLRelativeToHomeDirectory:request.URL];
_transcriptMessage = [[NSString alloc] initWithFormat:@"Listing %@", path];
}
return self;
}

- (id)initForCreatingDirectoryWithRequest:(NSURLRequest *)request withIntermediateDirectories:(BOOL)createIntermediates openingAttributes:(NSDictionary *)attributes client:(id<CK2ProtocolClient>)client;
{
NSMutableURLRequest *mutableRequest = [request mutableCopy];
Expand Down Expand Up @@ -230,7 +240,7 @@ - (void)start;
// Note what we're up to
if (_transcriptMessage)
{
[self.client protocol:self appendString:_transcriptMessage toTranscript:CK2TranscriptHeaderOut];
[self.client protocol:self appendStringToTranscript:_transcriptMessage isCommand:YES];
[_transcriptMessage release]; _transcriptMessage = nil;
}

Expand Down
62 changes: 62 additions & 0 deletions ConnectionKit/CK2Transcript.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// CK2Transcript.h
// Connection
//
// Created by Mike on 24/12/2013.
//
//

#import <Foundation/Foundation.h>


/**
All safe to access from multiple threads. Be a bit wary that new entries might
arrive while removing existing ones though, if you have any UI code around it.
*/


@interface CK2TranscriptEntry : NSObject
{
@private
NSString *_text;
BOOL _isCommand;
}

@property(nonatomic, copy, readonly) NSString *text;
@property(nonatomic, readonly) BOOL isCommand;

@end


@interface CK2Transcript : NSObject
{
@private
NSMutableArray *_entries;
dispatch_queue_t _queue;
}

#pragma mark Shared Transcript
+ (CK2Transcript *)sharedTranscript;


#pragma mark Retrieving Entries
- (NSArray *)entries;
- (NSUInteger)countOfEntries;
- (CK2TranscriptEntry *)entryAtIndex:(NSUInteger)index;


#pragma mark Adding Entries
- (void)addEntryWithText:(NSString *)text isCommand:(BOOL)command;


#pragma mark Removing Entries
- (void)removeAllEntries;


@end


/**
Posted on whichever thread modified the transcript
*/
extern NSString * const CK2TranscriptChangedNotification;
134 changes: 134 additions & 0 deletions ConnectionKit/CK2Transcript.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
//
// CK2Transcript.m
// Connection
//
// Created by Mike on 24/12/2013.
//
//

#import "CK2Transcript.h"


@implementation CK2TranscriptEntry

- initWithText:(NSString *)text isCommand:(BOOL)isCommand;
{
if (self = [self init])
{
_text = [text copy];
_isCommand = isCommand;
}
return self;
}

- (void)dealloc;
{
[_text release];
[super dealloc];
}

@synthesize text = _text;
@synthesize isCommand = _isCommand;

@end


@implementation CK2Transcript

+ (CK2Transcript *)sharedTranscript;
{
static CK2Transcript *transcript;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
transcript = [[CK2Transcript alloc] init];
});
return transcript;
}

- init
{
if (self = [super init])
{
_queue = dispatch_queue_create("com.karelia.ConnectionKit.transcript", NULL);
}
return self;
}

- (void)dealloc;
{
[_entries release];
dispatch_release(_queue);

[super dealloc];
}

- (NSArray *)entries;
{
__block NSArray *result;
dispatch_sync(_queue, ^{
result = [_entries copy];
});
return [result autorelease];
}

- (NSUInteger)countOfEntries;
{
__block NSUInteger result;
dispatch_sync(_queue, ^{
result = _entries.count;
});
return result;
}

- (CK2TranscriptEntry *)entryAtIndex:(NSUInteger)index;
{
__block CK2TranscriptEntry *result;
dispatch_sync(_queue, ^{
result = [[_entries objectAtIndex:index] retain];
});
return [result autorelease];
}

- (void)addEntryWithText:(NSString *)text isCommand:(BOOL)command;
{
dispatch_async(_queue, ^{

if (!_entries)
{
_entries = [[NSMutableArray alloc] init];

// Start off with details of the host machine
NSBundle *bundle = [NSBundle mainBundle];
NSString *transcriptHeader = [NSString stringWithFormat:
@"%@ %@ (architecture unknown) Session Transcript [%@] (%@)",
[bundle objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey],
[bundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey],
[[NSProcessInfo processInfo] operatingSystemVersionString],
[NSDate date]];

CK2TranscriptEntry *entry = [[CK2TranscriptEntry alloc] initWithText:transcriptHeader isCommand:NO];
[_entries addObject:entry];
[entry release];
}

CK2TranscriptEntry *entry = [[CK2TranscriptEntry alloc] initWithText:text isCommand:command];
[_entries addObject:entry];
[entry release];
});

[[NSNotificationCenter defaultCenter] postNotificationName:CK2TranscriptChangedNotification object:self];
}

- (void)removeAllEntries;
{
dispatch_async(_queue, ^{
[_entries removeAllObjects];
});

[[NSNotificationCenter defaultCenter] postNotificationName:CK2TranscriptChangedNotification object:self];
}

@end


NSString * const CK2TranscriptChangedNotification = @"CK2TranscriptChanged";
Loading