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 int len = strlen(name);
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)
176 s_char filename[1024];
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);
286 s_char filename[1024];
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 int len = strlen(name);
314 strcat(filename, "*");
315 hDir = FindFirstFile(filename, &fData);
316 if (hDir == INVALID_HANDLE_VALUE) {
317 switch (GetLastError()) {
318 case ERROR_FILE_NOT_FOUND:
319 pr("Sorry, there is no info on %s\n", name);
322 case ERROR_PATH_NOT_FOUND:
323 pr("Can't open info dir\n");
324 logerror("Can't open info dir \"%s\"", infodir);
327 pr("Error reading info dir\n");
328 logerror("Error (%d) reading info dir(%s)\\file(%s)",
329 infodir, filename, GetLastError());
334 if ((fData.dwFileAttributes != (DWORD)-1) &&
335 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
336 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
337 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY)) &&
338 (strncasecmp(name, fData.cFileName, strlen(name)) == 0)) {
341 _snprintf(last, sizeof(last), "%s", fData.cFileName);
344 pr("`%s' is ambiguous. The following topics match:\n%s",
346 width = strlen(last);
348 width += 2 + strlen(fData.cFileName);
352 width = strlen(fData.cFileName);
354 pr(",%c%s", sep, fData.cFileName);
357 } while (FindNextFile(hDir, &fData));
360 pr("Sorry, there is no info on %s\n", name);
362 } else if (nmatch > 1) {
366 _snprintf(filename, sizeof(filename), "%s/%s",
368 fp = fopen(filename, "rb");
370 pr("Error reading info file for %s\n", name);
371 logerror("Cannot open for \"%s\" info file (%s)",
372 filename, strerror(errno));
377 DWORD fAttrib = GetFileAttributes(filename);
378 if ((fAttrib == (DWORD)-1) || /* INVALID_FILE_ATTRIBUTES */
379 (fAttrib != FILE_ATTRIBUTE_NORMAL) &&
380 (fAttrib != FILE_ATTRIBUTE_ARCHIVE) &&
381 (fAttrib != FILE_ATTRIBUTE_READONLY)) {
382 pr("Error reading info file for %s\n", name);
383 logerror("The info file \"%s\" is not regular file\n",
390 pr("Information on: %s", name);
391 while (fgets(buf, sizeof(buf), fp) != 0)
401 WIN32_FIND_DATA fData;
406 s_char filename[1024];
407 long nf, nhf, nl, nlhl, nhl, nll;
411 if (player->argp[1] == 0 || !*player->argp[1]) {
412 pr("Apropos what?\n");
417 if (player->argp[2]) {
418 lhitlim = atoi(player->argp[2]);
423 _snprintf(filename, sizeof(filename), "%s\\*",infodir);
424 hDir = FindFirstFile(filename, &fData);
425 if (hDir == INVALID_HANDLE_VALUE) {
426 if (GetLastError() == ERROR_PATH_NOT_FOUND) {
427 pr("Can't open info dir\n");
428 logerror("Can't open info dir \"%s\"", infodir);
430 pr("Error reading info dir\n");
431 logerror("Error (%d) reading info dir(%s)\\file(%s)",
432 infodir, filename, GetLastError());
442 * lower case search string into lbp
444 name = player->argp[1];
445 lowerit(lbp, 256, name);
450 nf = nhf = nl = nhl = 0;
452 if ((fData.dwFileAttributes != (DWORD)-1) &&
453 ((fData.dwFileAttributes == FILE_ATTRIBUTE_NORMAL) ||
454 (fData.dwFileAttributes == FILE_ATTRIBUTE_ARCHIVE) ||
455 (fData.dwFileAttributes == FILE_ATTRIBUTE_READONLY))) {
456 _snprintf(filename, sizeof(filename), "%s\\%s", infodir,
458 fp = fopen(filename, "rb");
462 while (fgets(fbuf, 256, fp)) {
463 lowerit(lbuf, 256, fbuf);
464 if (strstr(lbuf, lbp)) {
466 pr("*** %s ***\n", fData.cFileName);
475 * break if too many lines
477 if ((nhl + nlhl) > lhitlim)
490 } while (FindNextFile(hDir, &fData));
497 if ((nhl) > lhitlim) {
498 pr("Limit of %ld lines exceeded\n", lhitlim);
500 pr("Found %s in %ld of %ld files and in %ld of %ld lines\n",
501 name, nhf, nf, nhl, nl);