mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-25 17:51:01 +00:00
Basic FTP store/retrieve implemented.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@13896 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
8af85e1863
commit
b694b824d6
1 changed files with 171 additions and 60 deletions
|
@ -313,7 +313,7 @@ NSString * const GSTelnetTextKey = @"GSTelnetTextKey";
|
||||||
}
|
}
|
||||||
if (i < len - 2)
|
if (i < len - 2)
|
||||||
{
|
{
|
||||||
NSLog(@"Command: %d %d", ptr[1], ptr[2]);
|
// NSLog(@"Command: %d %d", ptr[1], ptr[2]);
|
||||||
len -= 3;
|
len -= 3;
|
||||||
if (len - i > 0)
|
if (len - i > 0)
|
||||||
{
|
{
|
||||||
|
@ -337,7 +337,7 @@ NSLog(@"Command: %d %d", ptr[1], ptr[2]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NSLog(@"Command: %d", ptr[1]);
|
// NSLog(@"Command: %d", ptr[1]);
|
||||||
/*
|
/*
|
||||||
* Strip unimplemented escape sequence.
|
* Strip unimplemented escape sequence.
|
||||||
*/
|
*/
|
||||||
|
@ -425,7 +425,7 @@ NSLog(@"Command: %d", ptr[1]);
|
||||||
*/
|
*/
|
||||||
if (toWrite != nil)
|
if (toWrite != nil)
|
||||||
{
|
{
|
||||||
//NSLog(@"Write - '%@'", toWrite);
|
// NSLog(@"Write - '%@'", toWrite);
|
||||||
[remote writeInBackgroundAndNotify: toWrite];
|
[remote writeInBackgroundAndNotify: toWrite];
|
||||||
DESTROY(toWrite);
|
DESTROY(toWrite);
|
||||||
}
|
}
|
||||||
|
@ -519,12 +519,12 @@ static NSLock *urlLock = nil;
|
||||||
if ([[newUrl scheme] caseInsensitiveCompare: @"ftp"] == NSOrderedSame)
|
if ([[newUrl scheme] caseInsensitiveCompare: @"ftp"] == NSOrderedSame)
|
||||||
{
|
{
|
||||||
NSString *page = [newUrl absoluteString];
|
NSString *page = [newUrl absoluteString];
|
||||||
//NSLog(@"Lookup for handle for '%@'", page);
|
// NSLog(@"Lookup for handle for '%@'", page);
|
||||||
[urlLock lock];
|
[urlLock lock];
|
||||||
obj = [urlCache objectForKey: page];
|
obj = [urlCache objectForKey: page];
|
||||||
AUTORELEASE(RETAIN(obj));
|
AUTORELEASE(RETAIN(obj));
|
||||||
[urlLock unlock];
|
[urlLock unlock];
|
||||||
//NSLog(@"Found handle %@", obj);
|
// NSLog(@"Found handle %@", obj);
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
@ -563,7 +563,7 @@ static NSLock *urlLock = nil;
|
||||||
[urlLock lock];
|
[urlLock lock];
|
||||||
[urlCache setObject: self forKey: page];
|
[urlCache setObject: self forKey: page];
|
||||||
[urlLock unlock];
|
[urlLock unlock];
|
||||||
//NSLog(@"Cache handle %@ for '%@'", self, page);
|
// NSLog(@"Cache handle %@ for '%@'", self, page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
|
@ -583,60 +583,157 @@ static NSLock *urlLock = nil;
|
||||||
NSDictionary *info = [n userInfo];
|
NSDictionary *info = [n userInfo];
|
||||||
NSString *e = [info objectForKey: GSTelnetErrorKey];
|
NSString *e = [info objectForKey: GSTelnetErrorKey];
|
||||||
NSArray *text;
|
NSArray *text;
|
||||||
|
NSString *line;
|
||||||
|
|
||||||
if (e == nil)
|
if (e == nil)
|
||||||
|
{
|
||||||
|
text = [info objectForKey: GSTelnetTextKey];
|
||||||
|
line = [text objectAtIndex: 0];
|
||||||
|
// NSLog(@"Ctl: %@", text);
|
||||||
|
if (state == cConnect)
|
||||||
|
{
|
||||||
|
if ([line hasPrefix: @"2"] == YES)
|
||||||
|
{
|
||||||
|
NSString *user = [url user];
|
||||||
|
|
||||||
|
if (user == nil)
|
||||||
|
{
|
||||||
|
user = @"anonymous";
|
||||||
|
}
|
||||||
|
[cHandle putTelnetLine: [@"USER " stringByAppendingString: user]];
|
||||||
|
state = sentUser;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state == sentUser)
|
||||||
|
{
|
||||||
|
if ([line hasPrefix: @"230"] == YES) // No password required
|
||||||
|
{
|
||||||
|
[cHandle putTelnetLine: @"TYPE I"];
|
||||||
|
state = sentType;
|
||||||
|
}
|
||||||
|
else if ([line hasPrefix: @"331"] == YES)
|
||||||
|
{
|
||||||
|
NSString *pass = [url password];
|
||||||
|
|
||||||
|
if (pass == nil)
|
||||||
|
{
|
||||||
|
pass = [url user];
|
||||||
|
if (pass == nil)
|
||||||
|
{
|
||||||
|
pass = @"GNUstep@here";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass = @"";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[cHandle putTelnetLine: [@"PASS " stringByAppendingString: pass]];
|
||||||
|
state = sentPass;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state == sentPass)
|
||||||
|
{
|
||||||
|
if ([line hasPrefix: @"2"] == YES)
|
||||||
|
{
|
||||||
|
[cHandle putTelnetLine: @"TYPE I"];
|
||||||
|
state = sentType;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state == sentType)
|
||||||
|
{
|
||||||
|
if ([line hasPrefix: @"2"] == YES)
|
||||||
|
{
|
||||||
|
[cHandle putTelnetLine: @"PASV"];
|
||||||
|
state = sentPasv;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state == sentPasv)
|
||||||
|
{
|
||||||
|
if ([line hasPrefix: @"227"] == YES)
|
||||||
|
{
|
||||||
|
NSRange r = [line rangeOfString: @"("];
|
||||||
|
NSString *h = nil;
|
||||||
|
NSString *p = nil;
|
||||||
|
|
||||||
|
if (r.length > 0)
|
||||||
|
{
|
||||||
|
unsigned pos = NSMaxRange(r);
|
||||||
|
|
||||||
|
r = [line rangeOfString: @")"];
|
||||||
|
if (r.length > 0 && r.location > pos)
|
||||||
|
{
|
||||||
|
NSArray *a;
|
||||||
|
|
||||||
|
r = NSMakeRange(pos, r.location - pos);
|
||||||
|
line = [line substringWithRange: r];
|
||||||
|
a = [line componentsSeparatedByString: @","];
|
||||||
|
if ([a count] == 6)
|
||||||
|
{
|
||||||
|
h = [NSString stringWithFormat: @"%@.%@.%@.%@",
|
||||||
|
[a objectAtIndex: 0], [a objectAtIndex: 1],
|
||||||
|
[a objectAtIndex: 2], [a objectAtIndex: 3]];
|
||||||
|
p = [NSString stringWithFormat: @"%d",
|
||||||
|
[[a objectAtIndex: 4] intValue] * 256
|
||||||
|
+ [[a objectAtIndex: 5] intValue]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (h == nil)
|
||||||
|
{
|
||||||
|
e = @"Invalid host/port information for pasv command";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NSNotificationCenter *nc;
|
||||||
|
|
||||||
|
dHandle = [NSFileHandle
|
||||||
|
fileHandleAsClientInBackgroundAtAddress: h service: p
|
||||||
|
protocol: @"tcp"];
|
||||||
|
RETAIN(dHandle);
|
||||||
|
nc = [NSNotificationCenter defaultCenter];
|
||||||
|
[nc addObserver: self
|
||||||
|
selector: @selector(_data:)
|
||||||
|
name: GSFileHandleConnectCompletionNotification
|
||||||
|
object: dHandle];
|
||||||
|
state = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = line;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (state == data)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e = @"Message in unknown state";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (e != nil)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Tell superclass that the load failed - let it do housekeeping.
|
* Tell superclass that the load failed - let it do housekeeping.
|
||||||
*/
|
*/
|
||||||
[self endLoadInBackground];
|
[self endLoadInBackground];
|
||||||
[self backgroundLoadDidFailWithReason: e];
|
[self backgroundLoadDidFailWithReason: e];
|
||||||
return;
|
|
||||||
}
|
|
||||||
text = [info objectForKey: GSTelnetTextKey];
|
|
||||||
NSLog(@"Ctl: %@", text);
|
|
||||||
if (state == cConnect)
|
|
||||||
{
|
|
||||||
NSString *user = [url user];
|
|
||||||
|
|
||||||
if (user == nil)
|
|
||||||
{
|
|
||||||
user = @"anonymous";
|
|
||||||
}
|
|
||||||
[cHandle putTelnetLine: [@"USER " stringByAppendingString: user]];
|
|
||||||
state = sentUser;
|
|
||||||
}
|
|
||||||
else if (state == sentUser)
|
|
||||||
{
|
|
||||||
NSString *pass = [url password];
|
|
||||||
|
|
||||||
if (pass == nil)
|
|
||||||
{
|
|
||||||
pass = [url user];
|
|
||||||
if (pass == nil)
|
|
||||||
{
|
|
||||||
pass = @"GNUstep@here";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pass = @"";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[cHandle putTelnetLine: [@"PASS " stringByAppendingString: pass]];
|
|
||||||
state = sentPass;
|
|
||||||
}
|
|
||||||
else if (state == sentPass)
|
|
||||||
{
|
|
||||||
[cHandle putTelnetLine: @"TYPE I"];
|
|
||||||
state = sentType;
|
|
||||||
}
|
|
||||||
else if (state == sentType)
|
|
||||||
{
|
|
||||||
[cHandle putTelnetLine: @"PASV"];
|
|
||||||
state = sentPasv;
|
|
||||||
}
|
|
||||||
else if (state == sentPasv)
|
|
||||||
{
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -647,6 +744,7 @@ NSLog(@"Ctl: %@", text);
|
||||||
NSDictionary *info = [n userInfo];
|
NSDictionary *info = [n userInfo];
|
||||||
NSString *e = [info objectForKey: GSFileHandleNotificationError];
|
NSString *e = [info objectForKey: GSFileHandleNotificationError];
|
||||||
|
|
||||||
|
// NSLog(@"_data: %@", n);
|
||||||
[nc removeObserver: self name: name object: dHandle];
|
[nc removeObserver: self name: name object: dHandle];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -659,6 +757,7 @@ NSLog(@"Ctl: %@", text);
|
||||||
NSLog(@"Unable to connect to %@:%@ via socket",
|
NSLog(@"Unable to connect to %@:%@ via socket",
|
||||||
[dHandle socketAddress], [dHandle socketService]);
|
[dHandle socketAddress], [dHandle socketService]);
|
||||||
}
|
}
|
||||||
|
// NSLog(@"Fail - %@", e);
|
||||||
/*
|
/*
|
||||||
* Tell superclass that the load failed - let it do housekeeping.
|
* Tell superclass that the load failed - let it do housekeeping.
|
||||||
*/
|
*/
|
||||||
|
@ -670,6 +769,8 @@ NSLog(@"Ctl: %@", text);
|
||||||
{
|
{
|
||||||
if (wData == nil)
|
if (wData == nil)
|
||||||
{
|
{
|
||||||
|
[cHandle putTelnetLine:
|
||||||
|
[NSString stringWithFormat: @"RETR %@", [url path]]];
|
||||||
[nc addObserver: self
|
[nc addObserver: self
|
||||||
selector: @selector(_data:)
|
selector: @selector(_data:)
|
||||||
name: NSFileHandleReadCompletionNotification
|
name: NSFileHandleReadCompletionNotification
|
||||||
|
@ -678,6 +779,8 @@ NSLog(@"Ctl: %@", text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
[cHandle putTelnetLine:
|
||||||
|
[NSString stringWithFormat: @"STOR %@", [url path]]];
|
||||||
[nc addObserver: self
|
[nc addObserver: self
|
||||||
selector: @selector(_data:)
|
selector: @selector(_data:)
|
||||||
name: GSFileHandleWriteCompletionNotification
|
name: GSFileHandleWriteCompletionNotification
|
||||||
|
@ -703,8 +806,22 @@ NSLog(@"Ctl: %@", text);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[self didLoadBytes: nil loadComplete: YES];
|
NSNotificationCenter *nc;
|
||||||
[self endLoadInBackground];
|
|
||||||
|
nc = [NSNotificationCenter defaultCenter];
|
||||||
|
if (dHandle != nil)
|
||||||
|
{
|
||||||
|
[nc removeObserver: self name: nil object: dHandle];
|
||||||
|
[dHandle closeFile];
|
||||||
|
DESTROY(dHandle);
|
||||||
|
}
|
||||||
|
[nc removeObserver: self
|
||||||
|
name: GSTelnetNotification
|
||||||
|
object: cHandle];
|
||||||
|
DESTROY(cHandle);
|
||||||
|
state = idle;
|
||||||
|
|
||||||
|
[self didLoadBytes: d loadComplete: YES];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -755,12 +872,6 @@ NSLog(@"Ctl: %@", text);
|
||||||
}
|
}
|
||||||
|
|
||||||
[self beginLoadInBackground];
|
[self beginLoadInBackground];
|
||||||
if (dHandle != nil)
|
|
||||||
{
|
|
||||||
[dHandle closeFile];
|
|
||||||
DESTROY(dHandle);
|
|
||||||
}
|
|
||||||
|
|
||||||
host = [url host];
|
host = [url host];
|
||||||
p = [url port];
|
p = [url port];
|
||||||
if (p != nil)
|
if (p != nil)
|
||||||
|
|
Loading…
Reference in a new issue