Initial import from FreeBSD RELENG_4:
[dragonfly.git] / release / picobsd / tinyware / help / help.c
1 /*-
2  * Copyright (c) 1998 Eric P. Scott <eps@sirius.com>
3  * Copyright (c) 1998 Andrzej Bialecki <abial@freebsd.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD: src/release/picobsd/tinyware/help/help.c,v 1.5 1999/08/28 01:33:54 peter Exp $
28  */
29
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <ar.h>
34 #include <sys/ioctl.h>
35
36 int display(FILE *, const char *);
37
38 static int cnt, crt=-1;
39
40 int
41 main(int argc, char *argv[])
42 {
43         register int i, s;
44         FILE *fd;
45         struct ttysize ts;
46
47         if (!(fd=fopen("/help.a", "r"))) {
48                 (void)fputs("Couldn't open help archive.\n", stderr);
49                 exit(1);
50         }
51         cnt=0;
52         if (ioctl(fileno(stdout), TIOCGWINSZ, &ts)>=0) {
53                 crt=ts.ts_lines-1;
54         }
55         if (crt<3) crt=23;
56         s=display(fd, argc>1 ? argv[1] : "help");
57         if (s<0) s=0;
58         else for (i=2;i<argc;) {
59                 rewind(fd);
60                 s|=display(fd, argv[i++]);
61                 if (s<0) {
62                         s=0;
63                         break;
64                 }
65         }
66         (void)fclose(fd);
67         exit(s);
68 }
69
70 int
71 more(void)
72 {
73         char buf[8];
74
75         (void)fflush(stdout);
76         (void)fputs("\033[7mPress Enter to continue\033[m", stderr);
77         (void)fflush(stderr);
78         cnt=0;
79         if (fgets(buf, sizeof buf, stdin)) return 0;
80         (void)fputc('\n', stderr);
81         return 1;
82 }
83
84 int
85 display(FILE *fd, const char *fname)
86 {
87         register char *p;
88         register int c, n, o;
89         struct ar_hdr ar;
90         char aname[20];
91
92         if (!fgets(aname, sizeof aname, fd)) {
93                 return 1;
94         }
95         if (strncmp(aname, ARMAG, SARMAG)) return 1;
96         (void)snprintf(aname, sizeof(aname), "%s/", fname);
97         for (;;) {
98                 if (fread((void *)&ar, sizeof ar, 1, fd)!=1) return 1;
99                 if (strncmp(ar.ar_fmag, ARFMAG, 2)) return 1;
100                 n=0;
101                 p=ar.ar_size;
102                 do {
103                         if ((c=(int)(*p++-'0'))<0||c>9) break;
104                         n*=10; n+=c;
105                 } while (p<&ar.ar_size[sizeof ar.ar_size]);
106                 if (!strncmp(ar.ar_name, aname, strlen(aname))) break;
107                 if (fseek(fd, (long)n, SEEK_CUR)<0) return 1;
108                 if ((n&1)&&fgetc(fd)!='\n') return 1;
109         }
110         if (cnt>=crt&&more()) return -1;
111         (void)fputc('\n', stdout);
112         cnt++;
113         o=0; while (o<n&&(c=fgetc(fd))!=EOF) {
114         per:
115                 o++;
116                 (void)fputc(c, stdout);
117                 if (c!='\n') continue;
118                 if (++cnt<crt) continue;
119                 if (o>=n||(c=fgetc(fd))==EOF) break;
120                 if (more()) return -1;
121                 goto per;
122         }
123         if (cnt>=crt&&more()) return -1;
124         (void)fputc('\n', stdout);
125         cnt++;
126         if (!strcmp(fname, "help")) {
127                 rewind(fd);
128                 (void)fgets(aname, sizeof aname, fd);
129                 if (cnt>=crt&&more()) return -1;
130                 (void)fputs("The following help items are available:\n",
131                         stdout);
132                 cnt++;
133                 o=0;
134                 while (fread((void *)&ar, sizeof ar, 1, fd)==1) {
135                         if (strncmp(ar.ar_fmag, ARFMAG, 2)) break;
136                         if ((o%6)==0) {
137                                 (void)fputc('\n', stdout);
138                                 if (++cnt>=crt&&more()) return -1;
139                         }
140                         *(index(ar.ar_name,'/'))=' ';
141                         (void)printf("%.13s", ar.ar_name);
142                         ++o;
143                         n=0;
144                         p=ar.ar_size;
145                         do {
146                                 if ((c=(int)(*p++-'0'))<0||c>9) break;
147                                 n*=10; n+=c;
148                         } while (p<&ar.ar_size[sizeof ar.ar_size]);
149                         if (fseek(fd, (long)n, SEEK_CUR)<0) break;
150                         if ((n&1)&&fgetc(fd)!='\n') break;
151                 }
152                 if (cnt>=crt&&more()) return -1;
153                 (void)fputc('\n', stdout);
154                 cnt++;
155         }
156         return 0;
157 }