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(char *buf, int n, char *orig)
57 { /* converts a string to lower case */
58 /* lower case output buffer */
59 /* size of output buffer */
62 for (i = 0; i < n - 1 && orig[i]; i++)
63 buf[i] = tolower(orig[i]);
86 name = player->argp[1];
89 * don't let sneaky people go outside the info directory
91 if (NULL != (tmp_name = strrchr(name, '/')))
97 snprintf(filename, sizeof(filename), "%s/%s", infodir, name);
98 fp = fopen(filename, "r");
100 /* may be a "partial" request. */
101 info_dp = opendir(infodir);
103 pr("Can't open info dir\n");
104 logerror("Can't open info dir \"%s\"\n", infodir);
108 while ((dp = readdir(info_dp)) != 0) {
109 if (strncasecmp(name, dp->d_name, strlen(name)) != 0)
113 snprintf(last, sizeof(last), "%s", dp->d_name);
116 pr("`%s' is ambiguous. The following topics match:\n%s",
118 width = strlen(last);
120 width += 2 + strlen(dp->d_name);
124 width = strlen(dp->d_name);
126 pr(",%c%s", sep, dp->d_name);
131 pr("Sorry, there is no info on %s\n", name);
133 } else if (nmatch > 1) {
137 snprintf(filename, sizeof(filename), "%s/%s", infodir,
139 fp = fopen(filename, "r");
141 pr("Error reading info file for %s\n", name);
142 logerror("Cannot open for \"%s\" info file (%s)",
143 filename, strerror(errno));
147 if (fstat(fileno(fp), &statb) < 0) {
148 pr("Error reading info file for %s\n", name);
149 logerror("Cannot fstat for \"%s\" info file (%s)",
150 filename, strerror(errno));
154 if ((statb.st_mode & S_IFREG) == 0) {
155 pr("Error reading info file for %s\n", name);
156 logerror("The info file \"%s\" is not regular file\n", filename);
160 pr("Information on: %s Last modification date: %s",
161 name, ctime(&statb.st_mtime));
162 while (fgets(buf, sizeof(buf), fp) != 0)
178 long nf, nhf, nl, nlhl, nhl, nll;
183 if (player->argp[1] == 0 || !*player->argp[1]) {
184 pr("Apropos what?\n");
189 if (player->argp[2]) {
190 lhitlim = atoi(player->argp[2]);
195 info_dp = opendir(infodir);
196 if (info_dp == NULL) {
197 pr("Can't open info dir \n");
198 logerror("Can't open info dir \"%s\"", infodir);
207 * lower case search string into lbp
209 name = player->argp[1];
210 lowerit(lbp, 256, name);
215 nf = nhf = nl = nhl = 0;
216 while ((dp = readdir(info_dp)) != 0) {
217 snprintf(filename, sizeof(filename), "%s/%s", infodir,
219 fp = fopen(filename, "r");
223 if (fstat(fileno(fp), &statb) < 0) {
224 logerror("Cannot stat for \"%s\" info file (%s)",
225 filename, strerror(errno));
229 if ((statb.st_mode & S_IFREG) == 0) {
230 logerror("The info file \"%s\" is not regular file\n",
235 while (fgets(fbuf, 256, fp)) {
236 lowerit(lbuf, 256, fbuf);
237 if (strstr(lbuf, lbp)) {
239 pr("*** %s ***\n", dp->d_name);
248 * break if too many lines
250 if ((nhl + nlhl) > lhitlim)
269 if ((nhl) > lhitlim) {
270 pr("Limit of %d lines exceeded\n", lhitlim);
272 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
273 name, nhf, nf, nhl, nl);
292 name = player->argp[1];
295 * don't let sneaky people go outside the info directory
297 if (NULL != (tmp_name = strrchr(name, '/')))
299 if (NULL != (tmp_name = strrchr(name, '\\')))
301 if (NULL != (tmp_name = strrchr(name, ':')))
307 _snprintf(filename, sizeof(filename) - 1, "%s\\%s", infodir, name);
308 fp = fopen(filename, "rb");
310 /* may be a "partial" request. */
312 WIN32_FIND_DATA fData;
313 strcat(filename, "*");
314 hDir = FindFirstFile(filename, &fData);
315 if (hDir == INVALID_HANDLE_VALUE) {
316 switch (GetLastError()) {
317 case ERROR_FILE_NOT_FOUND:
318 pr("Sorry, there is no info on %s\n", name);
321 case ERROR_PATH_NOT_FOUND:
322 pr("Can't open info dir\n");
323 logerror("Can't open info dir \"%s\"", infodir);
326 pr("Error reading info dir\n");
327 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
328 GetLastError(), infodir, filename);
333 if ((fData.dwFileAttributes != (DWORD)-1) &&
334 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
335 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
336 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)) &&
337 (strncasecmp(name, fData.cFileName, strlen(name)) == 0)) {
340 _snprintf(last, sizeof(last), "%s", fData.cFileName);
343 pr("`%s' is ambiguous. The following topics match:\n%s",
345 width = strlen(last);
347 width += 2 + strlen(fData.cFileName);
351 width = strlen(fData.cFileName);
353 pr(",%c%s", sep, fData.cFileName);
356 } while (FindNextFile(hDir, &fData));
359 pr("Sorry, there is no info on %s\n", name);
361 } else if (nmatch > 1) {
365 _snprintf(filename, sizeof(filename), "%s/%s",
367 fp = fopen(filename, "rb");
369 pr("Error reading info file for %s\n", name);
370 logerror("Cannot open for \"%s\" info file (%s)",
371 filename, strerror(errno));
376 DWORD fAttrib = GetFileAttributes(filename);
377 if ((fAttrib == (DWORD)-1) || /* INVALID_FILE_ATTRIBUTES */
378 ((fAttrib != FILE_ATTRIBUTE_NORMAL) &&
379 (fAttrib != FILE_ATTRIBUTE_ARCHIVE) &&
380 (fAttrib != FILE_ATTRIBUTE_READONLY))) {
381 pr("Error reading info file for %s\n", name);
382 logerror("The info file \"%s\" is not regular file\n",
389 pr("Information on: %s", name);
390 while (fgets(buf, sizeof(buf), fp) != 0)
400 WIN32_FIND_DATA fData;
406 long nf, nhf, nl, nlhl, nhl, nll;
410 if (player->argp[1] == 0 || !*player->argp[1]) {
411 pr("Apropos what?\n");
416 if (player->argp[2]) {
417 lhitlim = atoi(player->argp[2]);
422 _snprintf(filename, sizeof(filename), "%s\\*",infodir);
423 hDir = FindFirstFile(filename, &fData);
424 if (hDir == INVALID_HANDLE_VALUE) {
425 if (GetLastError() == ERROR_PATH_NOT_FOUND) {
426 pr("Can't open info dir\n");
427 logerror("Can't open info dir \"%s\"", infodir);
429 pr("Error reading info dir\n");
430 logerror("Error (%lu) reading info dir(%s)\\file(%s)",
431 GetLastError(), infodir, filename);
441 * lower case search string into lbp
443 name = player->argp[1];
444 lowerit(lbp, 256, name);
449 nf = nhf = nl = nhl = 0;
451 if ((fData.dwFileAttributes != (DWORD)-1) &&
452 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
453 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
454 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY))) {
455 _snprintf(filename, sizeof(filename), "%s\\%s", infodir,
457 fp = fopen(filename, "rb");
461 while (fgets(fbuf, 256, fp)) {
462 lowerit(lbuf, 256, fbuf);
463 if (strstr(lbuf, lbp)) {
465 pr("*** %s ***\n", fData.cFileName);
474 * break if too many lines
476 if ((nhl + nlhl) > lhitlim)
489 } while (FindNextFile(hDir, &fData));
496 if ((nhl) > lhitlim) {
497 pr("Limit of %d lines exceeded\n", lhitlim);
499 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
500 name, nhf, nf, nhl, nl);