2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2008, 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
53 lowerit(char *buf, int n, char *orig)
54 { /* converts a string to lower case */
55 /* lower case output buffer */
56 /* size of output buffer */
59 for (i = 0; i < n - 1 && orig[i]; i++)
60 buf[i] = tolower(orig[i]);
83 name = player->argp[1];
86 * don't let sneaky people go outside the info directory
88 if (NULL != (tmp_name = strrchr(name, '/')))
94 snprintf(filename, sizeof(filename), "%s/%s", infodir, name);
95 fp = fopen(filename, "r");
97 /* may be a "partial" request. */
98 info_dp = opendir(infodir);
100 pr("Can't open info dir\n");
101 logerror("Can't open info dir \"%s\"\n", infodir);
105 while ((dp = readdir(info_dp)) != 0) {
106 if (strncasecmp(name, dp->d_name, strlen(name)) != 0)
110 snprintf(last, sizeof(last), "%s", dp->d_name);
113 pr("`%s' is ambiguous. The following topics match:\n%s",
115 width = strlen(last);
117 width += 2 + strlen(dp->d_name);
121 width = strlen(dp->d_name);
123 pr(",%c%s", sep, dp->d_name);
128 pr("Sorry, there is no info on %s\n", name);
130 } else if (nmatch > 1) {
134 snprintf(filename, sizeof(filename), "%s/%s", infodir,
136 fp = fopen(filename, "r");
138 pr("Error reading info file for %s\n", name);
139 logerror("Cannot open for \"%s\" info file (%s)",
140 filename, strerror(errno));
144 if (fstat(fileno(fp), &statb) < 0) {
145 pr("Error reading info file for %s\n", name);
146 logerror("Cannot fstat for \"%s\" info file (%s)",
147 filename, strerror(errno));
151 if ((statb.st_mode & S_IFREG) == 0) {
152 pr("Error reading info file for %s\n", name);
153 logerror("The info file \"%s\" is not regular file\n", filename);
158 while (fgets(buf, sizeof(buf), fp) != 0)
174 long nf, nhf, nl, nlhl, nhl, nll;
179 if (player->argp[1] == 0 || !*player->argp[1]) {
180 pr("Apropos what?\n");
185 if (player->argp[2]) {
186 lhitlim = atoi(player->argp[2]);
191 info_dp = opendir(infodir);
192 if (info_dp == NULL) {
193 pr("Can't open info dir \n");
194 logerror("Can't open info dir \"%s\"", infodir);
203 * lower case search string into lbp
205 name = player->argp[1];
206 lowerit(lbp, 256, name);
211 nf = nhf = nl = nhl = 0;
212 while ((dp = readdir(info_dp)) != 0) {
213 if (dp->d_name[0] == '.')
215 snprintf(filename, sizeof(filename), "%s/%s", infodir,
217 fp = fopen(filename, "r");
221 if (fstat(fileno(fp), &statb) < 0) {
222 logerror("Cannot stat for \"%s\" info file (%s)",
223 filename, strerror(errno));
227 if ((statb.st_mode & S_IFREG) == 0) {
228 logerror("The info file \"%s\" is not regular file\n",
233 while (fgets(fbuf, 256, fp)) {
234 lowerit(lbuf, 256, fbuf);
235 if (strstr(lbuf, lbp)) {
237 pr("*** %s ***\n", dp->d_name);
246 * break if too many lines
248 if ((nhl + nlhl) > lhitlim)
267 if ((nhl) > lhitlim) {
268 pr("Limit of %d lines exceeded\n", lhitlim);
270 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
271 name, nhf, nf, nhl, nl);
290 name = player->argp[1];
293 * don't let sneaky people go outside the info directory
295 if (NULL != (tmp_name = strrchr(name, '/')))
297 if (NULL != (tmp_name = strrchr(name, '\\')))
299 if (NULL != (tmp_name = strrchr(name, ':')))
305 snprintf(filename, sizeof(filename) - 1, "%s\\%s", infodir, name);
306 fp = fopen(filename, "rb");
308 /* may be a "partial" request. */
310 WIN32_FIND_DATA fData;
311 strcat(filename, "*");
312 hDir = FindFirstFile(filename, &fData);
313 if (hDir == INVALID_HANDLE_VALUE) {
314 switch (GetLastError()) {
315 case ERROR_FILE_NOT_FOUND:
316 pr("Sorry, there is no info on %s\n", name);
318 case ERROR_PATH_NOT_FOUND:
319 pr("Can't open info dir\n");
320 logerror("Can't open info dir \"%s\"", infodir);
323 pr("Error reading info dir\n");
324 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
325 GetLastError(), infodir, filename);
330 if ((fData.dwFileAttributes != (DWORD)-1) &&
331 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
332 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
333 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)) &&
334 (strncasecmp(name, fData.cFileName, strlen(name)) == 0)) {
337 snprintf(last, sizeof(last), "%s", fData.cFileName);
340 pr("`%s' is ambiguous. The following topics match:\n%s",
342 width = strlen(last);
344 width += 2 + strlen(fData.cFileName);
348 width = strlen(fData.cFileName);
350 pr(",%c%s", sep, fData.cFileName);
353 } while (FindNextFile(hDir, &fData));
356 pr("Sorry, there is no info on %s\n", name);
358 } else if (nmatch > 1) {
362 snprintf(filename, sizeof(filename), "%s/%s",
364 fp = fopen(filename, "rb");
366 pr("Error reading info file for %s\n", name);
367 logerror("Cannot open for \"%s\" info file (%s)",
368 filename, strerror(errno));
372 DWORD fAttrib = GetFileAttributes(filename);
373 if ((fAttrib == (DWORD)-1) || /* INVALID_FILE_ATTRIBUTES */
374 ((fAttrib != FILE_ATTRIBUTE_NORMAL) &&
375 (fAttrib != FILE_ATTRIBUTE_ARCHIVE) &&
376 (fAttrib != FILE_ATTRIBUTE_READONLY))) {
377 pr("Error reading info file for %s\n", name);
378 logerror("The info file \"%s\" is not regular file\n",
385 while (fgets(buf, sizeof(buf), fp) != 0)
395 WIN32_FIND_DATA fData;
401 long nf, nhf, nl, nlhl, nhl, nll;
405 if (player->argp[1] == 0 || !*player->argp[1]) {
406 pr("Apropos what?\n");
411 if (player->argp[2]) {
412 lhitlim = atoi(player->argp[2]);
417 snprintf(filename, sizeof(filename), "%s\\*",infodir);
418 hDir = FindFirstFile(filename, &fData);
419 if (hDir == INVALID_HANDLE_VALUE) {
420 if (GetLastError() == ERROR_PATH_NOT_FOUND) {
421 pr("Can't open info dir\n");
422 logerror("Can't open info dir \"%s\"", infodir);
424 pr("Error reading info dir\n");
425 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
426 GetLastError(), infodir, filename);
436 * lower case search string into lbp
438 name = player->argp[1];
439 lowerit(lbp, 256, name);
444 nf = nhf = nl = nhl = 0;
446 if ((fData.dwFileAttributes != (DWORD)-1) &&
447 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
448 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
449 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY))) {
450 snprintf(filename, sizeof(filename), "%s\\%s", infodir,
452 fp = fopen(filename, "rb");
456 while (fgets(fbuf, 256, fp)) {
457 lowerit(lbuf, 256, fbuf);
458 if (strstr(lbuf, lbp)) {
460 pr("*** %s ***\n", fData.cFileName);
469 * break if too many lines
471 if ((nhl + nlhl) > lhitlim)
484 } while (FindNextFile(hDir, &fData));
491 if ((nhl) > lhitlim) {
492 pr("Limit of %d lines exceeded\n", lhitlim);
494 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
495 name, nhf, nf, nhl, nl);