[comp.sources.unix] v17i032: MGR, Bellcore window manager, Part31/61

rsalz@uunet.uu.net (Rich Salz) (01/26/89)

Submitted-by: Stephen A. Uhler <sau@bellcore.com>
Posting-number: Volume 17, Issue 32
Archive-name: mgr/part31




#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 31 (of 61)."
# Contents:  demo/icon/iconmsgs.c demo/misc/getpty.c demo/misc/stat.c
#   doc/usrman/doc.5 src/startup.c
# Wrapped by rsalz@papaya.bbn.com on Thu Nov 17 21:05:38 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'demo/icon/iconmsgs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'demo/icon/iconmsgs.c'\"
else
echo shar: Extracting \"'demo/icon/iconmsgs.c'\" \(9313 characters\)
sed "s/^X//" >'demo/icon/iconmsgs.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: iconmsgs.c,v 4.1 88/06/21 13:59:58 bianchi Exp $
X	$Source: /tmp/mgrsrc/demo/icon/RCS/iconmsgs.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/demo/icon/RCS/iconmsgs.c,v $$Revision: 4.1 $";
X
X/* check for new messages */
X/* icon version */
X
X#include <stdio.h>
X#include <signal.h>
X#include <sgtty.h>
X#include "term.h"
X#include "msgs_icons.h"
X
X#define Isflag(arg,flag)	(!strncmp(arg,flag,strlen(flag)))
X#define Max(x,y)		((x)>(y)?(x):(y))
X#define MENU_COUNT	(sizeof(menu)/sizeof(struct menu_entry))
X#define SCMP(x,y)	(strcmp(x+(strlen(x)-strlen(y)),y)==0)
X
Xstatic char	MSG_reading[] = "\freading msgs ...\r";
Xstatic char	MSG_done[] = "\rdone? [?,-,!]";
Xstatic char	MSG_help[] = "\r\
XAvailable commands:\r\n\
X ?*          this message\r\n\
X -           return to most recently seen message\r\n\
X -<number>   skip back <number> messages\r\n\
X !<cmd>      escape to the shell and issue <cmd>\r\n\
X <anything>  exit\r\n";
X
X#define W_WIDE		80		/* character width of msgs window */
X#define W_HIGH		24		/* character height of msgs window */
X
X#define MSGSCMD	"msgs -p"
X#define BOUNDS	"/usr/msgs/bounds"
X#define RC	".msgsrc"
X#define POLL	 30				/* polling interval */
X#define XPOS	220				/* start of msgs window */
X#define YPOS	170				/* start of msgs window */
X#define MAX	50				/* max number of messages */
X
X#define MSGS()	(1 + get_bounds(bounds) - get_rc(rc))
X#define dprintf	if(debug) fprintf
X
Xstatic FILE	*bounds, *rc;		/* pntrs to bounds and rc files */
Xstatic int	msg_cnt, old_msg_cnt=0;	/* # of messages */
Xstatic char	line[MAXLINE];		/* input buffer */
Xstatic int	poll=POLL;		/* poll interval */
X
Xstatic struct menu_entry menu[] = {
X   "yes",    "y\r",
X   "skip",   "n\r",
X   "again",  "-\r",
X   "save",   "s\r",
X   "quit",   "q\r",
X   };
X
Xstatic int	x, y, w, h;	/* window location, width and height */
Xstatic int	border;		/* size of border */
Xstatic int	debug = 0;	/* debug printout flag */
Xstatic int	local=0;	/* use local machine for icons */
Xstatic int	cwide, chigh;	/* width and height of font characters. */
Xstatic char	*termcap;
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X   {
X   register int i;
X   int xpos = XPOS;
X   int ypos = YPOS;
X   int font = -1;
X   int shape = 1;
X
X   char *getenv();
X   char *home = getenv("HOME");
X   int clean(), update();
X
X   /* make sure we have a valid environment to run in */
X
X   ckmgrterm( *argv );
X
X   if (home==NULL || *home=='\0') {
X      fprintf(stderr,"%s: Can't find your home directory\n",argv[0]);
X      exit(1);
X      }
X
X   if ((bounds = fopen(BOUNDS,"r")) == NULL) {
X      fprintf(stderr,"%s: Can't find a bounds file\n",argv[0]);
X      exit(2);
X      }
X
X   sprintf(line,"%s/%s",home,RC);
X   
X   if ((rc = fopen(line,"r")) == NULL) {
X      fprintf(stderr,"%s: Can't find %s\n",argv[0],line);
X      exit(3);
X      }
X
X   /* process arguments */
X
X   for(i=1;i<argc;i++) {
X      if (Isflag(argv[i],"-s"))
X         shape = 0;
X      else if (Isflag(argv[i],"-x"))
X         xpos = atoi(argv[i]+2);
X      else if (Isflag(argv[i],"-y"))
X         ypos = atoi(argv[i]+2);
X      else if (Isflag(argv[i],"-f"))
X         font = atoi(argv[i]+2);
X      else if (Isflag(argv[i],"-p"))
X         poll  = Max(atoi(argv[i]+2),10);
X      else if (Isflag(argv[i],"-d"))
X         debug=1;
X      else if (Isflag(argv[i],"-l"))
X         local=1;
X      else
X         usage(argv[0],argv[i]);
X      }
X
X   /* setup mgr stuff */
X
X   m_setup(M_FLUSH);
X   m_push(P_BITMAP|P_MENU|P_EVENT|P_FONT|P_FLAGS|P_POSITION);
X   if (font < 0)
X	font = 0;
X   m_font(font);
X   get_font( &cwide, &chigh );
X
X   signal(SIGHUP,clean);
X   signal(SIGTERM,clean);
X   signal(SIGINT,clean);
X   signal(SIGALRM,update);
X
X   m_ttyset();
X   m_setmode(M_NOWRAP);
X   m_setmode(M_ABS);
X   m_func(B_COPY);
X
X   download_icon(&msg_board,1);
X   download_icon(&msg_note,2);
X   download_icon(&msg_read,3);
X   download_icon(&msg_none,4);
X
X   get_size(&x,&y,&w,&h);
X   get_param(0,0,0,&border);
X   m_movecursor(x+30,0);
X
X   old_msg_cnt = MSGS();
X   if (shape && !debug) {
X      m_shapewindow(x,y,2*border+msg_board.w,2*border+msg_board.h);
X      }
X   else if (debug)
X      fprintf(stderr,"would shape (%d,%d) + %d\r\n",
X               msg_board.w, msg_board.h, 2*border);
X   m_setevent(REDRAW,"R\r");
X   m_setevent(ACTIVATED,"A\r");
X   update(0);
X   m_clearmode(M_ACTIVATE);
X
X   termcap = getenv("TERMCAP");
X   if( termcap )
X      *termcap = '\0';
X
X   while(1) {
X      if( m_gets(line) == NULL ) {
X	 clearerr(m_termin);
X	 continue;
X      }
X      alarm(0);
X
X      /* read msgs */
X
X      old_msg_cnt = msg_cnt;
X      msg_cnt = MSGS();
X      if (msg_cnt > 0 && *line == 'A') {
X         do_msgs(MSGSCMD,font,xpos,ypos);
X         }
X
X      /* wait for window to deactivate */
X
X      else if (*line == 'A') {
X         set_icon(msg_none,0,0);
X         sleep(2);
X         }
X      m_clearmode(M_ACTIVATE);
X      update(0);
X      }
X   }
X    
Xint
Xget_rc(file)
XFILE *file;
X   {
X   char line[100], *fgets();
X   fseek(file,0,0);
X   if (fgets(line,sizeof(line),file) != NULL) 
X      return(atoi(line));
X   else
X      return(0);
X   }
X
Xint
Xget_bounds(file)
XFILE *file;
X   {
X   char buff[100], *line, *fgets();
X   fseek(file,0,0);
X   if ((line=fgets(buff,sizeof(buff),file)) != NULL) {
X      while(*line != ' ') line++;
X      while(*line == ' ') line++;
X      return(atoi(line));
X      }
X   else return(0);
X   }
X
Xclean(n)
Xint n;
X   {
X   m_ttyreset();
X   m_selectwin(0);
X   m_popall();
X   exit(n);
X   }
X
Xupdate(flag)
Xint flag;
X   {
X   alarm(0);
X   msg_cnt = MSGS();
X   if (msg_cnt != old_msg_cnt || flag==0) {
X      if (msg_cnt > old_msg_cnt) 		/* new messages */
X         m_printstr("\007");
X      draw(msg_cnt,old_msg_cnt,flag==0);
X      }
X   old_msg_cnt = msg_cnt;
X   alarm(poll);
X   }
X
Xusage(name,error)
Xchar *name, *error;
X{
X	fprintf(stderr,"Invalid argument: %s\n",error);
X	fprintf(stderr,"usage: %s -[s|x<pos>|y<pos>|f<font>|p<poll>\n",name);
X	exit(1);
X}
X
X/* down load an icon */
X
Xdownload_icon(icon,where)
Xregister struct icon *icon;	/* name of icon to download */
Xint where;			/* bitmap to download icon to */
X   {
X   static int local_mode = -1;
X   int size;
X   int w_in=0, h_in=0;
X
X   /* first try the local machine */
X
X   if (!local) {
X      dprintf(stderr, "looking for %s\n", icon->name);
X      m_bitfile(where, icon->name , &w_in, &h_in);
X      }
X
X   if (h_in==0 || w_in==0) {	/* can't find icon */
X      dprintf(stderr,"Couldn't find %s, downloading\n",icon->name);
X      if (local_mode == -1)
X         ioctl(fileno(m_termout),TIOCLGET,&local_mode);
X      local_mode |= LLITOUT;
X      ioctl(fileno(m_termout),TIOCLSET,&local_mode);
X
X      size = icon->h * (((icon->w+15)&~15)>>3);
X      m_bitldto(icon->w,icon->h,0,0,where,size);
X      m_flush();
X      write(fileno(m_termout),icon->data,size);
X      local_mode &= ~LLITOUT;
X      ioctl(fileno(m_termout),TIOCLSET,&local_mode);
X      }
X   else {
X      dprintf(stderr,"Found %s (%d x %d) expected %d x %d\n",
X               icon->name,w_in,h_in,icon->w,icon->h);
X      icon->w = w_in;
X      icon->h = h_in;
X      }
X   icon->type = where;
X   } 
X
X#define Rand(min,max)	((min) + random()%((max)-(min)))
X#define MAXNOTES	100		/* enough to make the message board
X					look filled, but not take too long
X					to draw when there are hundreds of
X					messages. */
X
Xdraw(new,old,redraw)
Xint new,old;				/* number of messages */
Xint redraw;
X   {
X   register int i;
X   long random();
X
X   dprintf(stderr,"draw %d -> %d (redraw=%d)\n",old,new,redraw);
X
X   if (redraw || new<old)
X      set_icon(msg_board,0,0);
X
X   if (new>old)
X      new -= old;
X
X   for(i=0;  i<new && i<MAXNOTES;  i++) {
X      set_icon( msg_note, Rand(0, msg_board.w-msg_note.w),
X		Rand(12, msg_board.w-msg_note.h) );
X      }
X   }
X   
Xset_icon(name,x0,y0)
Xstruct icon name;		/* name of icon */
Xint x0,y0;			/* where it goes */
X   {
X   m_bitcopyto(x0,y0,name.w,name.h,0,0,0,name.type);
X   m_flush();
X   }
X   
X/* run msgs in a subwindow */
X
Xdo_msgs(command,font,xpos,ypos)
Xchar *command;
Xint font,xpos,ypos;
X	{
X	int n;
X
X	alarm(0);
X	m_push(P_EVENT | P_FONT);
X	n = m_makewindow(xpos, ypos, W_WIDE*cwide + 2*border,
X		W_HIGH*chigh + 2*border );
X	if (n==0) {	/* can't make window */
X		m_printstr("\007\fCan't open msgs window, sorry");
X		m_pop();
X		return(0);
X		}
X  	set_icon(msg_read, 0, 0);
X	m_selectwin(n);
X	m_font(font);
X	menu_load(1,MENU_COUNT,menu);
X	m_selectmenu(1);
X	m_printstr(MSG_reading);
X	m_ttyreset();
X	system(command);
X	m_printstr(MSG_done);
X        while( m_gets(line) != NULL ) {
X		switch( *line ) {
X		case '?':
X			m_printstr(MSG_help);
X			break;
X		case '!':	/* shell escape */
X			system( &line[1] );
X			break;
X		case '-': {	/* go back; -N goes back N messages */
X				char	buf[ 2*MAXLINE ];
X				if( line[1] == '\n' )
X					strcpy( line, "-1" );
X				sprintf( buf, "%s %s", command, line );
X				system( buf );
X			}
X			break;
X		default:
X			goto nomore;
X		}
X		m_printstr(MSG_done);
X	}
X	clearerr(m_termin);
X    nomore:
X	m_ttyset();
X	m_selectwin(0);
X	m_destroywin(n);
X	m_pop();
X	m_clearmode(M_ACTIVATE);
X	}
END_OF_FILE
# end of 'demo/icon/iconmsgs.c'
fi
if test -f 'demo/misc/getpty.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'demo/misc/getpty.c'\"
else
echo shar: Extracting \"'demo/misc/getpty.c'\" \(9479 characters\)
sed "s/^X//" >'demo/misc/getpty.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X#ifndef lint
Xstatic char rcsid[] = "$Header: getpty.c,v 4.2 88/06/22 14:37:33 bianchi Exp $";
X#endif
X#include <sys/types.h>
X#include <sys/wait.h>
X
X#include <sys/file.h>
X#include <sys/signal.h>
X#include <sgtty.h>
X#include <stdio.h>
X
X#include <errno.h>
X#include <pwd.h>
X
X/*
X**	size of input and output buffers
X*/
X#define BFRSIZE		1024
X
Xextern	int errno;
Xextern  int done();
Xint	lostpeer();
Xint shellid;
Xint	rem;
Xint verboseflag = 0;
Xint	defflags, tabflag;
Xchar	deferase, defkill;
Xstruct	tchars deftc;
Xstruct	ltchars defltc;
Xstruct	tchars notc =	{ -1, -1, -1, -1, -1, -1 };
Xstruct	ltchars noltc =	{ -1, -1, -1, -1, -1, -1 };
X
X/*
X** flags to signal that massage routines have more data ready to go
X**	these flags are necessary so that massage routines can buffer
X**	data if necessary
X*/
Xint more_out = 0;
Xint more_in = 0;
Xgetpty(cmd)
X	char **cmd;
X{
X	int exit();
X	struct sgttyb sb;
X	char pibuf[BFRSIZE], fibuf[BFRSIZE], *pbp, *fbp;
X	int pcc = 0, fcc = 0;
X	int cc;
X
X	signal(SIGPIPE, lostpeer);
X        shellid = get_command(cmd,&rem);
X        if (rem < 0)
X                return(-1);
X
X	ioctl(0, TIOCGETP, (char *)&sb);
X	defflags = sb.sg_flags;
X	tabflag = defflags & TBDELAY;
X	defflags &= ECHO | CRMOD;
X	deferase = sb.sg_erase;
X	defkill = sb.sg_kill;
X	ioctl(0, TIOCGETC, (char *)&deftc);
X	notc.t_startc = deftc.t_startc;
X	notc.t_stopc = deftc.t_stopc;
X	ioctl(0, TIOCGLTC, (char *)&defltc);
X	signal(SIGINT, exit);
X	signal(SIGHUP, exit);
X	signal(SIGQUIT, exit);
X	mode(1);
X	signal(SIGINT, SIG_IGN);
X	signal(SIGCHLD, done);
X	for (;;)
X	{
X		int ibits = 0, obits = 0;
X
X		if (fcc)
X			obits |= (1<<rem);
X		else
X			ibits |= (1<<0);
X		if (pcc >= 0)
X			if (pcc)
X				obits |= (1<<1);
X			else
X				ibits |= (1<<rem);
X		if (fcc < 0 && pcc < 0)
X			break;
X		select(16, &ibits, &obits, 0, 0, 0);
X		if (ibits == 0 && obits == 0) {
X			sleep(5);
X			continue;
X		}
X		if ((fcc == 0) && more_in)
X		{
X			fbp = fibuf;
X			fcc = inmassage(fibuf,-2);
X		}
X		else
X		{
X			if (ibits & (1<<0)) {
X				fcc = read(0, fibuf, sizeof (fibuf));
X				if (fcc < 0 && errno == EWOULDBLOCK)
X					fcc = 0;
X				else {
X					if (fcc <= 0)
X						break;
X					fbp = fibuf;
X					fcc = inmassage(fibuf,fcc);
X				}
X			}
X		}
X		if ((pcc == 0) && more_out)
X		{
X			pbp = pibuf;
X			pcc = outmassage(pibuf,-2);
X		}
X		else
X		{
X			if (ibits & (1<<rem)) {
X				pcc = read(rem, pibuf, sizeof (pibuf));
X				pbp = pibuf;
X				if (pcc < 0 && errno == EWOULDBLOCK)
X					pcc = 0;
X				else if (pcc <= 0)
X					pcc = -1;
X				pcc = outmassage(pibuf,pcc);
X			}
X		}
X		if ((obits & (1<<1)) && pcc > 0) {
X			cc = write(1, pbp, pcc);
X			if (cc > 0) {
X				pcc -= cc;
X				pbp += cc;
X			}
X		}
X		if ((obits & (1<<rem)) && fcc > 0) {
X			cc = write(rem, fbp, fcc);
X			if (cc > 0) {
X				fcc -= cc;
X				fbp += cc;
X			}
X		}
X	}
X	fprintf(stderr,"Closed connection.\r\n");
X	done();
X	/* this point should never be reached !!! */
X	return(-2);
X}
X
Xdone()
X{
X
X	mode(0);
X	if (shellid > 0 && kill(shellid, SIGKILL) >= 0)
X		wait((int *)0);
X	cleanup();
X}
X
X
X/*
X * writer: write to remote: 0 -> line.
X */
Xwriter()
X{
X	int c;
X	while (read(0,&c,1) != 0)
X	{
X		if (write(rem, &c, 1) == 0) {
X			fprintf(stderr,"line gone\r\n");
X			return(0);
X		}
X	}
X}
X
X/*
X * reader: read from remote: line -> 1
X */
Xreader()
X{
X	char rb[BUFSIZ];
X	register int cnt;
X
X	for (;;) {
X		cnt = read(rem, rb, sizeof (rb));
X		if (cnt == 0)
X			break;
X		if (cnt < 0) {
X			if (errno == EINTR)
X				continue;
X			break;
X		}
X		write(1, rb, cnt);
X	}
X}
X
Xmode(f)
X{
X	struct tchars *tc;
X	struct ltchars *ltc;
X	struct sgttyb sb;
X
X	ioctl(0, TIOCGETP, (char *)&sb);
X	switch (f) {
X
X	case 0:
X		sb.sg_flags &= ~(CBREAK|RAW|TBDELAY);
X		sb.sg_flags |= defflags|tabflag;
X		tc = &deftc;
X		ltc = &defltc;
X		sb.sg_kill = defkill;
X		sb.sg_erase = deferase;
X		break;
X
X	case 1:
X		sb.sg_flags |=  RAW;
X/*
X		sb.sg_flags |= (eight ? RAW : CBREAK);
X*/
X		sb.sg_flags &= ~defflags;
X		/* preserve tab delays, but turn off XTABS */
X		if ((sb.sg_flags & TBDELAY) == XTABS)
X			sb.sg_flags &= ~TBDELAY;
X		tc = &notc;
X		ltc = &noltc;
X		sb.sg_kill = sb.sg_erase = -1;
X		break;
X
X	default:
X		return;
X	}
X	ioctl(0, TIOCSLTC, (char *)ltc);
X	ioctl(0, TIOCSETC, (char *)tc);
X	ioctl(0, TIOCSETN, (char *)&sb);
X}
X
X
Xlostpeer()
X{
X	signal(SIGPIPE, SIG_IGN);
X	fprintf(stderr,"\007Connection closed.\r\n");
X	done();
X}
X
X
X#define SHELL		"/bin/sh"
X
X#ifdef SYSV
X#define index		strchr
X#endif
X
Xstatic char *line = "/dev/ptypX";
Xstatic int  pty_index=5;	/* better hit rate than 0 */
Xextern char **environ;
X
X/* place to save tty modes */
X
Xint t_ldisc;
Xstruct sgttyb t_sgttyb;
Xstruct tchars t_tchars;
Xstruct ltchars t_ltchars;
Xint t_lflags;
X/*	get a pty line */
X
Xint
Xgetapty()
X   {
X   register int i;
X   int fd;
X   char list[20];
X
X   strcpy(list,"0123456789abcdef");
X   line[5] = 'p';
X/*
X   for(line[8]='p';line[8]!='r';line[8]='q')
X*/
X   for(line[8]='p';line[8]!='r';line[8]++)
X      for (i=1;i<=16;i++) {
X         line[9]=list[(pty_index+i)%16];
X	 if (verboseflag)
X	 {
X		printf("trying %s\n",line);
X	 }
X         if ((fd = open(line,2)) >= 0) {
X            /* pty_index = (pty_index+i)%16; */
X	    if (verboseflag)
X	    {
X		printf("   GOT %s\n",line);
X	    }
X            line[5] = 't';
X            return(fd);
X            }
X         }
X   return(-1);
X   }
X      
Xint getatty()
X   {
X   int fd;
X   line[5]='t';
X   fd=open(line,2);
X   if (fd<0) {
X      sleep(3);
X      return (open(line,2));
X      }
X   return(fd);
X   }
X
Xchar *
Xlast_tty()
X   {
X   return(line);
X   }
X
X/******************************************************************************/
X/* start a command */
X
Xget_command(argv,file)
Xchar **argv;
Xint *file;
X   {
X   register int i;				/* counter */
X   int fd;					/* file desc */
X   int tty;					/* fd of /dev/tty */
X   int pid;					/* pid of shell */
X   int group;					/* process group id */
X   int tty_slots;				/* # of tty slots */
X   char *name, *get_path();
X   char *getenv();
X   char *shell = getenv("SHELL");
X   char *arg[2];
X#define MAXNAME 256
X   char who[MAXNAME];
X
X   if (argv == (char **) 0 ) {
X      argv = arg;
X      *argv = shell?shell:SHELL;
X      *(argv+1) = (char *) 0;
X      }
X   name = get_path(argv[0]);
X
X   if (name == (char *) 0 || *name == '\0')
X      return(-2);
X
X#ifdef DEBUG
X   dprintf(stderr,"EXECING: ");
X   for(i=0;argv[i]!='\0';i++)
X      dprintf(stderr,"%s ",argv[i]);
X   dprintf("\n");
X#endif
X
X   if ((*file=getapty()) < 0)
X      return(-1);
X   ioctl(*file,TIOCREMOTE,0);	/* I dunno */
X
X   ioctl(0,TIOCGETD,&t_ldisc);
X   ioctl(0,TIOCGETP,&t_sgttyb);
X   ioctl(0,TIOCGETC,&t_tchars);
X   ioctl(0,TIOCGLTC,&t_ltchars);
X   ioctl(0,TIOCLGET,&t_lflags);
X
X   if ((pid=fork()) != 0) {
X      return(pid);
X      }
X
X   /* void association with controlling terminal */
X
X#ifdef TIOCNOTTY
X   tty = open("/dev/tty",0);
X   ioctl(tty,TIOCNOTTY,0);
X   close(tty);
X#endif
X
X   if ((fd=getatty())<0) {
X	char permsg[256];
X      sprintf(permsg,"Slave side of p-tty %s won't open",line);
X      perror(permsg);
X      sleep(5);
X      exit(1);
X      }
X
X
X   group=getpid();
X
X#ifndef SYSV
X   tty_slots = getdtablesize();
X#else
X   tty_slots = 20;
X#endif
X
X   for(i=0;i<tty_slots;i++) if (i != fd) close(i);
X
X   /* set the uid stuff up */
X
X   if (geteuid() < 2) {
X      int uid = getuid();
X      fchmod(fd,0622);
X      fchown(fd,uid,-1);
X      setreuid(uid,uid);
X
X      uid = getgid();
X      fchown(fd,-1,uid);
X      setregid(uid,uid);
X      }
X
X   dup(fd), dup(fd), dup(fd);
X   close(fd);
X
X   setpgrp(group,group);
X   ioctl(0,TIOCSPGRP,&group);
X
X   t_ldisc=NTTYDISC;
X   t_sgttyb.sg_flags = ECHO|CRMOD|EVENP|ODDP;
X
X   ioctl(0,TIOCSETD,&t_ldisc);
X   ioctl(0,TIOCSETP,&t_sgttyb);
X   ioctl(0,TIOCSETC,&t_tchars);
X   ioctl(0,TIOCSLTC,&t_ltchars);
X   ioctl(0,TIOCLSET,&t_lflags);
X
X   /* add a utmp entry */
X
X/*
X#ifdef WHO
X   add_utmp(0,sprintf(who,"%s%c",HOST,line[9]));
X#endif
X*/
X
X   /* start the command */
X
X#ifdef DEBUG
X   dprintf(stderr,"execing %s (%s ...)\r\n",name,*argv);
X   fflush(stderr);
X#endif
X
X/*
X   do_env("TERM=",TERMNAME);
X   do_env("TERMCAP=","");
X*/
X
X   execve(name,argv,environ);
X   _exit(1);
X   }
X
X/* get a complete path name from command */
X
Xstatic char path[512];
Xstatic char start[512];
X
Xchar *
Xget_path(name)
Xchar *name;
X   {
X   char *getenv(), *index();
X   register char c, *next, *list;
X
X#ifdef DEBUG
X   dprintf(stderr,"looking for command: %s\n",name);
X#endif
X
X   if (index("/.",*name))
X      if (access(name,X_OK)==0)
X         return(name);
X      else
X         return((char *)0);
X
X   strcpy(start,getenv("PATH"));
X   for(list=start;next=index(list,':');list=next+1) {
X      *next = '\0';
X      sprintf(path,"%s/%s",list,name);
X#ifdef DEBUG
X      dprintf(stderr," X? %s\n",path);
X#endif
X      if (access(path,X_OK) == 0)
X         return(path);
X      }
X
X   sprintf(path,"%s/%s",list,name);
X#ifdef DEBUG
X   dprintf(stderr,"X? %s\n",path);
X#endif
X   if (list && access(path,X_OK) == 0) {
X      return(path);
X      }
X   else {
X      return((char *) 0);
X      }
X   }
X
X/* change an environment variable */
X
Xdo_env(name,value)
Xchar *name, *value;
X   {
X   register int i;
X   int n = strlen(name);
X   
X   for(i=0;environ[i] != (char *) 0;i++)
X      if (strncmp(environ[i],name,n) == 0) {
X         strcpy(environ[i]+n,value);
X         break;
X         }
X   }
X
END_OF_FILE
# end of 'demo/misc/getpty.c'
fi
if test -f 'demo/misc/stat.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'demo/misc/stat.c'\"
else
echo shar: Extracting \"'demo/misc/stat.c'\" \(9572 characters\)
sed "s/^X//" >'demo/misc/stat.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: stat.c,v 4.2 88/06/22 14:38:11 bianchi Exp $
X	$Source: /tmp/mgrsrc/demo/misc/RCS/stat.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/demo/misc/RCS/stat.c,v $$Revision: 4.2 $";
X
X/* strip_chart vmstat output version II */
X
X/*
X#define NEWESC	'E' 
X*/
X
X#include "term.h"
X#include <signal.h>
X#include <sgtty.h>
X
X#define MAXTRY	5		/* max number of tries for window parameters */
X
XFILE *popen(), *file;
X
Xstruct data {
X   char *s_title;	/* short label */
X   char *l_title;	/* long label */
X   int index;		/* which item in vmstat */
X   int max;		/* maximum value */
X   };
X
Xstruct data data[] = {
X   "r",		"jobs in run q",	0,	5,
X   "b",		"jobs blocked",		1,	5,
X   "w",		"jobs waiting",		2,	5,
X   "fre",	"free memory",		4,	2000,
X   "fr",	"freed pages",		9,	10,
X   "d1",	"disk 1 accesses",	12,	5,
X   "d2",	"disk 2 accesses",	13,	5,
X   "d3",	"disk 3 accesses",	14,	5,
X   "d4",	"disk 4 accesses",	15,	5,
X   "in",	"interrupts",		16,	60,
X   "sy",	"system calls",		17,	60,
X   "cs",	"context switches",	18,	30,
X   "us",	"% user time",		19,	100,
X   "kn",	"% system time",	20,	100,
X   "id",	"% idle time",		21,	100,
X   "",		"",			-1,	-1
X   };
X
X#define INTERVAL	60	/* bar interval (in secs) */
X#define SCROLL		4	/* # of scrolls per window */
X#define MAX		10	/* max number of plots */
X#define FREQ		3	/* update frequency (secs)*/
X#define DELTA		4	/* pixels/update */
X
X#define Min(x,y)	((x)>(y)?(y):(x))
X#define Max(x,y)	((x)>(y)?(x):(y))
X#define dprintf		if (debug) fprintf
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X   {
X   register int i;
X   register int x;	/* current plot position */
X   int bar=0;		/* hash mark counter */
X   int back=0;		/* enable background writes */
X   int solid=1;		/* make solid lines */
X   int freq = FREQ;	/* update frequency (secs) */
X   int size;		/* size of label region */
X   int interval;	/* hash mark interval (secs) */
X
X   char host[16];	/* hostname */
X   char title[255];	/* chart title */
X   char line[255];	/* vmstat input buffer */
X   char *fields[25];	/* pntrs to vmstat fields */
X   char labels[MAX][100];	/* place for labels */
X   char *sprintf();
X
X   int current[MAX];	/* current data value */
X   int old[MAX];	/* previous data value */
X   int field[MAX];	/* index into 'data' */
X   int first =1;	/* first time through */ 
X   int clean();
X
X   int f_high, f_wide;		/* font size */
X   int high,wide;		/* window size */
X   int x1;			/* left margin */
X   int x2;			/* title */
X   int y1;			/* title line */
X   int y2;			/* first bar */
X   int scroll;			/* scroll amount */
X   int count;			/* number of plots */
X   int delta=DELTA;		/* pixels/line */
X   int item;
X   int max = 0;
X   int dummy;
X   int debug=0;
X
X   ckmgrterm( *argv );
X
X   /* process arguments */
X
X   if (argc<2) {
X      fprintf(stderr,"usage: %s -[i<incr>sbf<freq>] [-max] arg ...\n",argv[0]);
X      fprintf(stderr,"args:\n");
X      for(i=0;data[i].max >=0;i++)
X         fprintf(stderr,"  %s	(%s)\n",data[i].s_title,data[i].l_title);
X      exit(1);
X      }
X
X   for(count=0,i=1;i<argc;i++) {
X      if (strcmp(argv[i],"-d")==0) {
X         debug++;
X         continue;
X         }
X      if (strcmp(argv[i],"-b")==0) {
X         back++;
X         continue;
X         }
X      if (strcmp(argv[i],"-s")==0) {
X         solid=0;
X         continue;
X         }
X      if (strncmp(argv[i],"-f",2)==0) {
X         freq = atoi(argv[i]+2);
X         if (freq < 1) freq = 1;
X         if (freq > 120) freq = 120;
X         continue;
X         }
X      if (strncmp(argv[i],"-i",2)==0) {
X         delta = atoi(argv[i]+2);
X         if (delta < 1) delta = 1;
X         if (freq > 10) delta = 10;
X         continue;
X         }
X      if (*argv[i] == '-') {
X         max = atoi(argv[i]+1);
X         continue;
X         }
X      if ((item = get_item(argv[i],data)) < 0) {
X         fprintf(stderr,"%s:	%s is an invalid item\n",argv[0],argv[i]);
X         continue;
X         }
X      if (max > 0) {
X         data[item].max = max;
X         max = 0;
X         }
X      field[count] = item;
X      sprintf(labels[count],"%s",data[item].l_title);
X      if (++count == MAX)
X         break;
X      }
X
X   if (count < 1) {
X      fprintf(stderr,"%s:	not enough fields\n,argv[0]");
X      exit(5); 
X      }
X
X   if ((file = popen(sprintf(line,"vmstat %d",freq),"r")) == NULL)
X      exit(1);
X
X   m_setup(0);
X   m_ttyset();
X   m_push(P_EVENT|P_FLAGS);
X   m_setmode(M_ABS);
X   if (!back)
X      m_setmode(M_BACKGROUND);
X   else
X      m_clearmode(M_BACKGROUND);
X
X   signal(SIGINT,clean);
X   signal(SIGTERM,clean);
X
X   system("stty -ctlecho");
X   m_setevent(RESHAPE,"R\fRedrawing...\n");
X   m_setevent(REDRAW,"R\fRedrawing...\n");
X   first = 1;
X
X   while (1) {
X
X      for(size=0,i=0;i<count;i++)
X         size = Max(size,strlen(labels[i]));
X
X      /* clear the screen, flush pending input */
X
X      read_it(fileno(m_termin),line);
X
X      /* get font size */
X
X      for(i=0;i<MAXTRY && get_font(&f_wide,&f_high) < 0;i++);
X
X      /* get window size */
X
X      for(i=0;i<MAXTRY && get_size(0,0,&wide,&high) <= 0;i++);
X   
X      if (wide==0 || high==0 || f_wide==0 || f_high==0) {
X         fprintf(stderr,"Can't get window info\n");
X         clean();
X         }
X
X      /* get the title */
X
X      gethostname(host,sizeof(host));
X
X      sprintf(title,"Statistics for %s (%d second intervals)",host,freq);
X
X      if (strlen(title)*f_wide > wide)
X         sprintf(title,"%s (%d sec.)",host,freq);
X
X      /* make sure window is big enough */
X
X      if (f_high * (count+1) > high) {
X         fprintf(stderr,"\fWindow isn't tall enough\n");
X         m_gets(line);
X         continue;
X         }
X
X      if (strlen(title)*f_wide > wide || 3*size*f_wide > wide*2) {
X         fprintf(stderr,"\fWindow isn't\nwide enough\n");
X         m_gets(line);
X         continue;
X         }
X
X      /* calculate key positions */
X
X      x1 = (size*f_wide+1);
X      x2 = (wide-strlen(title)*f_wide)/2;
X      y1 = f_high +1;
X      y2 = (high - y1) /count;
X      high--;
X
X      m_func(B_SET);
X      m_clear();
X      x = x1;
X      scroll = Max((wide-x1)/SCROLL,10);
X      scroll += scroll%DELTA;
X
X      if (freq >15)
X         interval = INTERVAL * 10 /freq;
X      else 
X         interval = INTERVAL / freq;
X
X      /* draw form */
X
X      m_moveprint(x2,y1,title);
X
X      for(i=0;i<count;i++) {
X         char tmp[10];
X         if (f_high * (3*count+1) <= high) {
X            sprintf(tmp,"%d",data[field[i]].max);
X            m_moveprint(x1-f_wide*strlen(tmp),high-(i+1)*y2+f_wide*2+1,tmp);
X            m_moveprint(x1-f_wide,high-i*y2,"0");
X            m_moveprint(1,high-i*y2-f_high,labels[i]);
X            }
X         else
X            m_moveprint(1,high-i*y2-1,labels[i]);
X         m_line(x1,high-i*y2,wide,high-i*y2);
X         }
X   
X      m_line(0,y1,wide,y1);
X      m_line(x1,y1,x1,high);
X      m_movecursor(x1,0);
X      m_flush();
X
X      /* read the data */
X
X      while (fgets(line,sizeof(line),file) != NULL) {
X         i = parse(line,fields);
X         if (strcmp(*fields,"procs")==0) {
X            fgets(line,sizeof(line),file);
X            fgets(line,sizeof(line),file);
X            continue;
X            }
X          if (i < 22) continue;
X
X         /* calculate new line position */
X
X         for(i=0;i<count;i++) {
X            current[i] = atoi(fields[data[field[i]].index]) *
X                         (y2-3)/data[field[i]].max;
X            current[i] = Min(current[i],y2-3) + y2*i + 1;
X
X            if (!first) {
X               m_line(x,high-old[i],x+delta,high-current[i]);
X               if (solid)
X                  m_line(x+delta,high-y2*i,x+delta,high-current[i]);
X               }
X
X            dprintf(stderr,"%s %d->%d, ",data[field[i]].s_title,
X                            high-old[i],high-current[i]);
X            old[i] = current[i];
X            }
X         dprintf(stderr," [%d]\n",high);
X   
X         if (++bar  == interval) {
X            m_line(x,y1,x,high);
X            bar = 0;
X            dprintf(stderr,"---------\n");
X            }
X
X         if (first)
X            first = 0;
X         else
X            x += delta;
X
X         if (x > wide-delta) {
X
X            /* scroll the display */
X
X            x -= scroll;
X            m_func(B_COPY);
X            m_bitcopy(x1+1,y1+1,wide-x1-1,high-y1-1,x1+scroll+1,y1+1);
X            m_func(B_CLEAR);
X            m_bitwrite(wide-scroll,y1+1,scroll,high);
X            m_func(B_SET);
X         
X            dprintf(stderr,"scroll to %d,%d from %d,%d\n",
X                    x1+1,y1+1,x1+scroll+1,y1+1);
X            for(i=0;i<count;i++) 
X               m_line(wide-scroll,high-i*y2,wide,high-i*y2);
X            }
X         m_flush();
X         if (read_it(fileno(m_termin),line) && *line == 'R')
X            break;
X         }
X      }
X   }
X
Xint
Xget_item(s,data)	/* look up an parameter */
Xchar *s;
Xstruct data data[];
X   {
X   register int i;
X
X   for(i=0;data[i].index>=0;i++)
X      if (strcmp(s,data[i].s_title)==0)
X        return(i);
X   return(-1);
X   }
X
Xclean()			/* clean up on SIGINT */
X   {
X   m_pop(0);
X   pclose(file);
X   m_clear();
X   m_flush();
X   m_ttyreset();
X   exit(1);
X   }
X
Xint read_it(fd,line)	/* non blocking read */
Xint fd;
Xchar *line;
X   {
X   long rd;
X
X   ioctl(fd,FIONREAD,&rd);
X   line[rd] = '\0';
X   if (rd > 0)  {
X      return(read(fd,line,rd));
X      }
X   else
X      return(0);
X   }
END_OF_FILE
# end of 'demo/misc/stat.c'
fi
if test -f 'doc/usrman/doc.5' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'doc/usrman/doc.5'\"
else
echo shar: Extracting \"'doc/usrman/doc.5'\" \(9903 characters\)
sed "s/^X//" >'doc/usrman/doc.5' <<'END_OF_FILE'
X'\"                        Copyright (c) 1988 Bellcore
X'\"                            All Rights Reserved
X'\"       Permission is granted to copy or use this program, EXCEPT that it
X'\"       may not be sold for profit, the copyright notice must be reproduced
X'\"       on copies, and credit should be given to Bellcore where it is due.
X'\"       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X'\"
X'\"	$Header: doc.5,v 4.1 88/06/29 17:05:04 bianchi Exp $
X'\"	$Source: /tmp/mgrsrc/doc/usrman/RCS/doc.5,v $
X.Sh page Functions
XThe functions listed below have packaged common sequences of
X.I macro
Xcalls together to provide a slightly higher level of interface than the
Xmacros alone.  They are still low level, and have no pretense of
Xcompleteness. Except where noted, all of the functions return a value
Xgreater than zero on success, and a value less than zero upon failure.
XThe functions fail only if they read an unexpected value from \*M.
XClient programs may use the function
X.Fr m_lastline
Xin an attempt to determine what input caused the failure.
XThose functions which expect data from \*M automatically flush any
Xpending output before reading, and unless the 
X.I M_MODEOK
Xflag is set,
Xattempt to turn off character echoing
Xto prevent data returned by \*M from echoing back on the window.
X.LP
X.RS
X.Fd int
X.Fr get_all list 
X.Fs get_all\(dg 7 "Get all window status"
X.br
Xstruct window_data \*Alist;
X.Ft
XThe current position size and status of all windows on the display
Xis returned in
X.Fi list .
XThe number of in
Xwindows on the display is returned.
X.Fi List
Xshould be large enough to hold a status entry for each window.
XThe
X.I window_data
Xstructure 
Xis defined in
X.I term.h .
X.Fd int
X.Fr get_client list 
X.Fs get_client\(dg 7 "Get alternate window status"
X.br
Xstruct window_data \*Alist;
X.Ft
XThe current position size and status of the client programs
X.I main
Xand
X.I alternate
Xwindows
Xis returned in
X.Fi list .
XThe number of
Xwindows owned by the client program is returned.
X.Fi List
Xshould be large enough to hold a status entry for each window.
XThe
X.I window_data
Xstructure 
Xis defined in
X.I term.h .
X.Fd int
X.Fr get_colrow columns rows 
X.Fs get_colrow\(dg 7 "Get window size, in columns and rows"
X.br
Xint \*Acolumns, \*Arows;
X.Ft
XThe number of
X.I columns
Xand
X.I rows
Xin the current 
X.I "text region"
Xis returned in
X.Fi columns
Xand
X.Fi rows
Xrespectively.
XFor any
X.SM
X.I NULL
X.LG
Xargument,
Xno value is returned.
X.Fd int
X.Fr get_cursor column row 
X.Fs get_cursor\(dg 7 "Get cursor position"
X.br
Xint \*Acolumn, \*Arow;
X.Ft
XThe current
X.I character
Xcursor position is placed in
X.Fi column
Xand
X.Fi row .
XFor any
X.SM
X.I NULL
X.LG
Xargument,
Xno value is returned.
X.Fd int
X.Fr get_eachclientwin windatap
X.Fs get_eachclientwin\(dg 7 "Get window parameters for each window"
X.br
Xstruct window_data \*Awindatap;
X.Ft
XGet the window parameters for each window in the current window set,
Xone window at a time.
XThis function returns 1 if window_data structure has been filled,
X0 otherwise.
XIt is important to call get_eachcleintwin() in a tight loop that
Xdoesn't exit until it returns 0,
Xso that all the data is picked up.
XThis function is preferred to
X.Fr get_client
X because you don't need to know the maximum number of windows you are likely
Xto see.
X.Fd int
X.Fr get_eachwin windatap
X.Fs get_eachwin\(dg 7 "Get window parameters for each window"
X.br
Xstruct window_data \*Awindatap;
X.Ft
XGet the window parameters for all the windows,
Xone window at a time.
XThis function returns 1 if window_data structure has been filled,
X0 otherwise.
XIt is important to call get_eachwin() in a tight loop that
Xdoesn't exit until it returns 0,
Xso that all the data is picked up.
XThis function is preferred to
X.Fr get_all
X because you don't need to know the maximum number of windows you are likely
Xto see.
X.Fd int
X.Fr get_font wide high 
X.Fs get_font\(dg 7 "Get character font size"
X.br
Xint  \*Awide, \*Ahigh;
X.Ft
XThe character size of the current font, in pixels
Xis placed in
X.Fi wide
Xand
X.Fi high .
XFor any
X.SM
X.I NULL
X.LG
Xargument,
Xno value is returned.
XThe function returns the current font number, as would be
Xused in a call to
X.Fr m_font
X\&.
X.Fd int
X.Fr get_mouse x y 
X.Fs get_mouse\(dg 7 "Get mouse position"
X.br
Xint \*Ax, \*Ay;
X.Ft
XThe current mouse
Xposition, in
X.I window
Xcoordinates, is placed in
X.Fi x
Xand
X.Fi y .
XFor any
X.SM
X.I NULL
X.LG
Xargument,
Xno value is returned.
XThe function returns the current mouse button state, which is
Xin the range of -2 to +2 upon success, a value less than -2
Xupon failure.
XSee 
X.Fr m_getinfo G_MOUSE
X for a discussion of the return values.
X.Fd int
X.Fr get_param host xmax ymax border 
X.Fs get_param\(dg 7 "Get \*M system parameters"
X.br
Xchar \*Ahost;
Xint \*Axmax, \*Aymax, \*Aborder;
X.Ft
XThe
X.I \*M-host ,
Xdisplay size (in pixels)
Xand window border size (in pixels) is placed in the arguments
X.Fi host , xmax , ymax ,
Xand
X.Fi border .
XFor any
X.SM
X.I NULL
X.LG
Xargument,
Xno value is returned.
X.Fd int
X.Fr get_size X Y Dwidth Dheight 
X.Fs get_size\(dg 7 "Get the window size and position on the display"
X.br
Xint \*AX, \*AY, \*ADwidth, \*ADheight;
X.Ft
XThe position of the window on the display, in
X.I display
Xcoordinates is placed into
X.Fi X , Y , Dwidth 
Xand
X.Fi Dheight .
XFor any
X.SM
X.I NULL
X.LG
Xargument,
Xno value is returned.
X.Fd char \*A
X.Fr get_termcap  
X.Fs get_termcap\(dg 7 "Get a \s-2TERMCAP\s+2 entry"
X.br
X.Ft
XA string containing a
X.I \s-2TERMCAP\s+2
Xentry, suitable for placing into the
X.I \s-2TERMCAP\s+2
Xenvironment variable is returned.
XThe function
X.Fr get_termcap
X returns 
X.SM
X.I NULL
X.LG
Xupon failure.
X.Fd int
X.Fs is_active\(dg 7 "See if the window is the active window"
X.Fr is_active  
X.Ft
X.br
XThe function
X.Fr is_active
X returns
X.SM
X.I TRUE
X.LG
Xif the window is the
X.I active
Xwindow .
X.Fd void
X.Fr menu_load n count text 
X.Fs menu_load\(dg 8 "Down load a pop-up menu"
X.br
Xint n;
Xint count;
Xstruct menu_entry \*Atext;
X.Ft
XA menu is downloaded to \*M at position
X.Fi n .
XThe integer 
X.Fi count
Xis the number of menu items to be down-loaded, and
X.Fi text
Xis an array of menu item/value pairs.
XThe structure
X.I menu_entry
Xis defined in
X.I term.h .
X.Fd int
X.Fr m_bitfile to name widep highp
X.Fs m_bitfile\(dg 5 "Read a bitmap file into a scratchpad bitmap"
X.br
Xint to;
Xchar *name;
Xint *widep, *highp;
X.Ft
XGiven a bitmap id,
X.Fi to
Xand an icon 
X.Fi name ,
Xhave \*M load that icon into that scratchpad bitmap,
Xreturning the icon width
Xand height, in pixels, via the given integer pointers.
XReturn a positive number if successful.
XIf the icon is not loaded, set the width and height values to 0 and
Xreturn 0.
XThis function is identical to
X.Fr m_bitfromfile
Xplus the needed interception of the line returned from \*M.
X.Fd void
X.Fr m_bitload x y wide high data 
X.Fs m_bitload\(dg 5 "Download an image into the window"
X.br
Xint x,y;
Xint wide,high;
Xregister char \*Adata;
X.Ft
XThe bitmap image pointed at by
X.Fi data
Xis down-loaded to the window
Xat position
X.Fr ""  x  y
X in 
X.I window
Xcoordinates.
XIt is up to the client program to insure an 8 bit channel exists
Xbetween the client and \*M.
XThe integers
X.Fi wide
Xand
X.Fi high
Xspecify the size of the bitmap in pixels.
X.Fd char \*A
X.Fr m_lastline  
X.Fs m_lastline\(dg 1 "Retrieve the last line send from \*M for a library function"
X.br
X.Ft
XThe last input from \*M to a library function is returned.
XThe data is kept in a static buffer which is overwritten
Xat each request.
X.Fd int
X.Fr m_makewindow X Y Dwidth Dheight
X.Fs m_makewindow\(dg 11 "Make an alternate window"
X.br
Xint  X, Y, Dwidth, Dheight;
X.Ft
XAn alternate window is created as the
X.I active
Xwindow,
Xat display coordinates
X.Fr "" X Y
X and of size
X.Fi Dwidth
Xby
X.Fi Dheight
Xpixels.
XIf the window is too big to fit on the display, its
Xwidth and height are truncated.
XThe alternate window's
X.I window-id
Xis returned if the window was created successfully.
XThe macro
X.Fr m_selectwin
X is used to write on the newly created window.
X.Fd int
X.Fr m_setup mode 
X.Fs m_setup\(dg 1 "Initialize the library package"
X.br
Xint mode;
X.Ft
XThis function initializes the library.
XIt must be called before any other function or macro.
XThe argument
X.Fi mode
Xis one or more of the flags
X.SM
X.I M_FLUSH ,
X.I M_DEBUG ,
X.LG
Xor
X.SM
X.I M_MODEOK
X.LG
X.I or -ed
Xtogether.
XIf 
X.SM
X.I M_FLUSH
X.LG
Xis present, all macros and function flush output to \*M after each
Xmacro call.  This is slightly less efficient than letting the client
Xprogram flush the data
X(see
X.Fr m_flush
X )
Xbut prevent inadvertent buffering problems.
XThe 
X.I M_DEBUG
Xflag forces the macro package to read and write from
X.I stdin
Xand
X.I stdout
Xrespectively.
XNormally
X.I /dev/tty
Xis opened for reading and writing to permit standard input or output
Xredirection while still maintaining a connection to \*M.
XIf
X.I /dev/tty
Xcan not be opened, as would be the case for clients invoked through
X.I rsh ,
Xthe
X.I M_DEBUG
Xflag is turned on,
Xand
X.I stdin
Xand
X.I stdout
Xare used instead.
XThe
X.I M_MODEOK
Xflag instructs those functions which expect data from \*M
Xto assume the terminal modes are set appropriately.
XOtherwise, the functions attempt to turn off character echoing and
Xturn on line mode before fetching data from \*M.
XThe functions
X.Fr m_ttyset
X and
X.Fr m_ttyreset
X can be used to set and reset the terminal modes.
XThe function
X.Fr m_setup
X returns its argument, with the 
X.I M_DEBUG
Xflag
X.I or -ed
Xin if 
X.I /dev/tty
Xcan not be opened.
X.Fd void
X.Fr m_ttyreset  
X.Fs m_ttyreset\(dg 1 "Reset the tty modes"
X.br
X.Ft
XThe terminal modes are restored to their state just
Xprior to the last call to 
X.Fr m_ttyset 
X\&.
XCalls to 
X.Fr m_ttyset
X and
X.Fr m_ttyreset
X may be stacked up to ten levels.
X.Fd int
X.Fr m_ttyset  
X.Fs m_ttyset\(dg 1 "Set the tty modes for proper \*M interaction"
X.br
X.Ft
XThe terminal is set in a state suitable for data exchange with \*M.
XCharacter echoing is turned off, and line processing mode
Xis enabled.
XThe function returns zero (0) if it successfully retrieves the terminal
Xmodes, -1 otherwise.
X.RE
END_OF_FILE
# end of 'doc/usrman/doc.5'
fi
if test -f 'src/startup.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/startup.c'\"
else
echo shar: Extracting \"'src/startup.c'\" \(9609 characters\)
sed "s/^X//" >'src/startup.c' <<'END_OF_FILE'
X/*                        Copyright (c) 1987 Bellcore
X *                            All Rights Reserved
X *       Permission is granted to copy or use this program, EXCEPT that it
X *       may not be sold for profit, the copyright notice must be reproduced
X *       on copies, and credit should be given to Bellcore where it is due.
X *       BELLCORE MAKES NO WARRANTY AND ACCEPTS NO LIABILITY FOR THIS PROGRAM.
X */
X/*	$Header: startup.c,v 4.3 88/06/28 17:41:01 bianchi Exp $
X	$Source: /tmp/mgrsrc/src/RCS/startup.c,v $
X*/
Xstatic char	RCSid_[] = "$Source: /tmp/mgrsrc/src/RCS/startup.c,v $$Revision: 4.3 $";
X
X/* read and process startup file */ /* this needs to be redone */
X
X#include <stdio.h>
X#include "bitmap.h"
X#include "defs.h"
X#include "font.h"
X
X#define MAXLINE		128
X#define MAXFIELDS	100
X
Xstruct font *Get_font();
X
Xstatic int newx = -1, newy = -1, newdx, newdy, newfont, newflags;
Xstatic char newinit[MAXLINE];
Xstatic char *newshell[MAXFIELDS];
Xstatic char newstart[MAXLINE];
Xstatic char *initcmd, *suspendcmd, *resumecmd, *quitcmd;
X
Xstartup(name)		/* do startup file */
Xchar *name;		/* name of startup file */
X   {
X   FILE *file = fopen(name,"r");		/* file to read commands from */
X   int x=0 ,y=0 ,dx=0 ,dy=0 ,fnt=0 ;		/* window coords, font # */
X   char *trans(), *save_line(), *strcat();
X   char line[MAXLINE];				/* space to store stuff */
X   char start[MAXLINE];				/*  "  */
X   char init[MAXLINE];				/*  "  */
X   char *shell[MAXFIELDS];			/*  "  */
X   char *fields[MAXFIELDS];			/*  "  */
X   int curr_font = 0;				/* font # for this window */
X   int flags = 0;				/* window flags */
X   register int i;
X   int count,  gotwindow = 0, gotnewwindow = 0;			
X   int setactive = 0, activesetid = 0;
X   int windowsetid = 0;
X
X   bzero(start,MAXLINE);
X   bzero(line,MAXLINE);
X   bzero(init,MAXLINE);
X   bzero(shell,MAXFIELDS);
X   bzero(fields,MAXFIELDS);
X
X   if (file == NULL) 
X      return(-1);
X
X
X   /* process each line in startup file */
X
X   while (fgets(line,sizeof(line),file) != NULL) {
X#ifdef DEBUG
X      dprintf(S)(stderr,"*** got: %s \r\n",line);
X#endif
X      count = parse(line,fields);
X
X      if (*fields == (char *) 0)
X         continue;
X
X      else if (strcmp(*fields,"window")==0 || strcmp(*fields,"done")==0) {
X
X         if (gotnewwindow==1) {
X	    gotnewwindow = 0;
X	    newx = x;
X	    newy = y;
X	    newdx = dx;
X	    newdy = dy;
X	    newfont = curr_font;
X	    strcpy(newstart, start);
X	    strcpy(newinit, init);
X	    for( i = 0; shell[i]; i++ ) {
X	       if( newshell[i] )
X		  free( newshell[i] );
X	       newshell[i] = shell[i];
X	       shell[i] = (char*)0;
X	       }
X            gotwindow = 0;
X	    newshell[i] = (char*)0;
X            gotwindow = 0;
X            bzero(start,MAXLINE);
X            bzero(init,MAXLINE);
X            curr_font = 0;
X            flags = 0;
X	    windowsetid = 0;
X	    }
X      /* got a window */
X
X         if (gotwindow==1) {
X            if (check_window(x,y,dx,dy,curr_font) == 0) {
X               gotwindow = 0;
X               bzero(start,MAXLINE);
X               bzero(init,MAXLINE);
X               curr_font = 0;
X               flags = 0;
X	       windowsetid = 0;
X               continue;
X               }
X
X	    if( !active ) {
X	       MOUSE_OFF(mousex,mousey);
X               erase_win(screen,0,0);
X	       MOUSE_ON(mousex,mousey);
X	    }
X            dowindow( x, y, dx, dy, curr_font, shell, flags, init, start );
X
X	    if( windowsetid ) {
X	       ACTIVE(setid) = windowsetid;
X	       windowsetid = 0;
X	    }
X
X	    if( setactive  &&  activesetid == 0 )
X	       activesetid = ACTIVE(setid);
X   
X            if( setactive )
X	       topwin( activesetid, -1 );
X	    if( *shell )
X	       free( *shell );
X            *shell = '\0';
X            flags = 0;
X            bzero(start,MAXLINE);
X            bzero(init,MAXLINE);
X            curr_font = 0;
X            }
X
X         if (strcmp(*fields,"window")==0 && count >=5) {
X
X            gotwindow = 1;
X            x = atoi(fields[1]);
X            y = atoi(fields[2]);
X            dx = atoi(fields[3]);
X            dy = atoi(fields[4]);
X            if (count > 5 && (fnt=atoi(fields[5]))<=MAXFONT) {
X	       char lastchar();
X	       struct font *fp = Get_font( fnt );
X
X	       if( lastchar( fields[3] ) == 'c' )
X		  dx = dx*fp->head.wide + 2*SUM_BDR;
X	       if( lastchar( fields[4] ) == 'c' )
X		  dy = dy*fp->head.high + 2*SUM_BDR;
X               curr_font = fnt;
X	       }
X            }
X         else
X            gotwindow = 0;
X         }
X
X      else if (strcmp(*fields,"initcmd")==0 && count >2) {
X	    save_fields( &initcmd, fields );
X	    do_cmd( 'i' );
X	 }
X      else if (strcmp(*fields,"suspendcmd")==0 && count >2) {
X	    save_fields( &suspendcmd, fields );
X	 }
X      else if (strcmp(*fields,"resumecmd")==0 && count >2) {
X	    save_fields( &resumecmd, fields );
X	 }
X      else if (strcmp(*fields,"quitcmd")==0 && count >2) {
X	    save_fields( &quitcmd, fields );
X	 }
X      else if (strcmp(*fields,"font")==0 && count >2) {
X         fnt = atoi(fields[1]);
X#ifdef DEBUG
X         dprintf(S)(stderr,"got font %s (%d)\r\n",fields[2],fnt);
X#endif
X         if (fnt > 0  &&  fnt <= MAXFONT) {
X            if (fontlist[fnt-1])
X               free(fontlist[fnt-1]);
X            fontlist[fnt-1] = save_line(fields[2]);
X            }
X         }
X
X      else if (strcmp(*fields,"map")==0 && count >8) {
X         for(i=0;i<8;i++)
X            map_mouse(i,atoi(fields[i+1]));
X#ifdef DEBUG
X         dprintf(S)(stderr,"got mouse map \r\n");
X#endif
X         }
X
X      else if (strcmp(*fields,"slide")==0 && count > 2) {
X         set_slide(atoi(fields[1]),atoi(fields[2]));
X#ifdef DEBUG
X         dprintf(S)(stderr,"set menu slide %d,%d\r\n",
X                    atoi(fields[1]),atoi(fields[2]));
X#endif
X         }
X
X      else if (strcmp(*fields,"page")==0 && count > 2) {
X         set_page(atoi(fields[1]),atoi(fields[2]));
X#ifdef DEBUG
X         dprintf(S)(stderr,"set menu page %d,%d\r\n",
X                    atoi(fields[1]),atoi(fields[2]));
X#endif
X         }
X
X      else if (strcmp(*fields,"active")==0 && gotwindow==1) {
X	 setactive = 1;
X	 activesetid = 0;
X      }
X      else if (strcmp(*fields,"windowsetid")==0 && count>1 && gotwindow==1) {
X	 windowsetid = atoi( fields[1] );
X      }
X      else if (strcmp(*fields,"newwindow")==0 && gotwindow==1) {
X	 gotnewwindow = 1;
X      }
X      else if (strcmp(*fields,"shell")==0 && count>1 && gotwindow==1) {
X         for(i=0;i<count-1;i++) {
X            if (shell[i])
X               free(shell[i]);
X            shell[i] = save_line(fields[i+1]);
X            }
X         if (shell[count-1]) {
X            free (shell[count-1]);
X            shell[count-1] = (char *) 0;
X            }
X         }
X      else if (strcmp(*fields,"init")==0) {
X         for(i=1;fields[i]!=(char *)0;i++) {
X	    if( i > 1 )
X	       strcat(init," ");
X            strcat(init,fields[i]);
X	    }
X         trans(init);
X         }
X
X      else if (strcmp(*fields,"start")==0) {
X         for(i=1;fields[i]!=(char *)0;i++) {
X	    if( i > 1 )
X	       strcat(start," ");
X            strcat(start,fields[i]);
X	    }
X         trans(start);
X         }
X
X      else if (strcmp(*fields,"flags")==0 && count > 1 && gotwindow==1) {
X         for(i=1;i<count;i++) {
X            if (strcmp(fields[i],"expose")==0)
X               flags |= W_EXPOSE;
X            else if (strcmp(fields[i],"background")==0)
X               flags |= W_BACKGROUND;
X            else if (strcmp(fields[i],"nokill")==0)
X               flags |= W_NOKILL;
X#ifdef DEBUG
X            dprintf(S)(stderr,"Flags: %d (%s)\r\n",flags,fields[i]);
X#endif
X            }
X         }
X
X      else {
X#ifdef DEBUG
X         dprintf(S)(stderr,"invalid line: %s\r\n",line);
X#endif
X         }
X      }
X   fclose(file);
X   return(0);
X   }
X
X
X/*	Given a character pointer and a pointer to an array of strings,
X	catenate the strings into fresh memory and put the address of the copy
X	into the character pointer.
X	free() any space originally pointed to by the character pointer.
X*/
Xsave_fields( cpp, fields )
Xchar	**cpp;
Xchar	*fields[];
X{
X	register int	i;
X	char		savestr[MAXLINE];
X
X	if( *cpp )
X		free( *cpp );
X	*savestr = '\0';
X	for( i=1;  fields[i]!=(char *)0;  i++ ) {
X		if( i > 1 )
X			strcat(savestr, " ");
X		strcat(savestr, fields[i]);
X	}
X	trans(savestr);
X	*cpp = save_line( savestr );
X}
X
X
Xdo_cmd( flag )
Xchar	flag;
X{
X	switch( flag ) {
X	case 'i':
X		system( initcmd );
X		break;
X	case 's':
X		system( suspendcmd );
X		break;
X	case 'r':
X		system( resumecmd );
X		break;
X	case 'q':
X		system( quitcmd );
X		break;
X	}
X}
X
X
Xinitwindow()
X{
X    dowindow( newx, newy, newdx, newdy, newfont, newshell, newflags,
X	newinit, newstart );
X}
X
X
Xstatic
Xchar
Xlastchar( cp )
Xchar *cp;
X{
X   int length = strlen(cp);
X   if( !length )
X      return '\0';
X   return  cp[ length-1 ];
X}
X
X
Xstatic
Xdowindow( x, y, dx, dy, font, shell, flags, init, start )
Xint	x, y, dx, dy, font;
Xchar	*shell[];
Xint	flags;
Xchar	*init, *start;
X{
X    struct font *fp = Get_font( font );
X    int i;
X
X#ifdef DEBUG
X    dprintf(S)(stderr,"starting shell %s\r\n",shell ? *shell : "???");
X#endif
X    if( x < 0 )
X       x = 32 + 16*next_windowset_id();
X    if( y < 0 )
X       y = 32 + 16*next_windowset_id();
X    if( dx <= 0 )
X      dx = 80*fp->head.wide + 2*SUM_BDR;
X    if( dy <= 0 )
X      dy = 24*fp->head.high + 2*SUM_BDR;
X    MOUSE_OFF(mousex,mousey);
X    create_window(x, y, dx, dy, font, *shell?shell:0);
X    MOUSE_ON(mousex,mousey);
X
X    if (flags)
X       ACTIVE(flags) |= flags;
X    if (*init)
X       put_window(active,init,strlen(init));
X    if (*start)
X       i = Write(ACTIVE(to_fd),start,strlen(start));
X#ifdef DEBUG
X    dprintf(S)(stderr,"%s: start string %d/%d %s\r\n",ACTIVE(tty),
X	       i,strlen(start),start);
X#endif
X}
END_OF_FILE
# end of 'src/startup.c'
fi
echo shar: End of archive 31 \(of 61\).
cp /dev/null ark31isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
	21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 \
	38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 \
	55 56 57 58 59 60 61 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 61 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.