2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2005, 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 the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * 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
52 lowerit(s_char *buf, int n, s_char *orig)
53 { /* converts a string to lower case */
54 /* lower case output buffer */
55 /* size of output buffer */
61 for (i = 0; i < n && *orig; i++) {
62 *tmp++ = tolower(*orig++);
78 s_char filename[1024];
85 name = player->argp[1];
88 * don't let sneaky people go outside the info directory
90 if (NULL != (tmp_name = strrchr(name, '/')))
96 snprintf(filename, sizeof(filename), "%s/%s", infodir, name);
97 fp = fopen(filename, "r");
99 /* may be a "partial" request. */
100 info_dp = opendir(infodir);
102 pr("Can't open info dir\n");
103 logerror("Can't open info dir \"%s\"\n", infodir);
107 while ((dp = readdir(info_dp)) != 0) {
108 if (strncasecmp(name, dp->d_name, strlen(name)) != 0)
112 snprintf(last, sizeof(last), "%s", dp->d_name);
115 pr("`%s' is ambiguous. The following topics match:\n%s",
117 width = strlen(last);
119 width += 2 + strlen(dp->d_name);
123 width = strlen(dp->d_name);
125 pr(",%c%s", sep, dp->d_name);
130 pr("Sorry, there is no info on %s\n", name);
132 } else if (nmatch > 1) {
136 snprintf(filename, sizeof(filename), "%s/%s", infodir,
138 fp = fopen(filename, "r");
140 pr("Error reading info file for %s\n", name);
141 logerror("Cannot open for \"%s\" info file (%s)",
142 filename, strerror(errno));
146 if (fstat(fileno(fp), &statb) < 0) {
147 pr("Error reading info file for %s\n", name);
148 logerror("Cannot fstat for \"%s\" info file (%s)",
149 filename, strerror(errno));
153 if ((statb.st_mode & S_IFREG) == 0) {
154 pr("Error reading info file for %s\n", name);
155 logerror("The info file \"%s\" is not regular file\n", filename);
159 pr("Information on: %s Last modification date: %s",
160 name, ctime(&statb.st_mtime));
161 while (fgets(buf, sizeof(buf), fp) != 0)
175 s_char filename[1024];
177 long nf, nhf, nl, nlhl, nhl, nll;
182 if (player->argp[1] == 0 || !*player->argp[1]) {
183 pr("Apropos what?\n");
188 if (player->argp[2]) {
189 lhitlim = atoi(player->argp[2]);
194 info_dp = opendir(infodir);
195 if (info_dp == NULL) {
196 pr("Can't open info dir \n");
197 logerror("Can't open info dir \"%s\"", infodir);
206 * lower case search string into lbp
208 name = player->argp[1];
209 lowerit(lbp, 256, name);
214 nf = nhf = nl = nhl = 0;
215 while ((dp = readdir(info_dp)) != 0) {
216 snprintf(filename, sizeof(filename), "%s/%s", infodir,
218 fp = fopen(filename, "r");
222 if (fstat(fileno(fp), &statb) < 0) {
223 logerror("Cannot stat for \"%s\" info file (%s)",
224 filename, strerror(errno));
228 if ((statb.st_mode & S_IFREG) == 0) {
229 logerror("The info file \"%s\" is not regular file\n",
234 while (fgets(fbuf, 256, fp)) {
235 lowerit(lbuf, 256, fbuf);
236 if (strstr(lbuf, lbp)) {
238 pr("*** %s ***\n", dp->d_name);
247 * break if too many lines
249 if ((nhl + nlhl) > lhitlim)
268 if ((nhl) > lhitlim) {
269 pr("Limit of %d lines exceeded\n", lhitlim);
271 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
272 name, nhf, nf, nhl, nl);
285 s_char filename[1024];
291 name = player->argp[1];
294 * don't let sneaky people go outside the info directory
296 if (NULL != (tmp_name = strrchr(name, '/')))
298 if (NULL != (tmp_name = strrchr(name, '\\')))
300 if (NULL != (tmp_name = strrchr(name, ':')))
306 _snprintf(filename, sizeof(filename) - 1, "%s\\%s", infodir, name);
307 fp = fopen(filename, "rb");
309 /* may be a "partial" request. */
311 WIN32_FIND_DATA fData;
312 strcat(filename, "*");
313 hDir = FindFirstFile(filename, &fData);
314 if (hDir == INVALID_HANDLE_VALUE) {
315 switch (GetLastError()) {
316 case ERROR_FILE_NOT_FOUND:
317 pr("Sorry, there is no info on %s\n", name);
320 case ERROR_PATH_NOT_FOUND:
321 pr("Can't open info dir\n");
322 logerror("Can't open info dir \"%s\"", infodir);
325 pr("Error reading info dir\n");
326 logerror("Error (%d) reading info dir(%s)\\file(%s)",
327 infodir, filename, GetLastError());
332 if ((fData.dwFileAttributes != (DWORD)-1) &&
333 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
334 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
335 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)) &&
336 (strncasecmp(name, fData.cFileName, strlen(name)) == 0)) {
339 _snprintf(last, sizeof(last), "%s", fData.cFileName);
342 pr("`%s' is ambiguous. The following topics match:\n%s",
344 width = strlen(last);
346 width += 2 + strlen(fData.cFileName);
350 width = strlen(fData.cFileName);
352 pr(",%c%s", sep, fData.cFileName);
355 } while (FindNextFile(hDir, &fData));
358 pr("Sorry, there is no info on %s\n", name);
360 } else if (nmatch > 1) {
364 _snprintf(filename, sizeof(filename), "%s/%s",
366 fp = fopen(filename, "rb");
368 pr("Error reading info file for %s\n", name);
369 logerror("Cannot open for \"%s\" info file (%s)",
370 filename, strerror(errno));
375 DWORD fAttrib = GetFileAttributes(filename);
376 if ((fAttrib == (DWORD)-1) || /* INVALID_FILE_ATTRIBUTES */
377 (fAttrib != FILE_ATTRIBUTE_NORMAL) &&
378 (fAttrib != FILE_ATTRIBUTE_ARCHIVE) &&
379 (fAttrib != FILE_ATTRIBUTE_READONLY)) {
380 pr("Error reading info file for %s\n", name);
381 logerror("The info file \"%s\" is not regular file\n",
388 pr("Information on: %s", name);
389 while (fgets(buf, sizeof(buf), fp) != 0)
399 WIN32_FIND_DATA fData;
404 s_char filename[1024];
405 long nf, nhf, nl, nlhl, nhl, nll;
409 if (player->argp[1] == 0 || !*player->argp[1]) {
410 pr("Apropos what?\n");
415 if (player->argp[2]) {
416 lhitlim = atoi(player->argp[2]);
421 _snprintf(filename, sizeof(filename), "%s\\*",infodir);
422 hDir = FindFirstFile(filename, &fData);
423 if (hDir == INVALID_HANDLE_VALUE) {
424 if (GetLastError() == ERROR_PATH_NOT_FOUND) {
425 pr("Can't open info dir\n");
426 logerror("Can't open info dir \"%s\"", infodir);
428 pr("Error reading info dir\n");
429 logerror("Error (%d) reading info dir(%s)\\file(%s)",
430 infodir, filename, GetLastError());
440 * lower case search string into lbp
442 name = player->argp[1];
443 lowerit(lbp, 256, name);
448 nf = nhf = nl = nhl = 0;
450 if ((fData.dwFileAttributes != (DWORD)-1) &&
451 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
452 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
453 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY))) {
454 _snprintf(filename, sizeof(filename), "%s\\%s", infodir,
456 fp = fopen(filename, "rb");
460 while (fgets(fbuf, 256, fp)) {
461 lowerit(lbuf, 256, fbuf);
462 if (strstr(lbuf, lbp)) {
464 pr("*** %s ***\n", fData.cFileName);
473 * break if too many lines
475 if ((nhl + nlhl) > lhitlim)
488 } while (FindNextFile(hDir, &fData));
495 if ((nhl) > lhitlim) {
496 pr("Limit of %ld lines exceeded\n", lhitlim);
498 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
499 name, nhf, nf, nhl, nl);