This is GateDocEditor.m in view mode; [Download] [Up]
//*****************************************************************************
//
// GateDocEditor.m.
//
// Create, edit and link using a Gate doc
//
// by Felipe A. Rodriguez
//
// This code is supplied "as is" the author makes no warranty as to its
// suitability for any purpose. This code is free and may be distributed
// in accordance with the terms of the:
//
// GNU GENERAL PUBLIC LICENSE
// Version 2, June 1991
// copyright (C) 1989, 1991 Free Software Foundation, Inc.
// 675 Mass Ave, Cambridge, MA 02139, USA
//
//*****************************************************************************
#import <dbkit/DBImageView.h>
#import "GKdefs.h"
#import "GateDocEditor.h"
#import "options.h"
#import "Coordinator.h"
#import "CommandScroll.h"
#import "DLDelegate.h"
#import "OptionsEditor.h"
#import "EParse.h"
// filter for Gate doc path's
const char *filter[2] = {"Gate", NULL};
@implementation GateDocEditor
//*****************************************************************************
//
// create new Gate Document with default files inside.
//
//*****************************************************************************
- newDoc:sender
{
theSavePanel = [SavePanel new];
[theSavePanel setTitle:[[NXApp delegate] localString:"New"]];
[theSavePanel setRequiredFileType:filter[0]]; // append ext if not supplied
if(NX_OKTAG == [theSavePanel runModalForDirectory:
NXGetDefaultValue([NXApp appName], LIBPATH)
file:NULL])
{ // create .Gate doc wrapper
mkdir([theSavePanel filename], (_S_IRUSR | _S_IWUSR | _S_IXUSR));
chown([theSavePanel filename], getuid(), getgid());
[self addDefaultFiles:[theSavePanel filename]];
// [[NXApp delegate] updateBrowser:self];
[self editGateDoc:[theSavePanel filename]];
}
return self;
}
//*****************************************************************************
//
// execute pppd with info from .Gate open document
//
//*****************************************************************************
- linkDoc:sender
{
if(![[[NXApp mainMenu] findCellWithTag:1] isEnabled])
{ // is disconnect menu item enabled?
[[sender window] close];
[[NXApp delegate] setPhase:0];
[[[NXApp delegate] commandView] appendString:
[[NXApp delegate] localString:"Killing ppp daemon\n"]];
[[NXApp delegate] killDaemon];
[[NXApp delegate]linkWithFile:NXGetDefaultValue([NXApp appName],EDOC)];
}
else
[[NXApp delegate] showAlert:"A ppp session is already active."];
return self;
}
//*****************************************************************************
//
// open an existing .Gate document
//
//*****************************************************************************
- openDoc:sender
{
theOpenPanel = [OpenPanel new];
[theOpenPanel setTitle:[[NXApp delegate] localString:"Open"]];
if(NX_OKTAG == [theOpenPanel runModalForDirectory:
NXGetDefaultValue([NXApp appName], LIBPATH)
file:NULL
types:filter])
[self editGateDoc:[theOpenPanel filename]];
return self;
}
//*****************************************************************************
//
// edit an existing .Gate document using built in editor
//
//*****************************************************************************
- editGateDoc:(const char *)aGateDoc
{
id image;
// save doc path to ddb
if(!NXWriteDefault([NXApp appName], EDOC, aGateDoc))
[[NXApp delegate] showAlert:"ddbWriteError"];
if([[NXApp delegate] readable:[self pppupPath]]) // is readable
{
if(!theOptionsEditor) // open edit doc window
[NXApp loadNibSection:"EditDoc.nib" owner:self withNames:NO];
[docPath setStringValue:aGateDoc]; // display name
[docName setStringValue:
[[[NXApp delegate] docLDelegate] extractName:aGateDoc]];
[theOptionsEditor parseOptionsFile:[self optionsPath]];
strcpy(Path, aGateDoc); // display doc icon
strcat(Path, IMAGE); // in well
[[GDEImageView setEditable:NO] setStyle:DB_ImageNoFrame];
if(!(image = [[NXImage alloc] initFromFile:Path])) // if imge
image = [NXImage findImageNamed: ".dir"]; // else use blank
[GDEImageView setImage:image];
// [[theOptionsEditor editorWindow] center];
// [[theOptionsEditor editorWindow] makeKeyAndOrderFront:self];
if(!Parser) // parse options for login name
Parser = [[EParse alloc] init];
/// if(loginName = [self optionsLoginName:[self optionsPath]])
{
/// [loginNameField setStringValue:loginName];
/// [self beginEditing];
}
/// else
/// [[NXApp delegate] showAlert:"Login name missing from options file."];
[self continueEditing]; /// temp
}
return self;
}
//*****************************************************************************
//
// begin the editing process
//
//*****************************************************************************
- beginEditing;
{
char *passW = NULL;
if(passW = [self secretOwnedBySelf])
{ // found entry owned by user
[passwordField setStringValue:passW];
[self continueEditing];
free(passW);
}
else // if a pre-existing entry owned by another the user
{ // must supply the old password before editing is allowed
if(passW = [self secretOwnedByOther])
{
if([self comparePasswords:passW])
[self continueEditing];
free(passW);
}
else
{ // add new entry to secrets file
if(NX_ALERTDEFAULT == NXRunAlertPanel(0, [[NXApp delegate]
localString:"Login Name not found in secrets file. Add it?"],
[[[NXApp delegate] stringTable] valueForStringKey:"Yes"],
[[[NXApp delegate] stringTable] valueForStringKey:"No"], NULL))
{
[self addToSecretsFile:
NXGetDefaultValue([NXApp appName], "secrets")];
[self continueEditing];
}
}
}
return self;
}
//*****************************************************************************
//
// continue the editing process
//
//*****************************************************************************
- continueEditing
{
static char del2[] = {" \"\t\r\n"};
static char del3[] = {"\". =:|\t\r\nT"};
char *lName = NULL;
[[Parser setKey1:"A"] setKey2:"D"]; // set search pattern
[[Parser setDelim1:del3] setDelim2:del2]; // and delimiters
if(lName = [Parser parseFile:[self pppupPath]])
{
[phoneField setStringValue:lName];
free(lName);
}
else
[[NXApp delegate]showAlert:"Phone number not found in pppup file"];
[editPanel center];
[editPanel display];
[editPanel makeKeyAndOrderFront:self];
return self;
}
//*****************************************************************************
//
// add login name and password to selected secrets file
//
//*****************************************************************************
- addToSecretsFile:(const char *)pathOfSecretsFile
{
NXStream *inFStream;
char buf[2] = {" \0"};
char * gLogin;
if((inFStream = NXMapFile(pathOfSecretsFile, NX_READWRITE)) == NULL)
{
strcpy(Path, "Could not open file: ");
strcat(Path, pathOfSecretsFile);
NXRunAlertPanel(0, Path, 0, 0, 0);
}
else
{
NXSeek(inFStream, 0, NX_FROMEND); // go to end of file
strncpy(Path, "\"", MAXPATHLEN); // concat dummy entry
strncat(Path, [loginNameField stringValue],
MAXPATHLEN - strlen(rBuf));
strncat(Path, "\" * \"", MAXPATHLEN - strlen(rBuf));
strncat(Path, "myPassword", MAXPATHLEN - strlen(rBuf));
strncat(Path, "\"", MAXPATHLEN - strlen(rBuf));
if(gLogin = getlogin())
strncpy(gBuf, gLogin, MAXPATHLEN);
else
sprintf(gBuf, "%d", (int)getuid());
gLogin = gBuf;
if(NXRead(inFStream, buf, 1) != 1) // print to a new line by testing
{ // last char in file
if(buf[0] == '\n' || buf[0] == '\r') // insert at cur ln
NXPrintf(inFStream, "# owner:%s\r\n%s\r\n", gLogin, Path);
else // insert at new ln
NXPrintf(inFStream,"\r\n# owner:%s\r\n%s\r\n", gLogin, Path);
}
else
NXRunAlertPanel(0, "Error reading from memory stream.", 0, 0, 0);
NXFlush(inFStream);
if(NXSaveToFile(inFStream, pathOfSecretsFile) == -1)
NXRunAlertPanel(0, "Error saving memory stream.", 0, 0, 0);
else
NXCloseMemory(inFStream, NX_FREEBUFFER);
}
return self;
}
//*****************************************************************************
//
// target action of Gate Doc editor text field editing by user
//
//*****************************************************************************
- editField:sender
{
const char *aPath;
static char del2[] = {" \"\t\r\n"};
static char del3[] = {"\". =:|\t\r\nT"};
switch([sender selectedRow])
{
case 0: // phone number changed
if([[NXApp delegate] readable:(aPath = [self pppupPath])])
{
[[Parser setKey1:"A"] setKey2:"D"]; // set search pattern
[[Parser setDelim1:del3] setDelim2:del2]; // and delimiters
strncpy(rBuf, "ATDT", MAXPATHLEN);
strncat(rBuf, [[sender findCellWithTag:
[sender selectedRow]] stringValue],
MAXPATHLEN - strlen(rBuf));
[Parser replaceWith:rBuf];
if(![Parser editFile:aPath])
NXRunAlertPanel(0, "Error editing file", 0, 0, 0);
}
break;
case 1: // login name changed
[self loginNameChanged];
break;
case 2: // password changed
if([[NXApp delegate] readable:(aPath = [self optionsPath])])
[self editSecretsForName:[loginNameField stringValue]];
break;
default:
break;
}
return self;
}
//*****************************************************************************
//
// loginNameChanged
//
//*****************************************************************************
- loginNameChanged
{
char *passW = NULL;
if(passW = [self secretOwnedBySelf])
{ // found entry owned by user
[passwordField setStringValue:passW];
[self editFilesForName:[loginNameField stringValue]];
free(passW);
}
else // if a pre-existing entry owned by another, the user
{ // must supply the old password before editing is allowed
if(passW = [self secretOwnedByOther])
{
if([self comparePasswords:passW])
[self editFilesForName:[loginNameField stringValue]];
free(passW);
}
else // no pre-existing entry so just change current
[self editFilesForName:[self optionsLoginName:[self optionsPath]]];
}
return self;
}
//*****************************************************************************
//
// edit options and secrets
//
//*****************************************************************************
- editFilesForName:(const char *)aLoginName
{
static char del1[] = {"\". =:|\t\r\n"}, del2[] = {" \"\t\r\n"};
[self editSecretsForName:aLoginName];
// replace login name in options file
[[Parser setKey1:"user"] setKey2:""];
[[Parser setDelim1:del1] setDelim2:del2];
strncpy(rBuf, "name \"", MAXPATHLEN);
strncat(rBuf, [loginNameField stringValue], MAXPATHLEN - strlen(rBuf));
strncat(rBuf, "\"", MAXPATHLEN - strlen(rBuf));
[Parser replaceWith:rBuf];
if(![Parser editFile:[self optionsPath]])
NXRunAlertPanel(0, "Error editing file", 0, 0, 0);
return self;
}
//*****************************************************************************
//
// edit secrets
//
//*****************************************************************************
- editSecretsForName:(const char *)aLoginName
{ // replace login name, password in secrets file
[self setParserForOtherOwner:aLoginName];
[Parser replaceWith:[self concatSecret:[passwordField stringValue]]];
if(![Parser editFile:NXGetDefaultValue([NXApp appName], "secrets")])
NXRunAlertPanel(0, "Error editing secrets file.", 0, 0, 0);
return self;
}
//*****************************************************************************
//
// return concat'd secret
//
//*****************************************************************************
- (const char *)concatSecret:(const char *)aString
{
strncpy(rBuf, "\"", MAXPATHLEN);
strncat(rBuf, [loginNameField stringValue],
MAXPATHLEN - strlen(rBuf));
strncat(rBuf, "\" * \"", MAXPATHLEN - strlen(rBuf));
strncat(rBuf, aString, MAXPATHLEN - strlen(rBuf));
strncat(rBuf, "\"", MAXPATHLEN - strlen(rBuf));
return rBuf;
}
//*****************************************************************************
//
// return YES if new password matches user supplied password
//
//*****************************************************************************
- (BOOL)comparePasswords:(const char *)newPass
{
BOOL ret = NO;
if(NX_ALERTDEFAULT == NXRunAlertPanel(0, [[NXApp delegate] localString:
"An entry owned by another user already exists within the secrets file for the Login Name specified. Edit the existing entry?"],
[[[NXApp delegate] stringTable] valueForStringKey:"Yes"],
[[[NXApp delegate] stringTable] valueForStringKey:"No"], NULL))
{
[oldPassPanel makeKeyAndOrderFront:self];
// begin modal loop
[NXApp beginModalSession:&session for:oldPassPanel];
while([NXApp runModalSession:&session] == NX_RUNCONTINUES);
// end modal loop
[NXApp endModalSession:&session];
[oldPassPanel orderOut:self];
// test for correct old password before
// allowing the user to edit a pre-existing
// entry which he does not own
if(strcmp([oldPassField stringValue], newPass) == 0)
{
ret = YES;
[passwordField setStringValue:[oldPassField stringValue]];
[oldPassField setStringValue:" "];
free(loginName); // store current login name
loginName = NXCopyStringBuffer([loginNameField stringValue]);
}
else // incorrect password was entered, so revert to last login
{ // name and post warning
[[NXApp delegate] showAlert:"Incorrect Password."];
[loginNameField setStringValue:loginName];
}
}
return ret;
}
//*****************************************************************************
//
// sets the parser for detection of entries owned by self
//
//*****************************************************************************
- setParserForOwner:(const char *)aString
{
static char del2[] = {" \"\t\r\n"};
char * gLogin;
// check for an entry in secrets with login
// name which is owned by user
strncpy(gBuf, "owner:", MAXPATHLEN);
if(gLogin = getlogin())
strncat(gBuf, gLogin, MAXPATHLEN - strlen(gBuf));
else
{
sprintf(rBuf, "%d", (int)getuid());
strncat(gBuf, rBuf, MAXPATHLEN - strlen(gBuf));
}
[[Parser setKey1:gBuf] setKey2:aString];
[[Parser setDelim1:del2] setDelim2:del2]; // and delimiters
[Parser setEscape:1]; // words to escape
return self;
}
//*****************************************************************************
//
// sets the parser for detection of entries owned by others
//
//*****************************************************************************
- setParserForOtherOwner:(const char *)aString
{
static char del1[] = {"\". =:|\t\r\n"}, del2[] = {"\"\t\r\n"};
// check for an entry in secrets with login
// name and which is NOT owned by user
[[Parser setKey1:aString] setKey2:"*"];
[[Parser setDelim1:del1] setDelim2:del2]; // and delimiters
[Parser setEscape:0]; // words to escape
return self;
}
//*****************************************************************************
//
// return login name specified in options file
//
//*****************************************************************************
- (char *)optionsLoginName:(const char *)aPath
{
static char del1[] = {"\". =:|\t\r\n"}, del2[] = {" \"\t\r\n"};
char *oName;
[[Parser setKey1:"user"] setKey2:""];
[[Parser setDelim1:del1] setDelim2:del2];
if(!(oName = [Parser parseFile:aPath]))
[[NXApp delegate] showAlert:"Login Name not found in options file"];
return oName;
}
//*****************************************************************************
//
// return secrets password if the user owns the entry for login name
//
//*****************************************************************************
- (char *)secretOwnedBySelf
{
[self setParserForOwner:[loginNameField stringValue]];
return [Parser parseFile:NXGetDefaultValue([NXApp appName],"secrets")];
}
//*****************************************************************************
//
// return secrets password if another user owns the entry for login name
//
//*****************************************************************************
- (char *)secretOwnedByOther
{
[self setParserForOtherOwner:[loginNameField stringValue]];
return [Parser parseFile:NXGetDefaultValue([NXApp appName],"secrets")];
}
//*****************************************************************************
//
// add our default options and pppup files to our new Gate document
//
// paths for pppup file set from pref editor path
//
//*****************************************************************************
- addDefaultFiles:(const char *)nameOfFile
{
NXStream *Stream;
// add example options
if(![[NXBundle mainBundle]getPath:Path forResource:"Examples" ofType:NULL])
[[NXApp delegate] showAlert:"Error getting examples path"];
strncat(Path, XOPTION, MAXPATHLEN - strlen(XOPTION) - strlen(Path) + 1);
if((Stream = NXMapFile(Path, NX_READONLY)) == NULL)
[[NXApp delegate] showAlert:"Unable to open example options File"];
else
{
strncpy(Path, nameOfFile, MAXPATHLEN - strlen(OPTION));
strncat(Path, OPTION, (strlen(OPTION) + 1));
if((NXSaveToFile(Stream, Path)) == -1)
[[NXApp delegate] showAlert:"Error saving options to Gate doc"];
else
chown(Path, getuid(), getgid());
NXCloseMemory(Stream, NX_FREEBUFFER);
}
// add example pppup
if(![[NXBundle mainBundle]getPath:Path forResource:"Examples" ofType:NULL])
[[NXApp delegate] showAlert:"Error getting examples path"];
strncat(Path, PPPUP, MAXPATHLEN - strlen(PPPUP) - strlen(Path) + 1);
if((Stream = NXMapFile(Path, NX_READONLY)) == NULL)
[[NXApp delegate] showAlert:"Unable to open pppup example File"];
else
{
strncpy(Path, nameOfFile, MAXPATHLEN - strlen(PPPUP));
strncat(Path, PPPUP, (strlen(PPPUP) + 1));
if((NXSaveToFile(Stream, Path)) == -1)
[[NXApp delegate] showAlert:"Error saving pppup to .Gate doc"];
else
{
chmod(Path, (_S_IRUSR | _S_IWUSR)); // set to owner read/write
chown(Path, getuid(), getgid());
}
NXCloseMemory(Stream, NX_FREEBUFFER);
}
// add default Icon.tiff
if(![[NXBundle mainBundle] getPath:Path
forResource:"Icon.tiff" ofType:NULL])
[[NXApp delegate] showAlert:"Error getting Icon.tiff path"];
if((Stream = NXMapFile(Path, NX_READONLY)) == NULL)
[[NXApp delegate] showAlert:"Unable to open Icon.tiff File"];
strncpy(Path, nameOfFile, MAXPATHLEN - strlen(IMAGE));
strncat(Path, IMAGE, (strlen(IMAGE) + 1));
if((NXSaveToFile(Stream, Path)) == -1)
[[NXApp delegate] showAlert:"Unable to save Icon.tiff to Gate doc"];
else
chown(Path, getuid(), getgid());
NXCloseMemory(Stream, NX_FREEBUFFER);
return self;
}
//*****************************************************************************
//
// return path to options file
//
//*****************************************************************************
- (const char *)optionsPath
{
const char *aPath = NULL;
if(aPath = [self docPath])
{
strcpy(Path, aPath);
strcat(Path, OPTION);
aPath = Path;
}
else
[[NXApp delegate] showAlert:"ddbWriteError"];
return aPath;
}
//*****************************************************************************
//
// return path to pppup file
//
//*****************************************************************************
- (const char *)pppupPath
{
const char *aPath = NULL;
if(aPath = [self docPath])
{
strcpy(Path, aPath);
strcat(Path, PPPUP);
aPath = Path;
}
else
[[NXApp delegate] showAlert:"ddbWriteError"];
return aPath;
}
//*****************************************************************************
//
// return path to document
//
//*****************************************************************************
- (const char *)docPath
{
return NXGetDefaultValue([NXApp appName], EDOC);
}
//*****************************************************************************
//
// stop parsing
//
//*****************************************************************************
- ok:sender
{
return [NXApp stopModal];
}
//*********************** text field matrix delegation ************************
//*****************************************************************************
//
// as text delegate we recieve this when textfield cell is being edited
//
//*****************************************************************************
- (BOOL)textWillChange:textObject
{
[editPanel setDocEdited:YES]; // indicate change is not saved
return NO;
}
//*****************************************************************************
//
// text delegate receives when editing of textfield cell is ended
//
//*****************************************************************************
- textDidEnd:textObject endChar:(unsigned short)whyEnd
{
if ((whyEnd == 16) || (whyEnd == 17))
[editPanel setDocEdited:NO]; // indicate change is saved
return self;
}
//******************* Gate doc panel delegate methods *************************
//*****************************************************************************
//
// called whenever the user minituriazes our status window.
//
//*****************************************************************************
- windowWillMiniaturize:sender toMiniwindow:miniwindow
{
return [sender setMiniwindowIcon:".dir"];
}
//************************************************************************
//
// Edit options file in Edit.app
//
//************************************************************************
- editPppup:sender
{
if([[NXApp delegate] readable:[self pppupPath]]) // open with edit
[[Application workspace] openFile:[self pppupPath]
withApplication:"Edit"];
return self;
}
//************************************************************************
//
// Edit options file in Edit.app
//
//************************************************************************
- editOptions:sender
{
if([[NXApp delegate] readable:[self optionsPath]]) // open with edit
[[Application workspace] openFile:[self optionsPath]
withApplication:"Edit"];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.