This is HostListManager.m in view mode; [Download] [Up]
/*---------------------------------------------------------------------------
HostListManager.m -- Copyright (c) 1991 Rex Pruess
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 1, 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 or send
electronic mail to the the author.
This is the methods file for the HostListManager (HLM) class. A HLM object is
responsible for managing the internal linked host list and the host
configuration file.
Rex Pruess <rpruess@umaxc.weeg.uiowa.edu>
$Header: /rpruess/apps/Remotes3.0/RCS/HostListManager.m,v 3.0 92/09/23 21:49:40 rpruess Exp $
-----------------------------------------------------------------------------
$Log: HostListManager.m,v $
Revision 3.0 92/09/23 21:49:40 rpruess
Upgraded for NeXT System Release 3.0. Primary changes were to support the
Terminal application under NeXT System Release 3.0.
Revision 2.1 92/09/21 11:20:13 rpruess
Added code to set the window title and mini-window titles for Stuart
sessions.
Revision 2.0 91/01/22 15:32:47 rpruess
Remotes-2.0 was upgraded for NeXT System Release 2.0 (standard or extended).
Remotes-2.0 supports the NeXT supplied Terminal application and the Stuart
shareware product.
Revision 1.1 90/04/10 14:25:48 rpruess
Initial revision
-----------------------------------------------------------------------------*/
/* Standard C header files */
#include <ctype.h>
#include <libc.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/file.h>
/* Private C header files */
#include "remsubs.h"
/* Host List Manager class header files */
#import "HostListManager.h"
#import "StuartSpeaker.h"
/* Appkit header files */
#import <appkit/Application.h>
#import <appkit/Control.h>
#import <appkit/Panel.h>
#import <appkit/PopUpList.h>
#import <defaults/defaults.h>
@implementation HostListManager
/*---------------------------------------------------------------------------
Override the new method so the object can be properly initialized. This
initialization includes reading the configuration file & loading the hosts
into the internal linked list.
-----------------------------------------------------------------------------*/
- init
{
self = [super init];
[self initHLMObject:self]; /* Initialize linked host lists */
return self;
}
/*---------------------------------------------------------------------------
Initialize the host list.
-----------------------------------------------------------------------------*/
- initHLMObject:sender
{
short int appType;
short int autoLaunch;
char buffer[MAXRECLEN + 1];
char *bufPtr;
char buttonName[MAXPOPLEN + 1];
const char *defaultsDebugLevel;
int code;
short int columns;
char field[MAXRECLEN + 1];
unsigned int flagValues;
short int fontType;
short int fontSize;
char hName[MAXHOSTNAMELEN + 1];
int i;
short int lines;
short int metaNum;
BOOL oldStyle;
short int protocolType;
int recordNum;
NXSize screenSize; /* Screen width/height */
char userID[MAXIDLEN + 1];
short int versionNum;
short int x;
short int y;
FILE *fp;
/* Set debugging value from defaults data base */
defaultsDebugLevel = NXGetDefaultValue ([NXApp appName], "DebugLevel");
if (strcmp (defaultsDebugLevel, "low") == 0)
debugLevel = DEBUGLOW;
else if (strcmp (defaultsDebugLevel, "high") == 0)
debugLevel = DEBUGHIGH;
else if (strcmp (defaultsDebugLevel, "max") == 0)
debugLevel = DEBUGMAX;
else
debugLevel = DEBUGOFF;
/* Load linked host list. */
recordNum = 0;
nHosts = 0;
fp = [self openConfigFile:"r"];
if (fp == NULL) { /* In no hosts found, then force one! */
code = [self addLocalHost:self];
return self;
}
/* Read & process each record from the config file */
while (fgets (buffer, MAXRECLEN, fp) != NULL) {
bufPtr = buffer; /* Pointer to next field in buffer */
recordNum++;
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"version number" recNum:recordNum];
continue;
}
field[MAXPOPLEN] = '\0';
oldStyle = NO; /* Old style config file has no version # */
for (i = 0; i < strlen (field); i++) {
if (isdigit (field[i]))
continue;
else {
oldStyle = YES;
break;
}
}
if (oldStyle) {
versionNum = 0;
strcpy (buttonName, field);
}
else {
versionNum = atoi (field);
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"button name" recNum:recordNum];
continue;
}
field[MAXPOPLEN] = '\0';
strcpy (buttonName, field);
}
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"hostname" recNum:recordNum];
continue;
}
field[MAXHOSTNAMELEN] = '\0';
strcpy (hName, field);
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"user ID" recNum:recordNum];
continue;
}
field[MAXIDLEN] = '\0';
strcpy (userID, field);
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"application" recNum:recordNum];
continue;
}
appType = atoi (field);
if (appType != TERMINAL && appType != STUART) {
[self errPrint:"application" recNum:recordNum];
continue;
}
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"protocol" recNum:recordNum];
continue;
}
protocolType = atoi (field);
if (protocolType != RLOGIN && protocolType != TELNET
&& protocolType != TN3270) {
[self errPrint:"protocol" recNum:recordNum];
continue;
}
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"x" recNum:recordNum];
continue;
}
x = atoi (field);
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"y" recNum:recordNum];
continue;
}
y = atoi (field);
/* In old version, Y was measured from top of display. */
if (versionNum == 0 && y < 300) {
[NXApp getScreenSize:&screenSize];
y = screenSize.height - y;
}
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"lines" recNum:recordNum];
continue;
}
lines = atoi (field);
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"columns" recNum:recordNum];
continue;
}
columns = atoi (field);
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"font type" recNum:recordNum];
continue;
}
fontType = atoi (field);
if (fontType != COURIER && fontType != OHLFS) {
[self errPrint:"font type" recNum:recordNum];
continue;
}
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"font size" recNum:recordNum];
continue;
}
fontSize = atoi (field);
if ((bufPtr = getfield (bufPtr, field)) == NULL)
autoLaunch = NO;
else
autoLaunch = atoi (field);
if (appType == TERMINAL)
flagValues = TTRANSLAT | TAUTOWRAP | TSCROLLBK;
else
flagValues = SSCROLLBK | STRANSLAT | STERMSPAC;
metaNum = METAESC;
if (versionNum == CFGVERSION) {
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"flag values" recNum:recordNum];
continue;
}
flagValues = atoi (field);
if ((bufPtr = getfield (bufPtr, field)) == NULL) {
[self errPrint:"meta number" recNum:recordNum];
continue;
}
metaNum = atoi (field);
}
code = [self addHost:buttonName fullHostName:hName loginName:userID
application:appType protocol:protocolType locX:x locY:y
nLines:lines nCols:columns font:fontType fontSize:fontSize
autoStart:autoLaunch flags:flagValues meta:metaNum
updateConfigFile:NO];
if (debugLevel == DEBUGMAX) {
printf ("%s:(read #%d okay) version:%d\t%s\t%s\n",[NXApp appName],
recordNum, versionNum, buttonName, hName);
printf ("\tID:%s", userID);
printf ("\tapp:%d", appType);
printf ("\tprot:%d", protocolType);
printf ("\tx:%d", x);
printf ("\ty:%d", y);
printf ("\n");
printf ("\tlines:%d", lines);
printf ("\tcols:%d", columns);
printf ("\tfont:%d", fontType);
printf ("\tfontsize:%d", fontSize);
printf ("\n");
printf ("\tautostart:%d", autoLaunch);
printf ("\tflags:%u", flagValues);
printf ("\tmeta:%d", metaNum);
printf ("\n");
}
}
fclose (fp);
if (debugLevel >= DEBUGHIGH)
printf ("%s: %d records successfully read from config file.\n",
[NXApp appName], nHosts);
return self;
}
/*---------------------------------------------------------------------------
Stuff an entry into the doubly linked circular list of hosts. The head and
tail entries point to each other so a true circular loop is maintained & thus
simplifies coding. Duplicates are not entered. This routine returns the slot
number where the host was inserted. The list is maintained in alphabetical
order.
-----------------------------------------------------------------------------*/
- (int)insert:(struct hostEntry *) newEntry
{
int slotNum; /* Slot position of host in linked list */
struct hostEntry *hostPtr; /* Pointer to host entry */
/* First entry in the list. Point to myself. */
if (nHosts == 0) {
newEntry -> nextHost = newEntry;
newEntry -> prevHost = newEntry;
begHost = newEntry; /* Set beginning host pointer too. */
nHosts++;
return 0;
}
/* Find spot that this entry must be inserted at. */
hostPtr = begHost;
for (slotNum = 0; slotNum < nHosts; slotNum++) {
if (strcmp (newEntry -> popUpName, hostPtr -> popUpName) < 0)
break;
if (strcmp (newEntry -> popUpName, hostPtr -> popUpName) == 0)
return -1;
hostPtr = hostPtr -> nextHost;
}
/* Entry is at head of list. Adjust beginning host pointer too. */
if (slotNum == 0)
begHost = newEntry;
/* Set new entry's next & previous pointers */
newEntry -> nextHost = hostPtr;
newEntry -> prevHost = hostPtr -> prevHost;
/* Set previous host's "next pointer" */
hostPtr -> prevHost -> nextHost = newEntry;
/* Set next host's "previous pointer" */
hostPtr -> prevHost = newEntry;
nHosts++;
return slotNum;
}
/*---------------------------------------------------------------------------
Print error message about bad input record in configuration file.
-----------------------------------------------------------------------------*/
- errPrint:(char *)fieldName recNum:(int)recordNum
{
printf ("%s:Invalid %s field in record %d in config file.\n",
[NXApp appName], fieldName, recordNum);
return self;
}
/*---------------------------------------------------------------------------
Add a host into the internal linked list.
-----------------------------------------------------------------------------*/
- (int)addHost:(const char *)buttonName
fullHostName:(const char *)fullName
loginName:(const char *)userID
application:(short int)app
protocol:(short int)prot
locX:(short int)x
locY:(short int)y
nLines:(short int)lines
nCols:(short int)columns
font:(short int)aFont
fontSize:(short int)fontNum
autoStart:(short int)autoLaunch
flags:(unsigned int)flagValues
meta:(short int)metaNum
updateConfigFile:(short int)updConfigFile
{
int slotNum; /* Slot position of host in linked list */
struct hostEntry *newEntry; /* Pointer to host entry */
FILE *fp;
newEntry = malloc (HOSTENTRYLEN);
strcpy (newEntry -> popUpName, buttonName);
strcpy (newEntry -> hostName, fullName);
strcpy (newEntry -> loginName, userID);
newEntry -> appType = app;
newEntry -> protocolType = prot;
newEntry -> locX = x;
newEntry -> locY = y;
newEntry -> nLines = lines;
newEntry -> nCols = columns;
newEntry -> fontType = aFont;
newEntry -> fontSize = fontNum;
newEntry -> autoStart = autoLaunch;
newEntry -> flags = flagValues;
newEntry -> meta = metaNum;
slotNum = [self insert:newEntry];
if (slotNum < 0 || updConfigFile == NO)
return slotNum;
fp = [self openConfigFile:"a"];
if (fp != NULL) {
fprintf (fp, "%d", CFGVERSION);
fprintf (fp, "\t%s", buttonName);
fprintf (fp, "\t%s", fullName);
fprintf (fp, "\t%s", userID);
fprintf (fp, "\t%d", app);
fprintf (fp, "\t%d", prot);
fprintf (fp, "\t%d", x);
fprintf (fp, "\t%d", y);
fprintf (fp, "\t%d", lines);
fprintf (fp, "\t%d", columns);
fprintf (fp, "\t%d", aFont);
fprintf (fp, "\t%d", fontNum);
fprintf (fp, "\t%d", autoLaunch);
fprintf (fp, "\t%u", flagValues);
fprintf (fp, "\t%d", metaNum);
fprintf (fp, "\n");
}
fclose (fp);
if (debugLevel >= DEBUGHIGH)
printf ("%s: Record added to config file.\n",[NXApp appName]);
if (debugLevel == DEBUGMAX) {
printf ("%s:(append okay) version:%d\t%s\t%s\n",
[NXApp appName], CFGVERSION, buttonName, fullName);
printf ("\tID:%s", userID);
printf ("\tapp:%d", app);
printf ("\tprot:%d", prot);
printf ("\tx:%d", x);
printf ("\ty:%d", y);
printf ("\n");
printf ("\tlines:%d", lines);
printf ("\tcols:%d", columns);
printf ("\tfont:%d", aFont);
printf ("\tfontsize:%d", fontNum);
printf ("\n");
printf ("\tautostart:%d", autoLaunch);
printf ("\tflags:%u", flagValues);
printf ("\tmeta:%d", metaNum);
printf ("\n");
}
return slotNum;
}
/*---------------------------------------------------------------------------
Add a default Terminal & Stuart entry. Use values in the defaults data base
for the various fields.
-----------------------------------------------------------------------------*/
- (int)addLocalHost:sender
{
short int columns;
short int lines;
unsigned int flagValues;
short int fontNum;
short int fontStyle;
int slotNum; /* Slot position of host in linked list */
const char *string; /* Temporary variable */
string = NXGetDefaultValue ("Terminal", "Columns");
columns = atoi (string);
string = NXGetDefaultValue ("Terminal", "Rows");
lines = atoi (string);
string = NXGetDefaultValue ("Terminal", "NXFixedPitchFontSize");
fontNum = atoi (string);
string = NXGetDefaultValue ("Terminal", "NXFixedPitchFont");
if (strcmp (string, "Courier") == 0)
fontStyle = COURIER;
else
fontStyle = OHLFS;
flagValues = TTRANSLAT | TAUTOWRAP | TSCROLLBK | TSOURCEDL;
slotNum = [self addHost:"Terminal" fullHostName:"localhost" loginName:""
application:TERMINAL protocol:RLOGIN locX:120 locY:832 nLines:lines
nCols:columns font:fontStyle fontSize:fontNum
autoStart:NO flags:flagValues meta:METAESC updateConfigFile:YES];
string = NXGetDefaultValue ("Stuart", "Columns");
columns = atoi (string);
string = NXGetDefaultValue ("Stuart", "Lines");
lines = atoi (string);
string = NXGetDefaultValue ("Stuart", "NXFixedPitchFontSize");
fontNum = atoi (string);
string = NXGetDefaultValue ("Stuart", "NXFixedPitchFont");
if (strcmp (string, "Courier") == 0)
fontStyle = COURIER;
else
fontStyle = OHLFS;
flagValues = SSCROLLBK | STRANSLAT | STERMSPAC | SSOURCEDL;
slotNum = [self addHost:"Stuart" fullHostName:"localhost" loginName:""
application:STUART protocol:RLOGIN locX:130 locY:832 nLines:lines
nCols:columns font:fontStyle fontSize:fontNum
autoStart:NO flags:flagValues meta:METAESC updateConfigFile:YES];
return slotNum;
}
/*---------------------------------------------------------------------------
Change values in an existing host entry.
-----------------------------------------------------------------------------*/
- (int)changeHost:(const char *)buttonName
fullHostName:(const char *)fullName
loginName:(const char *)userID
application:(short int)app
protocol:(short int)prot
locX:(short int)x
locY:(short int)y
nLines:(short int)lines
nCols:(short int)columns
font:(short int)aFont
fontSize:(short int)fontNum
autoStart:(short int)autoLaunch
flags:(unsigned int)flagValues
meta:(short int)metaNum
{
int i;
int slotNum; /* Slot position of host in linked list */
struct hostEntry *hostPtr; /* Pointer to host entry */
slotNum = [self getHostSlotNum:buttonName];
if (slotNum < 0)
return slotNum;
/* Find the host in our list */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
strcpy (hostPtr -> popUpName, buttonName);
strcpy (hostPtr -> hostName, fullName);
strcpy (hostPtr -> loginName, userID);
hostPtr -> appType = app;
hostPtr -> protocolType = prot;
hostPtr -> locX = x;
hostPtr -> locY = y;
hostPtr -> nLines = lines;
hostPtr -> nCols = columns;
hostPtr -> fontType = aFont;
hostPtr -> fontSize = fontNum;
hostPtr -> autoStart = autoLaunch;
hostPtr -> flags = flagValues;
hostPtr -> meta = metaNum;
[self writeConfigFile:self];
return slotNum;
}
/*---------------------------------------------------------------------------
Delete a host entry from the internal linked list & from the file.
-----------------------------------------------------------------------------*/
- (int)deleteHost:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
if (slotNum == 0)
begHost = hostPtr -> nextHost; /* Head entry deletion */
else
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
hostPtr -> nextHost -> prevHost = hostPtr -> prevHost;
hostPtr -> prevHost -> nextHost = hostPtr -> nextHost;
free (hostPtr);
nHosts--;
[self writeConfigFile:self];
return slotNum;
}
/*---------------------------------------------------------------------------
Return the application type (e.g., Terminal, Stuart) for this slot.
-----------------------------------------------------------------------------*/
- (int)getAppType:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> appType;
}
/*---------------------------------------------------------------------------
Return the auto launch value for this slot.
-----------------------------------------------------------------------------*/
- (int)getAutoStart:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> autoStart;
}
/*---------------------------------------------------------------------------
Return the button name for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (char *)getButtonName:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> popUpName;
}
/*---------------------------------------------------------------------------
Return the width for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (int)getColumns:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> nCols;
}
/*---------------------------------------------------------------------------
Return the configuration pathname for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (const char *)getConfigFile:sender
{
return NXGetDefaultValue ([NXApp appName], "ConfigFile");
}
/*---------------------------------------------------------------------------
Return the debugging level.
-----------------------------------------------------------------------------*/
- (int)getDebugLevel:sender
{
return debugLevel;
}
/*---------------------------------------------------------------------------
Return the Stuart/Terminal flag values.
-----------------------------------------------------------------------------*/
- (unsigned int)getFlags:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> flags;
}
/*---------------------------------------------------------------------------
Return the font type for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (int)getFontType:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> fontType;
}
/*---------------------------------------------------------------------------
Return the font size for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (int)getFontSize:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> fontSize;
}
/*---------------------------------------------------------------------------
Return the complete host name for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (char *)getFullHostName:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> hostName;
}
/*---------------------------------------------------------------------------
Return the host slot number for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (int)getHostSlotNum:(const char *)buttonName
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < nHosts; i++) {
if (strcmp (buttonName, hostPtr -> popUpName) == 0)
return i;
hostPtr = hostPtr -> nextHost;
}
return -1;
}
/*---------------------------------------------------------------------------
Return the number of lines in the window for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (int)getLines:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> nLines;
}
/*---------------------------------------------------------------------------
Return the meta value.
-----------------------------------------------------------------------------*/
- (int)getMeta:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> meta;
}
/*---------------------------------------------------------------------------
Return the number of hosts in list.
-----------------------------------------------------------------------------*/
- (int)getNumHosts:sender
{
return nHosts;
}
/*---------------------------------------------------------------------------
Return the popup button name for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (char *)getPopUpName:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> popUpName;
}
/*---------------------------------------------------------------------------
Return the protocol type (e.g., rlogin, telnet, tn3270).
-----------------------------------------------------------------------------*/
- (int)getProtocolType:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> protocolType;
}
/*---------------------------------------------------------------------------
Return the user ID for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (char *)getUserID:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> loginName;
}
/*---------------------------------------------------------------------------
Return the X coordinate for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (int)getX:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> locX;
}
/*---------------------------------------------------------------------------
Return the Y coordinate for the entry at the specified slot.
-----------------------------------------------------------------------------*/
- (int)getY:(int)slotNum
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
return hostPtr -> locY;
}
/*---------------------------------------------------------------------------
Load a popuplist. This could be either the hosts popup list or the
configuration pulldown list.
-----------------------------------------------------------------------------*/
- loadPopUpList:aPopUpList
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < nHosts; i++) {
[aPopUpList addItem:hostPtr -> popUpName];
hostPtr = hostPtr -> nextHost;
}
return self;
}
/*---------------------------------------------------------------------------
Remotes is coming to life. Launch those automatic startup guys.
-----------------------------------------------------------------------------*/
- autoStart:sender
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
hostPtr = begHost;
for (i = 0; i < nHosts; i++) {
if (hostPtr -> autoStart == YES)
[self loginToHost:hostPtr -> popUpName activate:NO];
hostPtr = hostPtr -> nextHost;
}
return self;
}
/*---------------------------------------------------------------------------
Fire up a Terminal or Stuart session for the user.
-----------------------------------------------------------------------------*/
- loginToHost:(const char *)buttonName activate:(BOOL)actWindow
{
char colsStr[16];
char *comArgs[MAXCOMARGS];
char command[1024];
char errMsg[256];
int i;
int ind;
char fontStr[16];
char linesStr[16];
char loginStr[256];
char metaStr[16];
int pid;
char *shellPtr;
id stuart;
int slotNum;
char **tempPtr;
char xStr[16];
char yStr[16];
int vfork (void);
struct hostEntry *hostPtr; /* Pointer to host entry */
slotNum = [self getHostSlotNum:buttonName];
if (slotNum < 0) {
NXRunAlertPanel (NULL, "Button name '%s' not found.", NULL, NULL, NULL, buttonName);
return self;
}
ind = 0;
hostPtr = begHost;
for (i = 0; i < slotNum; i++)
hostPtr = hostPtr -> nextHost;
if (hostPtr -> appType == TERMINAL) {
strcpy (command, "/NextApps/Terminal.app/Terminal");
comArgs[ind++] = "Terminal";
comArgs[ind++] = "-Shell";
if (strcmp (hostPtr -> hostName, "localhost") == 0) {
shellPtr = getenv ("SHELL");
if (shellPtr == NULL)
comArgs[ind++] = "/bin/csh";
else
comArgs[ind++] = shellPtr;
}
else {
switch (hostPtr -> protocolType) {
case RLOGIN:
strcpy (loginStr, "\"/usr/ucb/rlogin ");
strcat (loginStr, hostPtr -> hostName);
if (*hostPtr -> loginName != '\0') {
strcat (loginStr, " -l ");
strcat (loginStr, hostPtr -> loginName);
}
break;
case TELNET:
strcpy (loginStr, "\"/usr/ucb/telnet ");
strcat (loginStr, hostPtr -> hostName);
break;
case TN3270:
strcpy (loginStr, "\"/usr/ucb/tn3270 ");
strcat (loginStr, hostPtr -> hostName);
break;
default:
break;
}
strcat (loginStr, "\"");
comArgs[ind++] = loginStr;
}
comArgs[ind++] = "-WinLocX";
sprintf (xStr, "%d", hostPtr -> locX);
comArgs[ind++] = xStr;
comArgs[ind++] = "-WinLocY";
sprintf (yStr, "%d", hostPtr -> locY);
comArgs[ind++] = yStr;
comArgs[ind++] = "-Rows";
sprintf (linesStr, "%d", hostPtr -> nLines);
comArgs[ind++] = linesStr;
comArgs[ind++] = "-Columns";
sprintf (colsStr, "%d", hostPtr -> nCols);
comArgs[ind++] = colsStr;
comArgs[ind++] = "-NXFixedPitchFont";
if (hostPtr -> fontType == COURIER)
comArgs[ind++] = "Courier";
else
comArgs[ind++] = "Ohlfs";
comArgs[ind++] = "-NXFixedPitchFontSize";
sprintf (fontStr, "%d", hostPtr -> fontSize);
comArgs[ind++] = fontStr;
if (hostPtr -> meta != TMETADEF) {
comArgs[ind++] = "-Meta";
sprintf (metaStr, "%d", hostPtr -> meta);
comArgs[ind++] = metaStr;
}
comArgs[ind++] = "-Translate";
comArgs[ind++] = (hostPtr -> flags & TTRANSLAT) ? "YES" : "NO";
comArgs[ind++] = "-Keypad";
comArgs[ind++] = (hostPtr -> flags & TKEYPAD) ? "YES" : "NO";
comArgs[ind++] = "-StrictEmulation";
comArgs[ind++] = (hostPtr -> flags & TSTRICTEM) ? "YES" : "NO";
comArgs[ind++] = "-Autowrap";
comArgs[ind++] = (hostPtr -> flags & TAUTOWRAP) ? "YES" : "NO";
comArgs[ind++] = "-Scrollback";
comArgs[ind++] = (hostPtr -> flags & TSCROLLBK) ? "YES" : "NO";
comArgs[ind++] = "-AutoFocus";
comArgs[ind++] = (hostPtr -> flags & TAUTOFOCS) ? "YES" : "NO";
comArgs[ind++] = "-SourceDotLogin";
comArgs[ind++] = (hostPtr -> flags & TSOURCEDL) ? "YES" : "NO";
comArgs[ind++] = "-CustomTitle";
comArgs[ind++] = hostPtr -> hostName;
comArgs[ind++] = NULL;
/*** Gotta build a shell-like command under NeXT Release 3.1. */
tempPtr = comArgs;
while (*++tempPtr != NULL) {
strcat (command, " ");
strcat (command, *tempPtr);
}
if (debugLevel != DEBUGOFF)
printf ("%s: %s\n",[NXApp appName], command);
pid = vfork ();
if (pid == 0) {
system (command);
exit (0);
#if 0 /*** execve worked under NeXT Release 2.x. Doesn't work now. */
code = execve (command, comArgs, environ);
perror ([NXApp appName]);
fprintf (stderr, "%s: Execve error code=%d.\n",[NXApp appName], code);
_exit (0);
#endif
}
}
else {
stuart = [StuartSpeaker new];
if (debugLevel != DEBUGOFF)
printf ("Stuart");
if (strcmp (hostPtr -> hostName, "localhost") != 0) {
switch (hostPtr -> protocolType) {
case RLOGIN:
strcpy (loginStr, "rlogin ");
strcat (loginStr, hostPtr -> hostName);
if (*hostPtr -> loginName != '\0') {
strcat (loginStr, " -l ");
strcat (loginStr, hostPtr -> loginName);
}
break;
case TELNET:
strcpy (loginStr, "telnet ");
strcat (loginStr, hostPtr -> hostName);
break;
case TN3270:
strcpy (loginStr, "tn3270 ");
strcat (loginStr, hostPtr -> hostName);
break;
default:
break;
}
[self setStuartDefault:stuart default:"Shell" as:loginStr];
}
sprintf (xStr, "%d", hostPtr -> locX);
[self setStuartDefault:stuart default:"WinLocX" as:xStr];
sprintf (yStr, "%d", hostPtr -> locY);
[self setStuartDefault:stuart default:"WinLocY" as:yStr];
sprintf (linesStr, "%d", hostPtr -> nLines);
[self setStuartDefault:stuart default:"Lines" as:linesStr];
sprintf (colsStr, "%d", hostPtr -> nCols);
[self setStuartDefault:stuart default:"Columns" as:colsStr];
if (hostPtr -> fontType == COURIER)
[self setStuartDefault:stuart default:"NXFixedPitchFont" as:"Courier"];
else
[self setStuartDefault:stuart default:"NXFixedPitchFont" as:"Ohlfs"];
sprintf (fontStr, "%d", hostPtr -> fontSize);
[self setStuartDefault:stuart default:"NXFixedPitchFontSize" as:fontStr];
if (hostPtr -> meta != SMETADEF) {
sprintf (metaStr, "%d", hostPtr -> meta);
[self setStuartDefault:stuart default:"Meta" as:metaStr];
}
[self setStuartDefault:stuart default:"Strict" as:(hostPtr -> flags & SSTRICTEM) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"Keypad" as:(hostPtr -> flags & SKEYPAD) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"Scrollback" as:(hostPtr -> flags & SSCROLLBK) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"Translate" as:(hostPtr -> flags & STRANSLAT) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"Reverse" as:(hostPtr -> flags & SREVERSE) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"KeyboardFocus" as:(hostPtr -> flags & SKEYBDFOC) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"TerminalSpacing" as:(hostPtr -> flags & STERMSPAC) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"MouseFocus" as:(hostPtr -> flags & SMOUSEFOC) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"SourceDotLogin" as:(hostPtr -> flags & SSOURCEDL) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"TestExit" as:(hostPtr -> flags & STESTEXIT) ? "YES" : "NO"];
[self setStuartDefault:stuart default:"WriteStuartrc" as:"NO"];
[self setStuartDefault:stuart default:"Title" as:hostPtr -> hostName];
[self setStuartDefault:stuart default:"MiniTitle" as:buttonName];
[self setStuartDefault:stuart default:"Activate" as:actWindow ? "YES" : "NO"];
if (debugLevel != DEBUGOFF)
printf("\n");
if ([stuart stuartConnectAndNew]) {
strcpy (errMsg, "There was a problem communicating with the Stuart ");
strcat (errMsg, "application. (Speaker port unavailable.) This may ");
strcat (errMsg, "have occurred because Stuart is not installed on ");
strcat (errMsg, "your system or because Stuart was slow in starting.");
NXRunAlertPanel (NULL, errMsg, NULL, NULL, NULL, NULL);
}
[stuart free];
}
return self;
}
/*---------------------------------------------------------------------------
Set specified Stuart default value.
-----------------------------------------------------------------------------*/
- setStuartDefault:aStuart default:(const char *)defaultV as:(const char *)asV
{
if (debugLevel != DEBUGOFF)
printf(" -%s %s", defaultV, asV);
[aStuart default:defaultV as:asV];
return self;
}
/*---------------------------------------------------------------------------
Set debugging variable within object & in defaults data base.
-----------------------------------------------------------------------------*/
- setDebugLevel:(short int)debugNum
{
int code;
char defaultsDebugLevel[5];
debugLevel = debugNum; /* Update object's setting */
if (debugNum == 1)
strcpy (defaultsDebugLevel, "low");
else if (debugNum == 2)
strcpy (defaultsDebugLevel, "high");
else
strcpy (defaultsDebugLevel, "off");
code = NXWriteDefault ([NXApp appName], "DebugLevel", defaultsDebugLevel);
return self;
}
/*---------------------------------------------------------------------------
Open the configuration file.
-----------------------------------------------------------------------------*/
- (FILE *) openConfigFile:(const char *)mode
{
const char *configFile; /* Configuration pathname */
FILE *fp;
configFile = NXGetDefaultValue ([NXApp appName], "ConfigFile");
if ((fp = fopen (configFile, mode)) == NULL) {
if (debugLevel >= DEBUGHIGH)
printf ("%s:Unable to open config file '%s' with mode '%s'.\n",
[NXApp appName], configFile, mode);
return NULL;
}
if (debugLevel >= DEBUGHIGH)
printf ("%s:'%s' opened with mode '%s'.\n",
[NXApp appName], configFile, mode);
return fp;
}
/*---------------------------------------------------------------------------
Set configuration path variable within object & in defaults data base.
-----------------------------------------------------------------------------*/
- setConfigFile:(const char *)configFile
{
const char *configFileOld;
FILE *fp;
if (strcmp (configFile,[self getConfigFile:self]) == 0)
return self;
if (index (configFile, ' ') != 0) {
NXRunAlertPanel (NULL, "Blanks not allowed in pathname.", NULL, NULL,
NULL);
return self;
}
fp = fopen (configFile, "r");
if (fp != NULL) {
fclose (fp);
if (NXRunAlertPanel (NULL, "The config file '%s' exists; OK to overwrite?",
"Cancel", "OK", NULL, configFile) == NX_ALERTDEFAULT)
return self;
}
fp = fopen (configFile, "w");
if (fp == NULL) {
NXRunAlertPanel (NULL, "Unable to open the config file '%s'.", NULL, NULL, NULL, configFile);
return self;
}
configFileOld = NXGetDefaultValue ([NXApp appName], "ConfigFile");
if (NXWriteDefault ([NXApp appName], "ConfigFile", configFile) == 0) {
NXRunAlertPanel (NULL, "Unable to write to defaults data base.", NULL, NULL,
NULL);
return self;
}
[self writeConfigFile:self];
unlink (configFileOld);
return self;
}
/*---------------------------------------------------------------------------
Write the configuration file from our internal list.
-----------------------------------------------------------------------------*/
- writeConfigFile:sender
{
int i;
struct hostEntry *hostPtr; /* Pointer to host entry */
FILE *fp;
fp = [self openConfigFile:"w"];
hostPtr = begHost;
for (i = 0; i < nHosts; i++) {
fprintf (fp, "%d", CFGVERSION);
fprintf( fp, "\t%s", hostPtr -> popUpName);
fprintf( fp, "\t%s", hostPtr -> hostName);
fprintf (fp, "\t%s", hostPtr -> loginName);
fprintf (fp, "\t%d", hostPtr -> appType);
fprintf (fp, "\t%d", hostPtr -> protocolType);
fprintf (fp, "\t%d", hostPtr -> locX);
fprintf (fp, "\t%d", hostPtr -> locY);
fprintf (fp, "\t%d", hostPtr -> nLines);
fprintf (fp, "\t%d", hostPtr -> nCols);
fprintf (fp, "\t%d", hostPtr -> fontType);
fprintf (fp, "\t%d", hostPtr -> fontSize);
fprintf (fp, "\t%d", hostPtr -> autoStart);
fprintf (fp, "\t%u", hostPtr -> flags);
fprintf (fp, "\t%d", hostPtr -> meta);
fprintf (fp, "\n");
if (debugLevel == DEBUGMAX) {
printf ("%s:(write #%d okay) version:%d\t%s\t%s\n",
[NXApp appName], i + 1, CFGVERSION, hostPtr -> popUpName, hostPtr -> hostName);
printf ("\tID:%s", hostPtr -> loginName);
printf ("\tapp:%d", hostPtr -> appType);
printf ("\tprot:%d", hostPtr -> protocolType);
printf ("\tx:%d", hostPtr -> locX);
printf ("\ty:%d", hostPtr -> locY);
printf ("\n");
printf ("\tlines:%d", hostPtr -> nLines);
printf ("\tcols:%d", hostPtr -> nCols);
printf ("\tfont:%d", hostPtr -> fontType);
printf ("\tfontsize:%d", hostPtr -> fontSize);
printf ("\n");
printf ("\tautostart:%d", hostPtr -> autoStart);
printf ("\tflags:%u", hostPtr -> flags);
printf ("\tmeta:%d", hostPtr -> meta);
printf ("\n");
}
hostPtr = hostPtr -> nextHost;
}
fclose (fp);
if (debugLevel >= DEBUGHIGH)
printf ("%s: Config file written. %d records in the file.\n",
[NXApp appName], nHosts);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.