1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License ("CDDL"), version 1.0.
6 * You may use this file only in accordance with the terms of version
7 * 1.0 of the CDDL.
8 *
9 * A full copy of the text of the CDDL should have accompanied this
10 * source. A copy of the CDDL is also available via the Internet at
11 * http://www.opensource.org/licenses/cddl1.txt
12 * See the License for the specific language governing permissions
13 * and limitations under the License.
14 *
15 * When distributing Covered Code, include this CDDL HEADER in each
16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 * If applicable, add the following below this CDDL HEADER, with the
18 * fields enclosed by brackets "[]" replaced with your own identifying
19 * information: Portions Copyright [yyyy] [name of copyright owner]
20 *
21 * CDDL HEADER END
22 */
23 /* Copyright (c) 1988 AT&T */
24 /* All Rights Reserved */
25 /*
26 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
28 */
29 /*
30 * Copyright 2006-2020 J. Schilling
31 *
32 * @(#)help.c 1.13 20/06/01 J. Schilling
33 */
34 #if defined(sun)
35 #pragma ident "@(#)help.c 1.13 20/06/01 J. Schilling"
36 #endif
37 /*
38 * @(#)help2.c 1.10 06/12/12
39 */
40
41 #if defined(sun)
42 #pragma ident "@(#)help.c"
43 #pragma ident "@(#)sccs:cmd/help.c"
44 #endif
45 #include <defines.h>
46 #include <i18n.h>
47 #include <ccstypes.h>
48
49 /*
50 * Program to locate helpful info in an ascii file.
51 * The program accepts a variable number of arguments.
52 *
53 * I18N changes are as follows:
54 *
55 * First determine the appropriate directory to search for help text
56 * files corresponding to the user's locale. Consistent with the
57 * setlocale() routine algorithm, environment variables are here
58 * searched in the following order of descending priority: LC_ALL,
59 * LC_MESSAGES, LANG. The first one found to be defined is used
60 * as the locale for help messages. If this directory does in fact
61 * not exist, a fallback to the (default) "C" locale is done.
62 *
63 * The file to be searched is determined from the argument. If the
64 * argument does not contain numerics, the search
65 * will be attempted on '/usr/ccs/lib/help/cmds', with the search key
66 * being the whole argument. This is used for SCCS command help.
67 *
68 * If the argument begins with non-numerics but contains
69 * numerics (e.g, zz32) the file /usr/ccs/lib/help/helploc
70 * will be checked for a file corresponding to the non numeric prefix,
71 * That file will then be seached for the mesage. If
72 * /usr/ccs/lib/help/helploc
73 * does not exist or the prefix is not found there the search will
74 * be attempted on '/usr/ccs/lib/help/<non-numeric prefix>',
75 * (e.g., /usr/ccs/lib/help/zz), with the search key
76 * being <remainder of arg>, (e.g., 32).
77 * If the argument is all numeric, or if the file as
78 * determined above does not exist, the search will be attempted on
79 * '/usr/ccs/lib/help/default' with the search key being
80 * the entire argument.
81 * In no case will more than one search per argument be performed.
82 *
83 * File is formatted as follows:
84 *
85 * * comment
86 * * comment
87 * -str1
88 * text
89 * -str2
90 * text
91 * * comment
92 * text
93 * -str3
94 * text
95 *
96 * The "str?" that matches the key is found and
97 * the following text lines are printed.
98 * Comments are ignored.
99 *
100 * If the argument is omitted, the program requests it.
101 */
102
103
104 int main __PR((int argc, char **argv));
105 static char *ask __PR((void));
106
107
108 int
main(argc,argv)109 main(argc, argv)
110 int argc;
111 char *argv[];
112 {
113 register int i;
114 int numerrs = 0;
115 #ifdef PROTOTYPES
116 char default_locale[] = NOGETTEXT("C"); /* Default English. */
117 #else
118 char *default_locale = NOGETTEXT("C"); /* Default English. */
119 #endif
120 char *helpdir = NOGETTEXT("/" SCCS_BIN_PRE "lib/help/locale/");
121 char help_dir[200]; /* Directory to search for help text. */
122 char *locale = NULL; /* User's locale. */
123
124
125 /*
126 * Set locale for all categories.
127 */
128 setlocale(LC_ALL, NOGETTEXT(""));
129
130 sccs_setinsbase(INS_BASE);
131
132 #ifdef LC_MESSAGES
133 /*
134 * Returns the locale value for the LC_MESSAGES category. This
135 * will be used to set the path to retrieve the appropriate
136 * help files in "/.../help.d/locale/<locale>".
137 */
138 locale = setlocale(LC_MESSAGES, NOGETTEXT(""));
139 if (locale == NULL) {
140 locale = default_locale;
141 }
142 #else
143 locale = default_locale;
144 #endif
145
146 /*
147 * Set directory to search for general l10n SCCS messages.
148 */
149 #ifdef PROTOTYPES
150 (void) bindtextdomain(NOGETTEXT("SUNW_SPRO_SCCS"),
151 NOGETTEXT(INS_BASE "/" SCCS_BIN_PRE "lib/locale/"));
152 #else
153 (void) bindtextdomain(NOGETTEXT("SUNW_SPRO_SCCS"),
154 NOGETTEXT("/usr/ccs/lib/locale/"));
155 #endif
156 (void) textdomain(NOGETTEXT("SUNW_SPRO_SCCS"));
157
158 #ifdef SCHILY_BUILD
159 save_args(argc, argv);
160 #endif
161 Fflags = FTLMSG;
162 #ifdef SCCS_FATALHELP
163 Fflags |= FTLFUNC;
164 Ffunc = sccsfatalhelp;
165 #endif
166
167 /*
168 * Set directory to search for SCCS help text, not general
169 * message text wrapped with "gettext()".
170 */
171 strlcpy(help_dir, sccs_insbase?sccs_insbase:"/usr", sizeof (help_dir));
172 strlcat(help_dir, helpdir, sizeof (help_dir));
173 strlcat(help_dir, locale, sizeof (help_dir));
174
175 /*
176 * The text of the printf statement below should not be wrapped
177 * with gettext(). Since we don't know what the locale is, we
178 * don't know how to get the proper translation text.
179 */
180 if (stat(help_dir, &Statbuf) != 0) { /* Does help directory exist? */
181 printf(gettext(
182 "No help for locale '%s' ... setting to English.\n"),
183 locale);
184 }
185
186 if (argc == 1) {
187 char *he = ask();
188 if (*he == '\0') {
189 numerrs += sccshelp(stdout, "intro");
190 } else {
191 numerrs += sccshelp(stdout, he);
192 }
193 } else {
194 for (i = 1; i < argc; i++)
195 numerrs += sccshelp(stdout, argv[i]);
196 }
197 return ((numerrs == (argc-1)) ? 1 : 0);
198 }
199
200 static char *
ask()201 ask()
202 {
203 static char resp[51];
204 FILE *iop;
205
206 iop = stdin;
207
208 printf(gettext("Enter the message number or SCCS command name: "));
209 fgets(resp, sizeof (resp), iop);
210 return (repl(resp, '\n', '\0'));
211 }
212