This is myApp.m in view mode; [Download] [Up]
#import "myApp.h"
#import <streams/streams.h>
#import <utmp.h>
int find();
void enter();
void clear_marks();
void remove_unmarked();
@implementation myApp
void who(DPSTimedEntry teNumber, double now, char *userData)
/* Call this function via the DPS Timed Entry */
{
struct utmp temp; /* Utmp structure. See utmp.h */
clear_marks(); /* Clear marked */
utmpFile = NXMapFile("/etc/utmp", NX_READONLY); /* Map utmp file into memory */
if (utmpFile == NULL)
{
exit(0);
}
while( NXRead(utmpFile, &temp, sizeof(struct utmp)) !=0 ) /* Read next entry */
{
if (temp.ut_name[0] != '\000') /* Is is a real user? */
enter(temp.ut_line, temp.ut_name); /* Yes, enter or affirm in list */
}
remove_unmarked(); /* Remove all un-referenced entries in
the list */
NXClose(utmpFile); /* Close utmp file */
}
-init
{
nextX = nextY = 0; /* Init Icon Position coordinates */
last = users = NULL; /* Initialize List pointers */
DPSAddTimedEntry((double)5.0, who, NULL, NX_BASETHRESHOLD);
c_self = self; /* Fudge. C calls seem to need this */
return(self);
}
-newIconUser: (const char *)name tty: (const char *)ttystr xcoord: (float)x ycoord: (float)y
{
NXRect windowRect;
iconWindow = [Window alloc]; /* Get a window instance */
/* Calulate Screen Coordinates */
windowRect.origin.x = 4.0 + 64.0 * x;
windowRect.origin.y = 0.0 + 64.0 * y;
windowRect.size.height = windowRect.size.width = 64.0; /* Icon size 64x64 */
/*Init the window content */
[iconWindow initContent: &windowRect style: NX_PLAINSTYLE
backing: NX_BUFFERED buttonMask:0 defer: YES];
/* Get an IconView Instance */
icon = [[IconView alloc] init];
/* Set IconView as the window's contentView */
[iconWindow setContentView: icon];
[iconWindow setDelegate:icon]; /* Make view the window's delegate */
[iconWindow makeFirstResponder:icon]; /* and first responder */
/* Add to window list */
[iconWindow makeKeyAndOrderFront:self];
[icon iconSetName: name]; /* Set icon variables */
[icon iconSetTty: ttystr];
return iconWindow;
}
void enter(tty,name)
char *tty, *name;
{
struct record *temp;
if (find(tty, name)==0) /* If new entry, malloc space and put in list */
{
temp = (struct record *) malloc(sizeof (struct record ));
temp->next = NULL;
/* New Icon */
temp->windowPointer = [c_self newIconUser: name tty: tty
xcoord: (float)nextX ycoord:(float) nextY];
temp->x = (float)nextX; /* Position Icon in "dock" */
temp->y = (float)nextY;
temp->marked = 1; /* Mark icon as referenced */
strcpy(temp->name, name); /* User name */
strcpy(temp->tty, tty); /* TTY name */
if (last == NULL) /* First entry in list (usually console) */
{
users = temp;
last = temp;
}
else /* Not furst entry in list */
{
last->next = temp;
last = temp;
}
nextY++; /* Update coordinate for next icon */
if (nextY>=13)
{
nextY = 0;
nextX++;
}
}
}
void clear_marks() /* Simply traverse list and clear "marked" item in struct */
{
struct record *temp;
temp = users;
while (temp!=NULL)
{
temp->marked = 0;
temp = temp->next;
}
}
void remove_unmarked() /* Remove all items from the list which have not been referenced */
{
struct record *temp,*prev;
nextX = nextY = 0;
temp = users;
prev = temp;
while (temp!=NULL)
{
if (temp->marked == 0) /* Standard linked list removal algorithm */
{
if (temp == users) /* Remove head item */
{
users = temp->next;
[temp->windowPointer free];
free(temp);
temp = users->next;
}
if (temp == last) /* Remove last item */
{
last = prev;
prev -> next = NULL;
[temp->windowPointer free];
free(temp);
temp = NULL;
}
else /* Remove internal item */
{
prev->next = temp->next;
[temp->windowPointer free];
free(temp);
temp = prev->next;
}
}
else
{
temp->x = 4.0 + 64.0 * (float) nextX; /* Calulate Screen Coordinates */
temp->y = 0.0 + 64.0 * (float) nextY;
/* Reposition icon to new location */
[temp->windowPointer moveTo: temp->x : temp->y];
[[temp->windowPointer contentView] display];
nextY++; /* Calculate next icon position */
if (nextY>13)
{
nextY = 0;
nextX++;
}
prev = temp;
temp = temp->next;
}
}
}
int find(tty,name) /* Return a 1 if record with "name" and "tty" exists in the list */
/* Mark record as referenced so that it is not removed from the list */
char *tty,*name;
{
struct record *temp;
temp = users; /* Head of list */
while(temp!=NULL)
{
if ((strcmp(temp->tty, tty)==0)&&(strcmp(temp->name,name) ==0))
{
temp->marked = 1;
return(1);
}
temp = temp->next;
}
return(0);
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.