2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program 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 2 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future projects/authors will amend these files as needed.
28 * info.c: display an info page
30 * Known contributors to this file:
32 * Mike Wise, 1997 - added apropos and case insensitivity
34 * Steve McClure, 1998-2000
55 lowerit(s_char *buf, int n, s_char *orig)
56 { /* converts a string to lower case */
57 /* lower case output buffer */
58 /* size of output buffer */
64 for (i = 0; i < n && *orig; i++) {
65 *tmp++ = tolower(*orig++);
81 s_char filename[1024];
88 name = player->argp[1];
91 * don't let sneaky people go outside the info directory
93 if (NULL != (tmp_name = strrchr(name, '/')))
99 snprintf(filename, sizeof(filename), "%s/%s", infodir, name);
100 fp = fopen(filename, "r");
102 /* may be a "partial" request. */
103 info_dp = opendir(infodir);
105 pr("Can't open info dir\n");
106 logerror("Can't open info dir \"%s\"\n", infodir);
110 while ((dp = readdir(info_dp)) != 0) {
111 if (strncasecmp(name, dp->d_name, strlen(name)) != 0)
115 snprintf(last, sizeof(last), "%s", dp->d_name);
118 pr("`%s' is ambiguous. The following topics match:\n%s",
120 width = strlen(last);
122 width += 2 + strlen(dp->d_name);
126 width = strlen(dp->d_name);
128 pr(",%c%s", sep, dp->d_name);
133 pr("Sorry, there is no info on %s\n", name);
135 } else if (nmatch > 1) {
139 snprintf(filename, sizeof(filename), "%s/%s", infodir,
141 fp = fopen(filename, "r");
143 pr("Error reading info file for %s\n", name);
144 logerror("Cannot open for \"%s\" info file (%s)",
145 filename, strerror(errno));
149 if (fstat(fileno(fp), &statb) < 0) {
150 pr("Error reading info file for %s\n", name);
151 logerror("Cannot fstat for \"%s\" info file (%s)",
152 filename, strerror(errno));
156 if ((statb.st_mode & S_IFREG) == 0) {
157 pr("Error reading info file for %s\n", name);
158 logerror("The info file \"%s\" is not regular file\n", filename);
162 pr("Information on: %s Last modification date: %s",
163 name, ctime(&statb.st_mtime));
164 while (fgets(buf, sizeof(buf), fp) != 0)
178 s_char filename[1024];
180 long nf, nhf, nl, nlhl, nhl, nll;
185 if (player->argp[1] == 0 || !*player->argp[1]) {
186 pr("Apropos what?\n");
191 if (player->argp[2]) {
192 lhitlim = atoi(player->argp[2]);
197 info_dp = opendir(infodir);
198 if (info_dp == NULL) {
199 pr("Can't open info dir \n");
200 logerror("Can't open info dir \"%s\"", infodir);
209 * lower case search string into lbp
211 name = player->argp[1];
212 lowerit(lbp, 256, name);
217 nf = nhf = nl = nhl = 0;
218 while ((dp = readdir(info_dp)) != 0) {
219 snprintf(filename, sizeof(filename), "%s/%s", infodir,
221 fp = fopen(filename, "r");
225 if (fstat(fileno(fp), &statb) < 0) {
226 logerror("Cannot stat for \"%s\" info file (%s)",
227 filename, strerror(errno));
231 if ((statb.st_mode & S_IFREG) == 0) {
232 logerror("The info file \"%s\" is not regular file\n",
237 while (fgets(fbuf, 256, fp)) {
238 lowerit(lbuf, 256, fbuf);
239 if (strstr(lbuf, lbp)) {
241 pr("*** %s ***\n", dp->d_name);
250 * break if too many lines
252 if ((nhl + nlhl) > lhitlim)
271 if ((nhl) > lhitlim) {
272 pr("Limit of %d lines exceeded\n", lhitlim);
274 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
275 name, nhf, nf, nhl, nl);
288 s_char filename[1024];
294 name = player->argp[1];
297 * don't let sneaky people go outside the info directory
299 if (NULL != (tmp_name = strrchr(name, '/')))
301 if (NULL != (tmp_name = strrchr(name, '\\')))
303 if (NULL != (tmp_name = strrchr(name, ':')))
309 _snprintf(filename, sizeof(filename) - 1, "%s\\%s", infodir, name);
310 fp = fopen(filename, "rb");
312 /* may be a "partial" request. */
314 WIN32_FIND_DATA fData;
315 strcat(filename, "*");
316 hDir = FindFirstFile(filename, &fData);
317 if (hDir == INVALID_HANDLE_VALUE) {
318 switch (GetLastError()) {
319 case ERROR_FILE_NOT_FOUND:
320 pr("Sorry, there is no info on %s\n", name);
323 case ERROR_PATH_NOT_FOUND:
324 pr("Can't open info dir\n");
325 logerror("Can't open info dir \"%s\"", infodir);
328 pr("Error reading info dir\n");
329 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
330 GetLastError(), infodir, filename);
335 if ((fData.dwFileAttributes != (DWORD)-1) &&
336 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
337 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
338 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)) &&
339 (strncasecmp(name, fData.cFileName, strlen(name)) == 0)) {
342 _snprintf(last, sizeof(last), "%s", fData.cFileName);
345 pr("`%s' is ambiguous. The following topics match:\n%s",
347 width = strlen(last);
349 width += 2 + strlen(fData.cFileName);
353 width = strlen(fData.cFileName);
355 pr(",%c%s", sep, fData.cFileName);
358 } while (FindNextFile(hDir, &fData));
361 pr("Sorry, there is no info on %s\n", name);
363 } else if (nmatch > 1) {
367 _snprintf(filename, sizeof(filename), "%s/%s",
369 fp = fopen(filename, "rb");
371 pr("Error reading info file for %s\n", name);
372 logerror("Cannot open for \"%s\" info file (%s)",
373 filename, strerror(errno));
378 DWORD fAttrib = GetFileAttributes(filename);
379 if ((fAttrib == (DWORD)-1) || /* INVALID_FILE_ATTRIBUTES */
380 ((fAttrib != FILE_ATTRIBUTE_NORMAL) &&
381 (fAttrib != FILE_ATTRIBUTE_ARCHIVE) &&
382 (fAttrib != FILE_ATTRIBUTE_READONLY))) {
383 pr("Error reading info file for %s\n", name);
384 logerror("The info file \"%s\" is not regular file\n",
391 pr("Information on: %s", name);
392 while (fgets(buf, sizeof(buf), fp) != 0)
402 WIN32_FIND_DATA fData;
407 s_char filename[1024];
408 long nf, nhf, nl, nlhl, nhl, nll;
412 if (player->argp[1] == 0 || !*player->argp[1]) {
413 pr("Apropos what?\n");
418 if (player->argp[2]) {
419 lhitlim = atoi(player->argp[2]);
424 _snprintf(filename, sizeof(filename), "%s\\*",infodir);
425 hDir = FindFirstFile(filename, &fData);
426 if (hDir == INVALID_HANDLE_VALUE) {
427 if (GetLastError() == ERROR_PATH_NOT_FOUND) {
428 pr("Can't open info dir\n");
429 logerror("Can't open info dir \"%s\"", infodir);
431 pr("Error reading info dir\n");
432 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
433 GetLastError(), infodir, filename);
443 * lower case search string into lbp
445 name = player->argp[1];
446 lowerit(lbp, 256, name);
451 nf = nhf = nl = nhl = 0;
453 if ((fData.dwFileAttributes != (DWORD)-1) &&
454 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
455 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
456 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY))) {
457 _snprintf(filename, sizeof(filename), "%s\\%s", infodir,
459 fp = fopen(filename, "rb");
463 while (fgets(fbuf, 256, fp)) {
464 lowerit(lbuf, 256, fbuf);
465 if (strstr(lbuf, lbp)) {
467 pr("*** %s ***\n", fData.cFileName);
476 * break if too many lines
478 if ((nhl + nlhl) > lhitlim)
491 } while (FindNextFile(hDir, &fData));
498 if ((nhl) > lhitlim) {
499 pr("Limit of %d lines exceeded\n", lhitlim);
501 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
502 name, nhf, nf, nhl, nl);