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
35 * Ron Koenderink, 2004
56 lowerit(s_char *buf, int n, s_char *orig)
57 { /* converts a string to lower case */
58 /* lower case output buffer */
59 /* size of output buffer */
65 for (i = 0; i < n && *orig; i++) {
66 *tmp++ = tolower(*orig++);
82 s_char filename[1024];
89 name = player->argp[1];
92 * don't let sneaky people go outside the info directory
94 if (NULL != (tmp_name = strrchr(name, '/')))
100 snprintf(filename, sizeof(filename), "%s/%s", infodir, name);
101 fp = fopen(filename, "r");
103 /* may be a "partial" request. */
104 info_dp = opendir(infodir);
106 pr("Can't open info dir\n");
107 logerror("Can't open info dir \"%s\"\n", infodir);
111 while ((dp = readdir(info_dp)) != 0) {
112 if (strncasecmp(name, dp->d_name, strlen(name)) != 0)
116 snprintf(last, sizeof(last), "%s", dp->d_name);
119 pr("`%s' is ambiguous. The following topics match:\n%s",
121 width = strlen(last);
123 width += 2 + strlen(dp->d_name);
127 width = strlen(dp->d_name);
129 pr(",%c%s", sep, dp->d_name);
134 pr("Sorry, there is no info on %s\n", name);
136 } else if (nmatch > 1) {
140 snprintf(filename, sizeof(filename), "%s/%s", infodir,
142 fp = fopen(filename, "r");
144 pr("Error reading info file for %s\n", name);
145 logerror("Cannot open for \"%s\" info file (%s)",
146 filename, strerror(errno));
150 if (fstat(fileno(fp), &statb) < 0) {
151 pr("Error reading info file for %s\n", name);
152 logerror("Cannot fstat for \"%s\" info file (%s)",
153 filename, strerror(errno));
157 if ((statb.st_mode & S_IFREG) == 0) {
158 pr("Error reading info file for %s\n", name);
159 logerror("The info file \"%s\" is not regular file\n", filename);
163 pr("Information on: %s Last modification date: %s",
164 name, ctime(&statb.st_mtime));
165 while (fgets(buf, sizeof(buf), fp) != 0)
179 s_char filename[1024];
181 long nf, nhf, nl, nlhl, nhl, nll;
186 if (player->argp[1] == 0 || !*player->argp[1]) {
187 pr("Apropos what?\n");
192 if (player->argp[2]) {
193 lhitlim = atoi(player->argp[2]);
198 info_dp = opendir(infodir);
199 if (info_dp == NULL) {
200 pr("Can't open info dir \n");
201 logerror("Can't open info dir \"%s\"", infodir);
210 * lower case search string into lbp
212 name = player->argp[1];
213 lowerit(lbp, 256, name);
218 nf = nhf = nl = nhl = 0;
219 while ((dp = readdir(info_dp)) != 0) {
220 snprintf(filename, sizeof(filename), "%s/%s", infodir,
222 fp = fopen(filename, "r");
226 if (fstat(fileno(fp), &statb) < 0) {
227 logerror("Cannot stat for \"%s\" info file (%s)",
228 filename, strerror(errno));
232 if ((statb.st_mode & S_IFREG) == 0) {
233 logerror("The info file \"%s\" is not regular file\n",
238 while (fgets(fbuf, 256, fp)) {
239 lowerit(lbuf, 256, fbuf);
240 if (strstr(lbuf, lbp)) {
242 pr("*** %s ***\n", dp->d_name);
251 * break if too many lines
253 if ((nhl + nlhl) > lhitlim)
272 if ((nhl) > lhitlim) {
273 pr("Limit of %d lines exceeded\n", lhitlim);
275 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
276 name, nhf, nf, nhl, nl);
289 s_char filename[1024];
295 name = player->argp[1];
298 * don't let sneaky people go outside the info directory
300 if (NULL != (tmp_name = strrchr(name, '/')))
302 if (NULL != (tmp_name = strrchr(name, '\\')))
304 if (NULL != (tmp_name = strrchr(name, ':')))
310 _snprintf(filename, sizeof(filename) - 1, "%s\\%s", infodir, name);
311 fp = fopen(filename, "rb");
313 /* may be a "partial" request. */
315 WIN32_FIND_DATA fData;
316 strcat(filename, "*");
317 hDir = FindFirstFile(filename, &fData);
318 if (hDir == INVALID_HANDLE_VALUE) {
319 switch (GetLastError()) {
320 case ERROR_FILE_NOT_FOUND:
321 pr("Sorry, there is no info on %s\n", name);
324 case ERROR_PATH_NOT_FOUND:
325 pr("Can't open info dir\n");
326 logerror("Can't open info dir \"%s\"", infodir);
329 pr("Error reading info dir\n");
330 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
331 GetLastError(), infodir, filename);
336 if ((fData.dwFileAttributes != (DWORD)-1) &&
337 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
338 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
339 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)) &&
340 (strncasecmp(name, fData.cFileName, strlen(name)) == 0)) {
343 _snprintf(last, sizeof(last), "%s", fData.cFileName);
346 pr("`%s' is ambiguous. The following topics match:\n%s",
348 width = strlen(last);
350 width += 2 + strlen(fData.cFileName);
354 width = strlen(fData.cFileName);
356 pr(",%c%s", sep, fData.cFileName);
359 } while (FindNextFile(hDir, &fData));
362 pr("Sorry, there is no info on %s\n", name);
364 } else if (nmatch > 1) {
368 _snprintf(filename, sizeof(filename), "%s/%s",
370 fp = fopen(filename, "rb");
372 pr("Error reading info file for %s\n", name);
373 logerror("Cannot open for \"%s\" info file (%s)",
374 filename, strerror(errno));
379 DWORD fAttrib = GetFileAttributes(filename);
380 if ((fAttrib == (DWORD)-1) || /* INVALID_FILE_ATTRIBUTES */
381 ((fAttrib != FILE_ATTRIBUTE_NORMAL) &&
382 (fAttrib != FILE_ATTRIBUTE_ARCHIVE) &&
383 (fAttrib != FILE_ATTRIBUTE_READONLY))) {
384 pr("Error reading info file for %s\n", name);
385 logerror("The info file \"%s\" is not regular file\n",
392 pr("Information on: %s", name);
393 while (fgets(buf, sizeof(buf), fp) != 0)
403 WIN32_FIND_DATA fData;
408 s_char filename[1024];
409 long nf, nhf, nl, nlhl, nhl, nll;
413 if (player->argp[1] == 0 || !*player->argp[1]) {
414 pr("Apropos what?\n");
419 if (player->argp[2]) {
420 lhitlim = atoi(player->argp[2]);
425 _snprintf(filename, sizeof(filename), "%s\\*",infodir);
426 hDir = FindFirstFile(filename, &fData);
427 if (hDir == INVALID_HANDLE_VALUE) {
428 if (GetLastError() == ERROR_PATH_NOT_FOUND) {
429 pr("Can't open info dir\n");
430 logerror("Can't open info dir \"%s\"", infodir);
432 pr("Error reading info dir\n");
433 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
434 GetLastError(), infodir, filename);
444 * lower case search string into lbp
446 name = player->argp[1];
447 lowerit(lbp, 256, name);
452 nf = nhf = nl = nhl = 0;
454 if ((fData.dwFileAttributes != (DWORD)-1) &&
455 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
456 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
457 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY))) {
458 _snprintf(filename, sizeof(filename), "%s\\%s", infodir,
460 fp = fopen(filename, "rb");
464 while (fgets(fbuf, 256, fp)) {
465 lowerit(lbuf, 256, fbuf);
466 if (strstr(lbuf, lbp)) {
468 pr("*** %s ***\n", fData.cFileName);
477 * break if too many lines
479 if ((nhl + nlhl) > lhitlim)
492 } while (FindNextFile(hDir, &fData));
499 if ((nhl) > lhitlim) {
500 pr("Limit of %d lines exceeded\n", lhitlim);
502 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
503 name, nhf, nf, nhl, nl);