138589Sabial/*-
238918Sabial * Copyright (c) 1998 Eric P. Scott <eps@sirius.com>
340813Sabial * Copyright (c) 1998 Andrzej Bialecki <abial@freebsd.org>
438589Sabial * All rights reserved.
538589Sabial *
638589Sabial * Redistribution and use in source and binary forms, with or without
738589Sabial * modification, are permitted provided that the following conditions
838589Sabial * are met:
938589Sabial * 1. Redistributions of source code must retain the above copyright
1038589Sabial *    notice, this list of conditions and the following disclaimer.
1138589Sabial * 2. Redistributions in binary form must reproduce the above copyright
1238589Sabial *    notice, this list of conditions and the following disclaimer in the
1338589Sabial *    documentation and/or other materials provided with the distribution.
1438589Sabial *
1538589Sabial * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1638589Sabial * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1738589Sabial * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1838589Sabial * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1938589Sabial * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2038589Sabial * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2138589Sabial * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2238589Sabial * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2338589Sabial * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2438589Sabial * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2538589Sabial * SUCH DAMAGE.
2638589Sabial *
2750479Speter * $FreeBSD$
2838589Sabial */
2938589Sabial
3038589Sabial
3138589Sabial#include <stdio.h>
3238589Sabial#include <string.h>
3338918Sabial#include <ar.h>
3438918Sabial#include <sys/ioctl.h>
3538589Sabial
3638918Sabialint display(FILE *, const char *);
3738918Sabial
3838918Sabialstatic int cnt, crt=-1;
3938918Sabial
4038918Sabialint
4138918Sabialmain(int argc, char *argv[])
4238589Sabial{
4338918Sabial	register int i, s;
4438589Sabial	FILE *fd;
4538918Sabial	struct ttysize ts;
4638589Sabial
4738918Sabial	if (!(fd=fopen("/help.a", "r"))) {
4838918Sabial		(void)fputs("Couldn't open help archive.\n", stderr);
4938589Sabial		exit(1);
5038589Sabial	}
5138918Sabial	cnt=0;
5238918Sabial	if (ioctl(fileno(stdout), TIOCGWINSZ, &ts)>=0) {
5338918Sabial		crt=ts.ts_lines-1;
5438589Sabial	}
5538918Sabial	if (crt<3) crt=23;
5638918Sabial	s=display(fd, argc>1 ? argv[1] : "help");
5738918Sabial	if (s<0) s=0;
5838918Sabial	else for (i=2;i<argc;) {
5938918Sabial		rewind(fd);
6038918Sabial		s|=display(fd, argv[i++]);
6138918Sabial		if (s<0) {
6238918Sabial			s=0;
6338918Sabial			break;
6438589Sabial		}
6538589Sabial	}
6638918Sabial	(void)fclose(fd);
6738918Sabial	exit(s);
6838589Sabial}
6938589Sabial
7038918Sabialint
7138918Sabialmore(void)
7238918Sabial{
7338918Sabial	char buf[8];
7438589Sabial
7538918Sabial	(void)fflush(stdout);
7638918Sabial	(void)fputs("\033[7mPress Enter to continue\033[m", stderr);
7738918Sabial	(void)fflush(stderr);
7838918Sabial	cnt=0;
7938918Sabial	if (fgets(buf, sizeof buf, stdin)) return 0;
8038918Sabial	(void)fputc('\n', stderr);
8138918Sabial	return 1;
8238918Sabial}
8338918Sabial
8438589Sabialint
8538918Sabialdisplay(FILE *fd, const char *fname)
8638589Sabial{
8738918Sabial	register char *p;
8838918Sabial	register int c, n, o;
8938918Sabial	struct ar_hdr ar;
9038918Sabial	char aname[20];
9138918Sabial
9238918Sabial	if (!fgets(aname, sizeof aname, fd)) {
9338918Sabial		return 1;
9438589Sabial	}
9538918Sabial	if (strncmp(aname, ARMAG, SARMAG)) return 1;
9639599Sabial	(void)snprintf(aname, sizeof(aname), "%s/", fname);
9738918Sabial	for (;;) {
9838918Sabial		if (fread((void *)&ar, sizeof ar, 1, fd)!=1) return 1;
9938918Sabial		if (strncmp(ar.ar_fmag, ARFMAG, 2)) return 1;
10038918Sabial		n=0;
10138918Sabial		p=ar.ar_size;
10238918Sabial		do {
10338918Sabial			if ((c=(int)(*p++-'0'))<0||c>9) break;
10438918Sabial			n*=10; n+=c;
10538918Sabial		} while (p<&ar.ar_size[sizeof ar.ar_size]);
10639599Sabial		if (!strncmp(ar.ar_name, aname, strlen(aname))) break;
10738918Sabial		if (fseek(fd, (long)n, SEEK_CUR)<0) return 1;
10838918Sabial		if ((n&1)&&fgetc(fd)!='\n') return 1;
10938918Sabial	}
11038918Sabial	if (cnt>=crt&&more()) return -1;
11138918Sabial	(void)fputc('\n', stdout);
11238918Sabial	cnt++;
11338918Sabial	o=0; while (o<n&&(c=fgetc(fd))!=EOF) {
11438918Sabial	per:
11538918Sabial		o++;
11638918Sabial		(void)fputc(c, stdout);
11738918Sabial		if (c!='\n') continue;
11838918Sabial		if (++cnt<crt) continue;
11938918Sabial		if (o>=n||(c=fgetc(fd))==EOF) break;
12038918Sabial		if (more()) return -1;
12138918Sabial		goto per;
12238918Sabial	}
12338918Sabial	if (cnt>=crt&&more()) return -1;
12438918Sabial	(void)fputc('\n', stdout);
12538918Sabial	cnt++;
12638918Sabial	if (!strcmp(fname, "help")) {
12738918Sabial		rewind(fd);
12838918Sabial		(void)fgets(aname, sizeof aname, fd);
12938918Sabial		if (cnt>=crt&&more()) return -1;
13038918Sabial		(void)fputs("The following help items are available:\n",
13138918Sabial			stdout);
13238918Sabial		cnt++;
13338918Sabial		o=0;
13438918Sabial		while (fread((void *)&ar, sizeof ar, 1, fd)==1) {
13538918Sabial			if (strncmp(ar.ar_fmag, ARFMAG, 2)) break;
13638918Sabial			if ((o%6)==0) {
13738918Sabial				(void)fputc('\n', stdout);
13838918Sabial				if (++cnt>=crt&&more()) return -1;
13938918Sabial			}
14039599Sabial			*(index(ar.ar_name,'/'))=' ';
14138918Sabial			(void)printf("%.13s", ar.ar_name);
14238918Sabial			++o;
14338918Sabial			n=0;
14438918Sabial			p=ar.ar_size;
14538918Sabial			do {
14638918Sabial				if ((c=(int)(*p++-'0'))<0||c>9) break;
14738918Sabial				n*=10; n+=c;
14838918Sabial			} while (p<&ar.ar_size[sizeof ar.ar_size]);
14938918Sabial			if (fseek(fd, (long)n, SEEK_CUR)<0) break;
15038918Sabial			if ((n&1)&&fgetc(fd)!='\n') break;
15138918Sabial		}
15238918Sabial		if (cnt>=crt&&more()) return -1;
15338918Sabial		(void)fputc('\n', stdout);
15438918Sabial		cnt++;
15538918Sabial	}
15638918Sabial	return 0;
15738589Sabial}
158