// 
//  SCSI_Inspector.app - a SCSI reporting tool for Motorola and Intel 
//						 systems running NeXTSTEP version 3.2 or higher.
//
//  Copyright (C) 1994 by Christopher Wolf.
//  
//	This program is free software; you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation; either version 2 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
//  Bug-reports, comments and questions should be directed to:
//		Christopher Wolf - chris@alchemy.geo.cornell.edu
//
//  Portions of this program are based on earlier code (SCSI Inquirer)
//  Copyright 1992 by Jiro Nakamura and used with permission.
//

//
// 	For best results view this file with a tab size of 4 and
//	a display width of 132 columns or wider.
//

// 	file version information
#define RCSCM "$Id: Controller.m,v 0.51 94/12/06 03:39:14 chris Exp $"

//	NeXTSTEP headers
#import <appkit/appkit.h>
#import <nikit/NILoginPanel.h>
#import <nikit/NIDomain.h>
#import <defaults/defaults.h>	

//	generic Unix headers
#import <strings.h>
#import <sys/types.h>
#import <libc.h>					// For geteuid()
#import <sys/vnode.h>				// for chmod code
#import <pwd.h>						// for user authentication

// 	SCSI_Inspector.app headers
#import "Controller.h"
#import "Inspector.h"
#import "Version.h"

// string constants
const char RCScm[] = RCSCM;
const char RCSch[] = RCSCH;

@implementation Controller
	

//	********************************
//
//	Delegate Methods for Application
//
// 	********************************

- appWillInit: sender
	{

	NILoginPanel *loginPanel;
		
	if(geteuid())
		{
		NXRunAlertPanel("Not Running as Root", 
 			 	  		"This program must be installed SUID root in order to access "
				 	    "SCSI devices. See manual for more information.", 
						"Quit", NULL, NULL);
		exit(1);
		}
	else
		{
		if (getuid())
			{
			loginPanel = [NILoginPanel new];
			[loginPanel setDelegate: self];
			if (![loginPanel runModalWithValidation: self inDomain: NULL withUser: "root" 
				withInstruction: "Please supply the local root password." allowChange: FALSE]) 
				{
				NXRunAlertPanel("Incorrect Password",
								"Sorry, you supplied an incorrect root password.",
								"Quit",NULL,NULL);
				exit(1);
				}
			}
		}

	return self;

	}

- appDidInit: sender
	{

	char tempBuffer[64], *tbi;	
	struct stat buf;
	
	sprintf(tempBuffer,"%s %s",REVNUMBER,REVDATE);
    for (tbi = tempBuffer; *tbi; tbi++)
		{
		if (*tbi == '$')
			{
			*tbi = ' ';
			}
		}		
	[versionInfoText setStringValue: tempBuffer];

	stat( NXArgv[0],  &buf);
	if( !(buf.st_mode & 04000) && !(geteuid()) )
		{
		[installSelfMenuItem setEnabled: YES];
		}

	[formatMenuItem setEnabled: NO];
	[cacheMenuItem setEnabled: NO];

	[selectorWindow makeKeyAndOrderFront: self];
			
	return self;
	
	}

	
	
// ******************************************
// 
// Delegate methods for NXBrowser device list
// 
// ******************************************	

- (int) browser: sender getNumRowsInColumn: (int) column
	{
	return 8;
	}
	
- browser: sender loadCell: cell atRow: (int)row inColumn: (int)column
	{
	
	char tempBuffer[32];
			
	[inspector setTarget: row lun: 0];
	
	if ([inspector inquireTarget])
		{
		sprintf(tempBuffer, "%d - %.8s %.16s", row, [inspector targetVendorID], [inspector targetProductID]);
		}
	else
		{
		sprintf(tempBuffer, "%d - No Device", row);
		}

	[cell setStringValue: tempBuffer];
	[cell setLeaf: YES];
	[cell setLoaded: YES];
				
	return self;

	}



//	**********************************************
//
//	Delegate methods for user authentication panel
//
//	**********************************************

- (BOOL) panel: thePanel authenticateUser: (const char *)userName withPassword: (const char *) password inDomain: (const void *)domain
	{

	struct passwd *passwd;
	char passwordcopy[32];
	char salt[3] = "  ";
	
	passwd = getpwnam(userName);
	strcpy(passwordcopy,password);
	strncpy(salt,passwd->pw_passwd,2);
	return (!(strcmp(crypt(passwordcopy,salt),passwd->pw_passwd)));

	}


//	*********************************
//
//	Controller class instance methods
//
//	*********************************
	
//
//	target for Install Self menu item
//

- installSelf: sender
	{

	struct stat buf;
		
	if( !NXRunAlertPanel("Install SCSI Inspector as SUID Root", 
		"Installing this program as SUID root allows any user "
		"to run this program as root and represents a security "
		"hazard for some sites. Please read the documentation for more "
		"details.", "Install", "Cancel", NULL))
		{
		return nil;
		}
		
	stat( NXArgv[0],  &buf);
	chown( NXArgv[0], 0, 3);
	chmod( NXArgv[0], VSUID | buf.st_mode);
	
	[installSelfMenuItem setEnabled: NO];
	NXRunAlertPanel("Installation Successful", "Program installed successfully.", "OK", NULL, NULL);
		
	return self;
	
	}


//
//	target for NXBrowser selection
//
		
- inquireSelected: sender
	{

	[inspector setTarget: [[sender matrixInColumn: [sender selectedColumn]] selectedRow] lun: 0];

	if (  [inspector targetIsValid] 
	   && ([inspector targetDeviceType] == DEVTYPE_DISK))
	   	{
		[formatMenuItem setEnabled: YES];
		[cacheMenuItem setEnabled: YES];
	   	}
	else
		{
		[formatMenuItem setEnabled: NO];
		[cacheMenuItem setEnabled: NO];
		}
	
	[inspectorWindow makeKeyAndOrderFront: self];
	[cachePanel close];
	[formatPanel close];
	
	[inspector inspectTarget: self];

	return self;
	
	}

@end
