2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2012, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure, Markus Armbruster
6 * Empire is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * See files README, COPYING and CREDITS in the root of the source
22 * tree for related information and legal notices. It is expected
23 * that future projects/authors will amend these files as needed.
27 * info.c: display an info page
29 * Known contributors to this file:
31 * Mike Wise, 1997 - added apropos and case insensitivity
33 * Steve McClure, 1998-2000
34 * Ron Koenderink, 2004
50 lowerit(char *buf, int n, char *orig)
51 { /* converts a string to lower case */
52 /* lower case output buffer */
53 /* size of output buffer */
56 for (i = 0; i < n - 1 && orig[i]; i++)
57 buf[i] = tolower(orig[i]);
80 name = player->argp[1];
83 * don't let sneaky people go outside the info directory
85 if (NULL != (tmp_name = strrchr(name, '/')))
91 snprintf(filename, sizeof(filename), "%s/%s", infodir, name);
92 fp = fopen(filename, "r");
94 /* may be a "partial" request. */
95 info_dp = opendir(infodir);
97 pr("Can't open info dir\n");
98 logerror("Can't open info dir \"%s\"\n", infodir);
102 while ((dp = readdir(info_dp))) {
103 if (strncasecmp(name, dp->d_name, strlen(name)) != 0)
107 snprintf(last, sizeof(last), "%s", dp->d_name);
110 pr("`%s' is ambiguous. The following topics match:\n%s",
112 width = strlen(last);
114 width += 2 + strlen(dp->d_name);
118 width = strlen(dp->d_name);
120 pr(",%c%s", sep, dp->d_name);
125 pr("Sorry, there is no info on %s\n", name);
127 } else if (nmatch > 1) {
131 snprintf(filename, sizeof(filename), "%s/%s", infodir, last);
132 fp = fopen(filename, "r");
134 pr("Error reading info file for %s\n", name);
135 logerror("Cannot open for \"%s\" info file (%s)",
136 filename, strerror(errno));
140 if (fstat(fileno(fp), &statb) < 0) {
141 pr("Error reading info file for %s\n", name);
142 logerror("Cannot fstat for \"%s\" info file (%s)",
143 filename, strerror(errno));
147 if ((statb.st_mode & S_IFREG) == 0) {
148 pr("Error reading info file for %s\n", name);
149 logerror("The info file \"%s\" is not regular file\n", filename);
154 while (fgets(buf, sizeof(buf), fp))
170 long nf, nhf, nl, nlhl, nhl, nll;
175 if (!player->argp[1] || !*player->argp[1]) {
176 pr("Apropos what?\n");
181 if (player->argp[2]) {
182 lhitlim = atoi(player->argp[2]);
187 info_dp = opendir(infodir);
188 if (info_dp == NULL) {
189 pr("Can't open info dir \n");
190 logerror("Can't open info dir \"%s\"", infodir);
199 * lower case search string into lbp
201 name = player->argp[1];
202 lowerit(lbp, 256, name);
207 nf = nhf = nl = nhl = 0;
208 while ((dp = readdir(info_dp))) {
209 if (dp->d_name[0] == '.')
211 snprintf(filename, sizeof(filename), "%s/%s", infodir, dp->d_name);
212 fp = fopen(filename, "r");
216 if (fstat(fileno(fp), &statb) < 0) {
217 logerror("Cannot stat for \"%s\" info file (%s)",
218 filename, strerror(errno));
222 if ((statb.st_mode & S_IFREG) == 0) {
223 logerror("The info file \"%s\" is not regular file\n",
228 while (fgets(fbuf, 256, fp)) {
229 lowerit(lbuf, 256, fbuf);
230 if (strstr(lbuf, lbp)) {
232 pr("*** %s ***\n", dp->d_name);
241 * break if too many lines
243 if ((nhl + nlhl) > lhitlim)
262 if ((nhl) > lhitlim) {
263 pr("Limit of %d lines exceeded\n", lhitlim);
265 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
266 name, nhf, nf, nhl, nl);
285 name = player->argp[1];
288 * don't let sneaky people go outside the info directory
290 if (NULL != (tmp_name = strrchr(name, '/')))
292 if (NULL != (tmp_name = strrchr(name, '\\')))
294 if (NULL != (tmp_name = strrchr(name, ':')))
300 snprintf(filename, sizeof(filename) - 1, "%s\\%s", infodir, name);
301 fp = fopen(filename, "rb");
303 /* may be a "partial" request. */
305 WIN32_FIND_DATA fData;
306 strcat(filename, "*");
307 hDir = FindFirstFile(filename, &fData);
308 if (hDir == INVALID_HANDLE_VALUE) {
309 switch (GetLastError()) {
310 case ERROR_FILE_NOT_FOUND:
311 pr("Sorry, there is no info on %s\n", name);
313 case ERROR_PATH_NOT_FOUND:
314 pr("Can't open info dir\n");
315 logerror("Can't open info dir \"%s\"", infodir);
318 pr("Error reading info dir\n");
319 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
320 GetLastError(), infodir, filename);
325 if ((fData.dwFileAttributes != (DWORD)-1) &&
326 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
327 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
328 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)) &&
329 (strncasecmp(name, fData.cFileName, strlen(name)) == 0)) {
332 snprintf(last, sizeof(last), "%s", fData.cFileName);
335 pr("`%s' is ambiguous. The following topics match:\n%s",
337 width = strlen(last);
339 width += 2 + strlen(fData.cFileName);
343 width = strlen(fData.cFileName);
345 pr(",%c%s", sep, fData.cFileName);
348 } while (FindNextFile(hDir, &fData));
351 pr("Sorry, there is no info on %s\n", name);
353 } else if (nmatch > 1) {
357 snprintf(filename, sizeof(filename), "%s/%s", infodir, last);
358 fp = fopen(filename, "rb");
360 pr("Error reading info file for %s\n", name);
361 logerror("Cannot open for \"%s\" info file (%s)",
362 filename, strerror(errno));
366 DWORD fAttrib = GetFileAttributes(filename);
367 if ((fAttrib == (DWORD)-1) || /* INVALID_FILE_ATTRIBUTES */
368 ((fAttrib != FILE_ATTRIBUTE_NORMAL) &&
369 (fAttrib != FILE_ATTRIBUTE_ARCHIVE) &&
370 (fAttrib != FILE_ATTRIBUTE_READONLY))) {
371 pr("Error reading info file for %s\n", name);
372 logerror("The info file \"%s\" is not regular file\n",
379 while (fgets(buf, sizeof(buf), fp) != 0)
389 WIN32_FIND_DATA fData;
395 long nf, nhf, nl, nlhl, nhl, nll;
399 if (player->argp[1] == 0 || !*player->argp[1]) {
400 pr("Apropos what?\n");
405 if (player->argp[2]) {
406 lhitlim = atoi(player->argp[2]);
411 snprintf(filename, sizeof(filename), "%s\\*", infodir);
412 hDir = FindFirstFile(filename, &fData);
413 if (hDir == INVALID_HANDLE_VALUE) {
414 if (GetLastError() == ERROR_PATH_NOT_FOUND) {
415 pr("Can't open info dir\n");
416 logerror("Can't open info dir \"%s\"", infodir);
418 pr("Error reading info dir\n");
419 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
420 GetLastError(), infodir, filename);
430 * lower case search string into lbp
432 name = player->argp[1];
433 lowerit(lbp, 256, name);
438 nf = nhf = nl = nhl = 0;
440 if ((fData.dwFileAttributes != (DWORD)-1) &&
441 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
442 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
443 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY))) {
444 snprintf(filename, sizeof(filename), "%s\\%s", infodir,
446 fp = fopen(filename, "rb");
450 while (fgets(fbuf, 256, fp)) {
451 lowerit(lbuf, 256, fbuf);
452 if (strstr(lbuf, lbp)) {
454 pr("*** %s ***\n", fData.cFileName);
463 * break if too many lines
465 if ((nhl + nlhl) > lhitlim)
478 } while (FindNextFile(hDir, &fData));
485 if ((nhl) > lhitlim) {
486 pr("Limit of %d lines exceeded\n", lhitlim);
488 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
489 name, nhf, nf, nhl, nl);