• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
NSTask / NSPipe / FTP
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

NSTask / NSPipe / FTP


  • Subject: NSTask / NSPipe / FTP
  • From: John Pannell <email@hidden>
  • Date: Fri, 21 Sep 2001 16:02:22 -0600

Hi there-

I'm working on a program that wraps the command line FTP program in a
GUI, using NSTask, NSPipe, etc. I had success doing this with ping,
netstat, and a few other programs, but FTP is giving me fits - It
doesn't seem to send the command line output for the interactive part of
FTP to either stdout or stderr. I'm not sure where it goes, but I can't
seem to get anything back out of the pipes once the task kicks off.
Here's a few parts of the code (this is lengthy, sorry):

This starts the FTP session when the user clicks a button in the UI...

- (void)start
{
// initialize arguments for CLI
NSMutableArray *theArguments = [NSMutableArray
arrayWithArray:[NSArray arrayWithObjects:@"-v",@"-d",
@"www.positivespinmedia.com", nil]];

// open a pipe for ping to send its output to
NSPipe *thePipe = [NSPipe pipe];

// open another pipe for the errors
NSPipe *errorPipe = [NSPipe pipe];

// open another pipe for the input (what I have to say to FTP)
NSPipe *inputPipe = [NSPipe pipe];

// make sure there isn't FTP task currently running
NSAssert( !theTask, @"Task already exists" );

// create the subprocess
theTask = [[NSTask alloc] init];

// set the subprocess to start a session
[theTask setLaunchPath:@"/usr/bin/ftp"];

[theTask setArguments:theArguments];

// point the output of the ping session to the pipe,
// and the error to the other pipe
[theTask setStandardOutput:thePipe];
[theTask setStandardError:errorPipe];
[theTask setStandardInput:inputPipe];

// launch ftp
[theTask launch];

// create file handles for the input, output, and error of the
session
theOutput = [[thePipe fileHandleForReading] retain];
theError = [[errorPipe fileHandleForReading] retain];
theInput = [[inputPipe fileHandleForWriting] retain];

// register myself as an observer for this pipe
// updates trigger output method
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(output:) name:NSFileHandleReadCompletionNotification
object:theOutput];

// register myself as an observer for the error pipe
// updates trigger output method
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(output:) name:NSFileHandleReadCompletionNotification
object:theError];

// put it in the background - don't hold UI hostage
[theOutput readInBackgroundAndNotify];
[theError readInBackgroundAndNotify];

// make the UI signal user - session in progress
// clean out the text field
[[theResponse textStorage] setAttributedString:[[[NSAttributedString
alloc] init] autorelease]];

// change button to stop
[connectButton setTitle:@"Stop"];

// this thing should be purring like a kitten
}

Once I click the button, I see (in a text field in the UI):

Connected to positivespinmedia.com.
220 ProFTPD 1.2.2rc1 Server (FTP) [positivespinmedia.com]

So... it does start the task and connect to the server properly. But
what I want to see is:

Connected to positivespinmedia.com.
220 ProFTPD 1.2.2rc1 Server (FTP) [positivespinmedia.com]
Name (www.positivespinmedia.com:johnp):

I'm missing that last line in my interface, despite the fact that it
does show up when running FTP from the command line. I would then enter
my username, password, and be on my way to a nice FTP session - thus my
wondering where FTP could be sending that last line to: it doesn't seem
to be showing up at stdout or stderr.

Here's the output method... as you can see, I am "resetting" the
notification mechanism for the filehandle...

- (void)output:(NSNotification *)aNotification
{
// get the data from the notification
NSData *theData = [[aNotification userInfo]
objectForKey:NSFileHandleNotificationDataItem];

NSString *theString = [[[NSString alloc] initWithData:theData
encoding:NSNEXTSTEPStringEncoding] autorelease];

// reset the notifier
[theOutput readInBackgroundAndNotify];

NSLog(@"output pipe triggered");

// put the stuff in the text field
[[theResponse textStorage]
appendAttributedString:[[[NSAttributedString alloc]
initWithString:theString attributes:[NSDictionary
dictionaryWithObjectsAndKeys:[NSFont userFontOfSize:12],
NSFontAttributeName, nil]] autorelease]];

// move the scroll if needed
[theResponse scrollRangeToVisible:NSMakeRange( [[theResponse
textStorage] length], 0 )];
}

Does anyone know where FTP is sending its output/error to, and how I can
pick it up? Or have any other ideas what might be wrong?

I appreciate any help anyone can offer!

John P.


  • Prev by Date: Re: static typing (Learning Cocoa Chapter 13)
  • Next by Date: Re: static typing (Learning Cocoa Chapter 13)
  • Previous by thread: XML-RPC or SOAP ?
  • Next by thread: Free database engine?
  • Index(es):
    • Date
    • Thread