grotwin (Part 5 of 7)
nwh at hrc63.UUCP
nwh at hrc63.UUCP
Sat Jul 12 00:08:18 AEST 1986
#! /bin/sh
# This is a shell archive. To extract the files type 'sh file'
# This archive created on Thu Jul 10 16:38:07 WET 1986
echo 'shar: extracting 'update.c' ( 9169 characters)'
if test -f 'update.c'
then
echo "shar: will not overwrite existing file 'update.c'"
else
cat << \SHAR_EOF > 'update.c'
#ifndef lint
static char sccsid[] = "@(#)update.c 2.2 [ (C) Nigel Holder 1986 ]";
#endif
/***************************************
*
* Author : Nigel Holder
*
* Date : 10 July 1986
*
*
* Copyright (C) 1986 by Nigel Holder
*
* Permission to use this program is granted, provided it is not
* sold, or distributed for direct commercial advantage, and includes
* the copyright notice and this clause.
*
* Grotwin - provides a somewhat primitive windowing capability
* for people unfortunate enough to use the standard 24 x 80 type
* of terminal when the console is in use. Definitely written for
* 4.[2,3] at the present time, as Sys V.2 does not cater for pseudo
* terminals or have the select() facility (amongst other things !)
* (version 8 should fix this).
*
* Files used :-
*
* grotwin.c - window system initialisation
* deals with startup files
*
* manager.c - window manager
* deals with input and output
*
* window.c - window manipulator
* deals with aspects concerning windows
* during normal usage
*
* update.c - simulates dumb terminal for use
* with window manager.
*
* grotwin.h - header file for above
*
* utmp.c - utmp manipulator
* updates utmp entries for each window
*
* grotwin.make - makefile for above
*
* Bugs :-
*
* Can't have the situation where no windows are present !
* Needs a vt100 like terminal type
*
***************************************/
#include "grotwin.h"
/* defines specific to grotty terminal type (see term and termcap below) */
#define INSERT_LINE ( 0x01 )
#define DELETE_LINE ( 0x02 )
#define STANDOUT ( 0x05 )
#define STANDEND ( 0x06 )
#define BELL ( 0x07 )
#define BACKSPACE ( 0x08 )
#define TAB ( 0x09 )
#define CURSOR_DOWN ( 0x0A )
#define CURSOR_UP ( 0x0B )
#define CLEAR_SCREEN ( 0x0C )
#define NONDESTRUCT_SPACE ( 0x18 )
#define DELETE_TO_EOL ( 0x19 )
#define CURSOR_ADDR ( 0x1B )
#define TABS ( 0x08 )
#define SPECIAL '\0'
extern struct windowdetails win[MAX_WINDOWS_PLUS];
extern int **screen_priority;
extern char **masterscreen;
/*******************
*
* My very own terminal type. Loosely based on a adm3a and Newbury 8000
* Used in grotwin.c but defined here since this module handles terminal
* escape sequences. Although a vt100 definition would probably be better,
* this simple terminal type generally uses less I/O to achieve the same
* goals (ie. cursor movement), at the cost of programs that use
* vt100 escape sequences without looking at TERMCAP.
*
* Termcap entry should also be placed in in /etc/termcap as well.
*
*******************/
char term[] = "TERM=grotty";
char termcap[] = "TERMCAP=gr|grotty|grotwin pseudo tty:\
co#%d:li#%d:cl=\^L:cm=\\E=%%+ %%+ :am:bs:nd=\^X:ce=\^Y:\
up=\^K:do=\^J:kb=\^H:so=\^E:se=\^F:al=\^A:dl=\^B:";
/* updates specified window with string */
update_screen(winno)
int winno;
{
register struct windowdetails *ptr;
register int x, y;
int length, temp;
char *strcpy(), *string;
ptr = &(win[winno]);
if (ptr->paged_page_full || ptr->output_blocked) { /* can't o/p */
return;
}
string = ptr->page_buf;
length = ptr->page_buf_length;
while (length-- > 0) {
*string &= 0x7F; /* strip off top most bit */
if (ptr->cursor_addressing) {
temp = *string++;
/* check for cursor addressing */
if (++(ptr->cursor_addr_passes) == 1) {
if (temp != '=') {
ptr->cursor_addressing = FALSE;
ptr->cursor_addr_passes = 0;
mywaddch(winno, CURSOR_ADDR);
mywaddch(winno, temp);
continue;
}
}
else {
if (ptr->cursor_addr_passes == 2) {
ptr->cursor_addr_row = temp - ' ';
if (ptr->cursor_addr_row >= ptr->lines){
ptr->cursor_addr_row =
ptr->lines - 1;
}
else {
if (ptr->cursor_addr_row < 0) {
ptr->cursor_addr_row =0;
}
}
}
else {
/* move it */
ptr->y_current = ptr->cursor_addr_row;
ptr->x_current = temp - ' ';
if (ptr->x_current >= ptr->columns) {
ptr->x_current = ptr->columns-1;
}
else {
if (ptr->x_current < 0) {
ptr->x_current = 0;
}
}
ptr->cursor_addressing = FALSE;
ptr->cursor_addr_passes = 0;
}
}
continue;
}
y = ptr->y_current;
x = ptr->x_current;
switch (*string) {
case '\r' :
ptr->x_current = 0;
break;
case '\n' :
if (ptr->output_paged &&
++ptr->line_count >= ptr->lines) {
ptr->paged_page_full = TRUE;
ptr->line_count = 0;
/* remember rest of output */
strcpy(ptr->page_buf, string);
ptr->page_buf_length = length + 1;
return;
}
if (y >= (ptr->y_end - ptr->y_start - 1)) {
ptr->y_current = 0;
if (! ptr->overwrite) {
mywlineop(winno, DELETE_LINE);
ptr->y_current = y;
}
}
else {
++ptr->y_current;
}
if (ptr->overwrite) {
mywline_clear(winno,
ptr->y_current + ptr->y_start);
}
break;
case CURSOR_UP :
if (y > 0) {
--y;
}
ptr->y_current = y;
break;
case CLEAR_SCREEN :
mywclear(winno);
break;
case CURSOR_ADDR :
ptr->cursor_addressing = TRUE;
break;
case TAB :
x = x + TABS - (x % TABS);
if (x > ptr->columns - 1) {
x = ptr->columns - 1;
}
ptr->x_current = x;
break;
case BACKSPACE :
if (x > 0) {
--ptr->x_current;
}
break;
case STANDOUT :
ptr->standout_mode = WIN_STANDOUT;
break;
case STANDEND :
ptr->standout_mode = WIN_STANDEND;
break;
case BELL :
write(1, "\007", 1);
break;
case NONDESTRUCT_SPACE :
if (x < ptr->columns - 1) {
++x;
}
else {
ptr->y_current = ++y;
x = 0;
}
ptr->x_current = x;
break;
case INSERT_LINE :
mywlineop(winno, INSERT_LINE);
break;
case DELETE_LINE :
mywlineop(winno, DELETE_LINE);
break;
case DELETE_TO_EOL :
temp = x;
while (temp++ < ptr->columns) {
mywaddch(winno, ' ');
}
ptr->x_current = x;
break;
case SPECIAL :
break;
default :
mywaddch(winno, *string);
if (x >= ptr->columns - 1) {
/* insert \r\n into string */
length = string_insert(string + 1,
"\r\n");
}
break;
}
++string;
}
ptr->page_buf_length = 0;
}
/* insert s2 at beginning of s1 after shifting s2 to make room */
/* returns length of new string */
static
string_insert(s1, s2)
char *s1, *s2;
{
register char *src_ptr, *dest_ptr;
register int i;
int n1, n2;
n1 = strlen(s1);
n2 = strlen(s2);
src_ptr = s1 + n1;
dest_ptr = src_ptr + n2;
/* include string delimiter */
i = n1 + 1;
while (i--) {
*dest_ptr-- = *src_ptr--;
}
i = n2;
while (i--) {
*s1++ = *s2++;
}
return(n1 + n2);
}
static
mywaddch(winno, c) /* add char to window */
int winno;
char c;
{
register struct windowdetails *ptr;
register int x, y;
ptr = &(win[winno]);
x = ptr->x_current + ptr->x_start;
y = ptr->y_current + ptr->y_start;
c |= ptr->standout_mode;
ptr->screenptr[y][x] = c;
if (screen_priority[y][x] == winno) {
masterscreen[y][x] = c;
}
++ptr->x_current;
}
static
mywlineop(winno, command) /* insert - delete a line on the screen */
int winno, command;
{
register struct windowdetails *ptr;
register int x, *line_priority;
register char *image, *screenline;
int y, y_actual_current;
char *temp;
ptr = &(win[winno]);
y_actual_current = ptr->y_current + ptr->y_start;
/* move lines around */
if (command == DELETE_LINE) {
temp = ptr->screenptr[y_actual_current];
for (y = y_actual_current ; y < ptr->y_end - 1 ; ++y) {
ptr->screenptr[y] = ptr->screenptr[y + 1];
}
ptr->screenptr[ptr->y_end - 1] = temp;
mywline_clear(winno, ptr->y_end - 1);
}
else { /* INSERT_LINE */
temp = ptr->screenptr[ptr->y_end - 1];
for (y = ptr->y_end - 1 ; y > y_actual_current ; --y) {
ptr->screenptr[y] = ptr->screenptr[y - 1];
}
ptr->screenptr[y_actual_current] = temp;
mywline_clear(winno, y_actual_current);
}
/* update real screen */
for (y = y_actual_current ; y < ptr->y_end ; ++y) {
line_priority = screen_priority[y];
screenline = masterscreen[y];
image = ptr->screenptr[y];
for (x = ptr->x_start ; x < ptr->x_end ; ++x) {
if (line_priority[x] == winno) {
screenline[x] = image[x];
}
}
}
}
static
mywline_clear(winno, line)
int winno, line;
{
register struct windowdetails *ptr;
register int x, *line_priority;
register char *lineptr, *masterline;
ptr = &(win[winno]);
lineptr = ptr->screenptr[line];
line_priority = screen_priority[line];
masterline = masterscreen[line];
for (x = ptr->x_start ; x < ptr->x_end ; ++x) {
lineptr[x] = ' ';
if (line_priority[x] == winno) {
masterline[x] = ' ';
}
}
}
mywclear(winno) /* clear window */
int winno;
{
struct windowdetails *ptr;
int y;
ptr = &(win[winno]);
for (y = ptr->y_start ; y < ptr->y_end ; ++y) {
mywline_clear(winno, y);
}
ptr->y_current = 0;
ptr->x_current = 0;
ptr->line_count = 0;
}
SHAR_EOF
if test 9169 -ne `wc -c < 'update.c'`
then
echo 'shar: error transmitting 'update.c' (should have been 9169 charcaters)'
fi
fi
echo 'shar: extracting 'utmp.c' ( 3641 characters)'
if test -f 'utmp.c'
then
echo "shar: will not overwrite existing file 'utmp.c'"
else
cat << \SHAR_EOF > 'utmp.c'
#ifndef lint
static char sccsid[] = "@(#)utmp.c 2.2 [ (C) Nigel Holder 1986 ]";
#endif
/**************************************
*
* Author : Nigel Holder
*
* Date : 10 July 1986
*
*
* Copyright (C) 1986 by Nigel Holder
*
* Permission to use this program is granted, provided it is not
* sold, or distributed for direct commercial advantage, and includes
* the copyright notice and this clause.
*
* This program attempts to overcome the deficiences of 4.2 not
* having any visible routines to update the utmp file like Sys V.
* Utmp is used by utilities such as who to find out who is
* logged on. On Sun 4.2, /etc/utmp can be written by
* anyone, so no setuid etc. is required to alter it.
*
* Accessed only via utmp_insert(tty, id) and utmp_delete(tty)
* to enable routines to be kept internal. Uses host field
* to indicate that pseudo tty is being used by grotwin (I know its
* not what the field is meant for, but it looks better all the same).
*
* Getpwent() appears to hunk in approx 30 K of unnecessary code
* to deal with remote hosts etc.
*
**************************************/
#include <stdio.h>
#include <utmp.h>
#include <pwd.h>
#define UTMP_INSERT ( 1 )
#define UTMP_DELETE ( 2 )
/* max length of tty name entry in /etc/ttys file */
#define TTYS_MAXLEN ( 20 )
typedef enum { FALSE, TRUE } bool;
utmp_insert(tty, id) /* add entry to utmp */
char *tty, *id;
{
return(utmp_update(tty, id, UTMP_INSERT));
}
utmp_delete(tty) /* delete entry from utmp */
char *tty;
{
return(utmp_update(tty, "", UTMP_DELETE));
}
static
utmp_update(tty, id, mode) /* update utmp file */
char *tty, *id;
int mode;
{
static char utmp[] = "/etc/utmp";
struct utmp entry;
struct passwd *getpwuid(), *passwd_entry;
FILE *fp, *fopen();
long *time();
int position, i;
char *getlogin(), *user_name;
position = utmp_pos(tty);
if (position == -1) {
return(-1);
}
if ((fp = fopen(utmp, "r+")) == NULL) {
return(-1);
}
if (mode == UTMP_INSERT) { /* try to find user */
if ((user_name = getlogin()) == NULL) {
if ((passwd_entry = getpwuid(getuid())) == NULL) {
return(-1); /* give up */
}
user_name = passwd_entry->pw_name;
}
/*******************
* In case strings are too long to fit utmp structure,
* copy max - 1 chars and null terminate at end.
*******************/
strncpy(entry.ut_name, user_name, sizeof(entry.ut_name) - 1);
entry.ut_host[sizeof(entry.ut_name) - 1] = '\0';
strncpy(entry.ut_host, id, sizeof(entry.ut_host) - 1);
entry.ut_host[sizeof(entry.ut_host) - 1] = '\0';
}
else { /* UTMP_DELETE */
for (i = 0 ; i < sizeof(entry.ut_name) ; ++i) {
entry.ut_name[i] = '\0';
}
for (i = 0 ; i < sizeof(entry.ut_host) ; ++i) {
entry.ut_host[i] = '\0';
}
}
strncpy(entry.ut_line, tty, sizeof(entry.ut_line) - 1);
entry.ut_line[sizeof(entry.ut_host) - 1] = '\0';
(void) time(&(entry.ut_time));
if (fseek(fp, (long) (sizeof(entry) * position), 0) != -1) {
(void) fwrite(&entry, sizeof(entry), 1, fp);
}
(void) fclose(fp);
return(position);
}
utmp_pos(tty) /* like ttyslot */
char *tty;
{
static char ttys[] = "/etc/ttys";
FILE *fp, *fopen();
int position;
bool found;
char temp[TTYS_MAXLEN];
if ((fp = fopen(ttys, "r")) == NULL) {
return(-1);
}
found = FALSE;
for (position = 1 ; fgets(temp, TTYS_MAXLEN, fp) != NULL ; ++position) {
temp[strlen(temp) - 1] = '\0'; /* remove trailing \n */
if (strcmp(temp + 2, tty) == 0) {
found = TRUE;
break;
}
}
(void) fclose(fp);
if (found == FALSE) {
return(-1);
}
return(position);
}
SHAR_EOF
if test 3641 -ne `wc -c < 'utmp.c'`
then
echo 'shar: error transmitting 'utmp.c' (should have been 3641 charcaters)'
fi
fi
exit
Nigel Holder UK JANET: yf21 at uk.co.gec-mrc.u
Marconi Research, ARPA: yf21%u.gec-mrc.co.uk at ucl-cs
Chelmsford,
Essex. CM2 8HN.
+44 245 73331 ext. 3219 / 3214
More information about the Comp.sources.unix
mailing list