[comp.os.minix] New program man.c

ast@cs.vu.nl (Andy Tanenbaum) (11/30/89)

/* man - display and manage manual pages	Author: Dick van Veen */

/* Options:
 *	man <ar-dir>? <ar-name>? <man-page>+
 *		display <man-page> from <ar-name> in <ar-dir>.
 *	man <ar-dir>? <ar-name>?
 *		display contents of <ar-name> in <ar-dir>,
 *		by using the <cursor-keys> and <return> a page is choosen.
 *
 * <ar-dir>	is a directory name starting with a '/'.
 *		the default directory is '/usr/man'.
 *
 * <ar-name>	is a digit, when no digit is used, chapter 1 searched.
 */

#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <ctype.h>

#ifndef INDEX_H
#define INDEX_H

#define MAN_DELIM	'#'
#define NAME_SIZE	12	/* for size in index file */
#define NAME_WIDTH	15	/* for on screen projection */
#define AR_NAME_SIZE	64	/* for file names */
#define AR_DIR		"/usr/man"
#define AR_NAME		"/man"
#define AR_INDEX	"/._man"

struct INDEX {
  long page_pos;		/* position in index file */
  char page_name[NAME_SIZE];	/* name of manual page */
};

extern char ar_name[AR_NAME_SIZE];	/* name of man archive file */
extern char ar_index[AR_NAME_SIZE];	/* name of index file */
extern struct INDEX *index_buf;	/* contains indices */
extern int max_index_nr;	/* number of indices in index_buf */

/* Should be a prototype */
extern void read_index();
#endif
#ifndef DISPLAY_H
#define DISPLAY_H

#define MAX_X		(CO/NAME_WIDTH)	/* define width of screen */
#define MAX_Y		(LI)	/* define hight of screen */

#define STOP		256	/* codes returned by get_token */
#define READY		257
#define	CURSLEFT	258
#define CURSRIGHT	259
#define CURSUP      	260
#define CURSDOWN	261
#define CURSHOME	262
#define CURSEND		263
#define CURSPAGEUP	264
#define CURSPAGEDOWN	265
#define CURSMIDDLE	266

extern int term_dialog;		/* do we have a terminal ? */
extern int term_clear;		/* do we clear at exit ? */
extern int top_y, cur_x, cur_y;	/* current position on the screen */
extern char *CL, *CM, *DL, *SO, *SE;	/* for termcap */
extern int CO, LI;		/* for termcap */

#define	GOTOXY(x, y)		fputs(tgoto(CM, (x), (y)), stdout)
#define reverse(on)		fputs((on)?SO:SE, stdout)
#define clrscr()		fputs(CL, stdout)

/* Should be prototypes */
extern void display();
extern int gettoken();
extern void set_cursor();
extern void term_init();
extern void term_exit();
#endif

/* Arguments for do_wait() */
#define	WAIT1		"press <return>"
#define WAIT2		"press <return> for "
#define WAIT3		"press <return> for more ..."

#define DO_REVERSE	0x01	/* modes for do_wait() */
#define DO_DELETE	0x02

extern char *malloc();
extern char *getenv();

/* Forward declaration: */
extern void Exit();
static void man();
static void _man();
static void choose();
static int do_choose();
static int do_wait();

main(argc, argv)
int argc;
char **argv;
{
  FILE *man_fd;

  argv++;
  argc--;
  if (*argv != NULL && **argv == '/') {
	(void) strcpy(ar_name, *argv);	/* get archive directory */
	(void) strcpy(ar_index, *argv);	/* get index directory */
	argv++;
	argc--;
  } else {
	(void) strcpy(ar_name, AR_DIR);	/* use default directory */
	(void) strcpy(ar_index, AR_DIR);
  }

  (void) strcat(ar_name, AR_NAME);	/* get archive name */
  (void) strcat(ar_index, AR_INDEX);	/* get index name */

  if (*argv != NULL && isdigit(**argv)) {
	(void) strcat(ar_name, *argv);	/* get archive name */
	(void) strcat(ar_index, *argv);
	argv++;
	argc--;
  } else {
	(void) strcat(ar_name, "1");	/* default archive */
	(void) strcat(ar_index, "1");
  }
  man_fd = fopen(ar_name, "r");	/* open man archive */
  if (man_fd == NULL) {
	fprintf(stderr, "can't open %s\n", ar_name);
	Exit(1);
  }
  read_index();
  term_dialog = isatty(0) && isatty(1);
  term_init();
  if (*argv == NULL)
	choose(man_fd);
  else
	man(man_fd, argv);
  Exit(0);
}

void Exit(code)
int code;
{
  term_exit();			/* return terminal to old status */
  exit(code);
}

static void man(man_fd, man_pages)
FILE *man_fd;
char **man_pages;
{				/* copy all requested manual pages to
			 * standard output */
  int ch;

  while (1) {
	_man(man_fd, *man_pages);
	man_pages++;
	if (*man_pages == NULL) break;
	if (term_dialog) {	/* wait before starting next page */
		fputs(WAIT2, stdout);
		if (do_wait(*man_pages, 0)) break;
		fputc('\n', stdout);
	}
  }
}

static void _man(man_fd, man_page)
FILE *man_fd;
char *man_page;
{				/* copy the manual page to standard output */
  int index_nr, ch, line_nr = -1;

  /* Search entries for man_page */
  for (index_nr = 0; index_nr < max_index_nr; index_nr++) {
	if (strncmp(man_page, index_buf[index_nr].page_name,
		    NAME_SIZE) == 0)
		break;
  }
  if (index_nr == max_index_nr) {
	fprintf(stderr, "manual page for %s not available\n", man_page);
	return;
  }
  if (fseek(man_fd, index_buf[index_nr].page_pos, 0) == -1) {
	fprintf(stderr, "can't seek in manaul archive\n");
	Exit(1);
  }
  while ((ch = fgetc(man_fd)) != '\n') {	/* skip names on first line */
	if (ch == EOF) break;
  }
  ch = fgetc(man_fd);		/* display manual page */
  while (ch != EOF) {
	fputc(ch, stdout);
	if (ch == '\n') {
		ch = fgetc(man_fd);
		if (ch == MAN_DELIM) break;
		if (term_dialog) {	/* wait after page full */
			line_nr++;
			if (line_nr != LI - 2) continue;
			if (do_wait(WAIT3, DO_REVERSE | DO_DELETE)) break;
			line_nr = 0;
		}
	} else
		ch = fgetc(man_fd);
  }
}

static void choose(man_fd)
FILE *man_fd;
{				/* driver one time chosing a page on the
			 * screen */
  int ch, index, max_x, max_y;

  if (!term_dialog) {
	fprintf(stderr, "sorry, no terminal\n");
	Exit(1);
  }
  term_clear = 1;
  max_y = (max_index_nr - 1) / MAX_X;	/* determine screen sizes */
  max_x = max_index_nr % MAX_X;
  if (max_x == 0) max_x = MAX_X;
  while (1) {
	index = do_choose(max_x, max_y);
	if (index == STOP) break;
	clrscr();
	_man(man_fd, index_buf[index].page_name, 1);
	(void) do_wait(WAIT1, DO_REVERSE);
  };
}

static int do_choose(max_x, max_y)
int max_x, max_y;
{				/* implements the cursor movement on screen,
			 * returns entry number */
  int token;

  display(1);
  set_cursor(1);
  while (1) {
	fflush(stdout);
	token = gettoken();
	if (token == READY || token == STOP) break;
	set_cursor(0);
	switch (token) {
	    case CURSLEFT:
		if (cur_x > 0) cur_x--;
		break;
	    case CURSRIGHT:
		if (cur_x < MAX_X - 1) cur_x++;
		break;
	    case CURSUP:
		if (cur_y > top_y)
			cur_y--;
		else if (top_y > 0) {
			cur_y--;
			top_y--;
		}
		break;
	    case CURSDOWN:
		if (cur_y < (top_y + MAX_Y - 1)) {
			cur_y++;
			if (cur_y > max_y) cur_y = max_y;
		} else if ((top_y + MAX_Y - 1) < max_y) {
			top_y++;
			cur_y++;
		}
		break;
	    case CURSPAGEUP:
		top_y -= MAX_Y;
		if (top_y < 0) {
			top_y = 0;
		}
		cur_y = top_y;
		cur_x = 0;
		break;
	    case CURSPAGEDOWN:
		top_y += MAX_Y;
		if ((top_y + MAX_Y - 1) >= max_y) {
			top_y = max_y - (MAX_Y - 1);
			if (top_y < 0) top_y = 0;
		}
		cur_y = top_y;
		cur_x = 0;
		break;
	    case CURSHOME:
		top_y = 0;
		cur_y = 0;
		cur_x = 0;
		break;
	    case CURSEND:
		top_y = max_y - (MAX_Y - 1);
		if (top_y < 0) top_y = 0;
		cur_y = max_y;
		cur_x = 0;
		break;
	    case CURSMIDDLE:
		clrscr();	/* redraw screen */
		break;
	}
	if (cur_y == max_y && cur_x >= max_x) cur_x = max_x - 1;
	display(token == CURSMIDDLE);
	set_cursor(1);
  }
  if (token == STOP)
	return(STOP);
  else
	return(cur_x + cur_y * MAX_X);
}

static int do_wait(message, mode)
char *message;
int mode;
{				/* print message and waits for a newline,
			 * only on terminal dialog */
  int ch;

  if (!term_dialog) return(0);
  if (mode & DO_REVERSE) reverse(1);
  fputs(message, stdout);
  if (mode & DO_REVERSE) reverse(0);
  fflush(stdout);
  do {
	ch = getchar();
  } while (ch != EOF && ch != 'q' && ch != 'Q' && ch != '\n');

  if ((mode & DO_DELETE) && DL) fprintf(stdout, "%s\r", DL);
  if (ch == '\n') return (0);	/* normal end */
  return(1);			/* abnormal end */
}

/* Index.c:	a file to handle the index file */
/*
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <ctype.h>
#include "index.h"
*/

#define MAN_FGETC(ch, man_fd)	{ch=fgetc(man_fd);man_pos++;}
#define INDEX_SIZE()	(max_index_nr * sizeof(struct INDEX))

char ar_name[AR_NAME_SIZE];	/* name of man archive file */
char ar_index[AR_NAME_SIZE];	/* name of index file */

struct INDEX *index_buf;	/* contains indices */
struct INDEX index_record;	/* one index for build_index(); */
int max_index_nr = 0;		/* number of indices in index_buf */
static long man_pos;		/* position in manual file */

/* Forward declarations: */
static void _read_index();
static void build_index();
static int find_name();
static int find_delim();

static int index_cmp(index1, index2)
struct INDEX *index1, *index2;
{				/* used in qsort to sort the indexes read */
  int tmp;
  tmp = strncmp(index1->page_name, index2->page_name, NAME_SIZE);
  if (tmp == 0) tmp = index1 - index2;
  return(tmp);
}

extern void read_index()
{				/* read index file, if necessary creat a new
			 * one */
  int index_fd, build = 1;	/* assume to build a new index */
  struct stat name_stat, index_stat;

  stat(ar_name, &name_stat);
  if (stat(ar_index, &index_stat) == 0) {
	if (name_stat.st_mtime < index_stat.st_mtime)
		build = 0;	/* index OK */
  }
  if (build) build_index(ar_name, ar_index);

  index_fd = open(ar_index, O_RDONLY);	/* read the index */
  stat(ar_index, &index_stat);
  _read_index(index_fd, (int) index_stat.st_size);
  close(index_fd);

  if (build) {			/* write new index out to index file */
	qsort(index_buf, max_index_nr, sizeof(struct INDEX), index_cmp);
	index_fd = creat(ar_index, 0600);
	if (index_fd == -1) {
		fprintf(stderr, "can't create index\n");
		return;		/* not fatal for now */
	}
	if (write(index_fd, index_buf, INDEX_SIZE()) != INDEX_SIZE()) {
		fprintf(stderr, "write error on index file\n");
		unlink(ar_index);	/* don't leave partial index */
		return;		/* not fatal for now */
	}
	close(index_fd);
  }
}

static void _read_index(index_fd, index_size)
int index_fd;
int index_size;
{				/* allocate index buffer and read index */
  index_buf = (struct INDEX *) malloc(index_size);
  if (index_buf == NULL) {
	fprintf(stderr, "can't allocate index buffer\n");
	Exit(1);
  }
  if (read(index_fd, index_buf, index_size) != index_size) {
	fprintf(stderr, "can't read index file\n");
	Exit(1);
  }
  max_index_nr = index_size / sizeof(struct INDEX);
}

static void build_index(ar_name, ar_index)
char *ar_name, *ar_index;
{
  /* Create new index by reading manual file and recording start points
   * to new entries. thes entries are writen to index file, which is
   * later read, sorten and writen out again. use stdio buffering to
   * speed up this process. */
  FILE *man_fd, *index_fd;
  int ch;

  fprintf(stderr, "please wait, rebuilding index\n");
  man_fd = fopen(ar_name, "r");
  if (man_fd == NULL) {
	fprintf(stderr, "can't open %s\n", ar_name);
	Exit(1);
  }
  index_fd = fopen(ar_index, "w");
  if (index_fd == NULL) {
	fprintf(stderr, "can't create index file\n");
	Exit(1);
  }
  man_pos = 0L;			/* initialize page pointer */
  MAN_FGETC(ch, man_fd);
  if (ch != MAN_DELIM) ch = find_delim(man_fd, ch);

  while (ch != EOF) {
	index_record.page_pos = man_pos;
	ch = find_name(man_fd, index_fd);
	ch = find_delim(man_fd, ch);
  }
  fclose(man_fd);
  fclose(index_fd);
}

static int find_name(man_fd, index_fd)
FILE *man_fd, *index_fd;
{				/* write an index record for all names this
			 * entry is known by. these names are on the
			 * first line following the MAN_DELIM,
			 * separated by comma's. */
  int ch, name_size;

  MAN_FGETC(ch, man_fd);
  while (ch != EOF && ch != '\n') {
	name_size = 0;
	while (ch != '\n' && (isspace(ch) || ch == ','))
		MAN_FGETC(ch, man_fd);	/* read leading spaces */
	if (ch == '\n') break;

	while (!isspace(ch) && ch != ',' && ch != '\n' && ch != EOF) {
		if (ch == EOF) break;	/* read manual name */
		if (name_size < NAME_SIZE)
			index_record.page_name[name_size++] = ch;
		MAN_FGETC(ch, man_fd);
	}
	while (name_size < NAME_SIZE)	/* fill name out */
		index_record.page_name[name_size++] = '\0';

	if (index_record.page_name[0] == '\0')
		continue;	/* no manual name */

	if (fwrite(&index_record, sizeof(struct INDEX), 1, index_fd) != 1) {
		fprintf(stderr, "write error on index file\n");
		unlink(ar_index);	/* don't leave partial index */
		Exit(1);
	}
  }
  return(ch);
}

static int find_delim(man_fd, ch)
FILE *man_fd;
int ch;
{				/* find start of next manual page. this is
			 * the line on which the MAN_DELIM is the
			 * first character on that line. */
  while (ch != EOF) {
	if (ch == '\n') {	/* check for end manual page */
		MAN_FGETC(ch, man_fd);
		if (ch == MAN_DELIM) break;
	} else
		MAN_FGETC(ch, man_fd);
  }
  return(ch);
}

/* Display.c:	a file to handle the display */

#include <sgtty.h>
#include <signal.h>
/*
#include <stdio.h>
#include "index.h"
#include "display.h"
*/

int term_dialog = 0;		/* to determine if we have a terminal */
int term_clear = 0;		/* do we have to clear the terminal at exit */
int top_y = 0;			/* position of top line on screen (absolute) */
int cur_y = 0;			/* y-position on screen (absolute) */
int cur_x = 0;			/* x-position on screen (absolute) */

char *AL = "";			/* string to insert a line */
char *DL = "";			/* string to delete a line */
char *CL = "";			/* string for clearing the screen */
char *CM = "";			/* string for cursor goto code */
char *SE = "";			/* string to enter standout mode */
char *SO = "";			/* string to end standout mode */
int CO = 0;			/* number of columns on screen */
int LI = 0;			/* number of lines on screen */

static struct sgttyb termmode;	/* contains startup sgtty struct */
static int term_used = 0;	/* set when terminal is initialised */

extern char *tgetstr();

/* Forward declarations */
static void disp_all();
static void scr_down();
static void scr_up();
static void disp_fill();
static void disp_elem();
static void get_termcap();

void term_init()
{				/* initialize terminal and termcap functions */
  struct sgttyb argp;
  static int init_done = 0;
  extern void Exit();

  if (init_done || !term_dialog) return;
  get_termcap();
  setbuf(stdout, malloc(BUFSIZ));
  signal(SIGHUP, Exit);		/* we got to restore the term mode */
  signal(SIGINT, Exit);
  signal(SIGQUIT, Exit);
  signal(SIGTERM, Exit);
  ioctl(fileno(stdout), TIOCGETP, &termmode);
  argp = termmode;
  argp.sg_flags |= CBREAK;
  argp.sg_flags &= ~ECHO;
  ioctl(fileno(stdout), TIOCSETP, &argp);
  init_done = 1;
  term_used = 1;
}

void term_exit()
{
  if (term_used) ioctl(fileno(stdout), TIOCSETP, &termmode);
  if (term_used && term_clear) clrscr();
}

void display(force)
int force;
{				/* do scrolling by determining direction of
			 * scrolling */
  static int prev_y = 0;
  int diff;

  diff = prev_y - top_y;	/* determine direction */
  if (diff < 0) {
	diff = -diff;
	if (diff >= MAX_Y)
		disp_all();	/* distance to large */
	else
		scr_up(diff);
  } else if (diff == 0) {	/* no scrolling */
	if (force) disp_all();	/* redraw screen */
  } else if (diff >= MAX_Y) {
	disp_all();		/* distance to large */
  } else
	scr_down(diff);
  prev_y = top_y;		/* remember old top */
}

int gettoken()
{				/* read character from keyboard and decode
			 * cursor keys */
  int ch;

  do {
	ch = fgetc(stdin);
	if (ch == '\033') {	/* decode the cursor keys */
		ch = fgetc(stdin);
		if (ch != '[') continue;
		ch = fgetc(stdin);
		switch (ch & 0377) {
		    case 'H':	ch = CURSHOME;	break;
		    case 'A':	ch = CURSUP;	break;
		    case 'V':	ch = CURSPAGEUP;	break;
		    case 'D':	ch = CURSLEFT;	break;
		    case 'G':	ch = CURSMIDDLE;	break;
		    case 'C':	ch = CURSRIGHT;	break;
		    case 'Y':	ch = CURSEND;	break;
		    case 'B':	ch = CURSDOWN;	break;
		    case 'U':	ch = CURSPAGEDOWN;	break;
		    default:	ch = READY;	break;
		}
		if (ch != READY) return(ch);
	} else if (ch == EOF || ch == 'q' || ch == 'Q')
		return(STOP);
  } while (ch != '\n');
  return(READY);
}

void set_cursor(on)
int on;
{				/* put highlighted menu item on screen */
  if (on) reverse(1);
  disp_elem(cur_x, cur_y - top_y);
  if (on) reverse(0);
}

static void scr_up(count)
int count;
{				/* do actual moving of screen object for
			 * scrolling up */
  int i;

  GOTOXY(0, 0);
  for (i = count; i > 0; i--) fputs(DL, stdout);
  disp_fill(MAX_Y - count, MAX_Y - 1);
}

static void scr_down(count)
int count;
{				/* do actual moving of screen object for
			 * scrolling down */
  int i;

  for (i = count; i > 0; i--) {
	GOTOXY(0, MAX_Y - 1);
	fputs(DL, stdout);
	GOTOXY(0, 0);
	fputs(AL, stdout);
  }
  disp_fill(0, count - 1);
}

static void disp_all()
{				/* redraw complete screen */
  clrscr();
  disp_fill(0, MAX_Y - 1);
}

static void disp_fill(first_y, last_y)
int first_y, last_y;
{				/* fill in cleared space for scrolling with
			 * new items */
  int x, y;

  for (y = first_y; y <= last_y; y++) for (x = 0; x < MAX_X; x++)
		disp_elem(x, y);
}

static void disp_elem(x, y)
int x, y;
{				/* put one menu item on correct place on
			 * screen */
  register int i, index;

  index = (top_y + y) * MAX_X + x;
  if (index >= max_index_nr) {
	return;			/* for simplicity this check is made here */
  }
  GOTOXY(x * NAME_WIDTH, y);
  for (i = 0; i < NAME_SIZE; i++) {
	register int ch = index_buf[index].page_name[i];

	if (ch != '\0')
		putc(ch, stdout);
	else
		putc(' ', stdout);	/* fill name out */
  }
}

static void get_termcap()
{				/* initialize all needed termcap entries,
			 * assumes all entries are available. */
  static char entries[100];
  char *term_buf[1024];
  char *loc = entries;
  static int init_done = 0;

  if (init_done) return;
  init_done = 1;
  /* Read terminal capabilities */
  if (tgetent(term_buf, getenv("TERM")) <= 0) {
	fprintf(stderr, "Unknown terminal\n");
	Exit(-1);
  }
  CO = tgetnum("co");
  LI = tgetnum("li");
  AL = tgetstr("al", &loc);
  CL = tgetstr("cl", &loc);
  CM = tgetstr("cm", &loc);
  DL = tgetstr("dl", &loc);
  SE = tgetstr("se", &loc);
  SO = tgetstr("so", &loc);

  if (CO < NAME_WIDTH || LI < 1) {
	fprintf(stderr, "sorry, co or li not sufficient in termcap\n");
	Exit(-1);
  }
  if (AL == 0 || CL == 0 || CM == 0 || DL == 0 || SE == 0 || SO == 0) {
	fprintf(stderr,
		"sorry, al, cl, cm, dl, se or so not in termcap\n");
	Exit(-1);
  }
}

nfs@notecnirp.Princeton.EDU (Norbert Schlenker) (12/02/89)

In article <4658@ast.cs.vu.nl> ast@cs.vu.nl (Andy Tanenbaum) writes:
>/* man - display and manage manual pages	Author: Dick van Veen */
>...

Here are some changes to Andy's recently posted man pages.  I haven't
looked the actual pages over, so I won't comment on their individual
content.  But since the new man system has the facility to index a
particular man page under more than one name, I thought it might be
nice to make use of that fact.

With these patches applied, you can say things like "man 3 clearerr"
and get more than an error message (since clearerr is buried in the
ferror entry in the distributed pages).

I also did a manual nroff of the rename(3) entry, which appears to be
in clear in the original posting.

In deference to BITNET, these are context diffs that have been 
successively fed to shar, compress -b13, and uuencode.

Norbert

P.S. If the line justification in man1 and the lack of spacing in all
     the pages gets on your nerves too, drop me a note.  I have every
     intention of dejustifying man1 and respacing everything for myself;
     feel free to ask for a copy (if there is enough demand, I will post).

-------------------------------- Cut here --------------------------------
begin 644 changes.Z
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
)T2W*@5=]5D< 
 
end