Exemple #1
0
/* scan for the page, print any matches */
static void do_apropos (MYDBM_FILE dbf,
			const char * const *pages, int num_pages, int *found)
{
	datum key, cont;
	char **lowpages;
	int *found_here;
	int (*combine) (int, int *);
	int i;
#ifndef BTREE
	datum nextkey;
#else /* BTREE */
	int end;
#endif /* !BTREE */

	lowpages = XNMALLOC (num_pages, char *);
	for (i = 0; i < num_pages; ++i) {
		lowpages[i] = lower (pages[i]);
		debug ("lower(%s) = \"%s\"\n", pages[i], lowpages[i]);
	}
	found_here = XNMALLOC (num_pages, int);
	combine = require_all ? all_set : any_set;

#ifndef BTREE
	key = MYDBM_FIRSTKEY (dbf);
	while (MYDBM_DPTR (key)) {
		cont = MYDBM_FETCH (dbf, key);
#else /* BTREE */
	end = btree_nextkeydata (dbf, &key, &cont);
	while (!end) {
#endif /* !BTREE */
		char *tab;
		struct mandata info;

		memset (&info, 0, sizeof (info));

		/* bug#4372, NULL pointer dereference in MYDBM_DPTR (cont),
		 * fix by [email protected] (J.H.M.Dassen), thanx Ray.
		 * cjwatson: In that case, complain and exit, otherwise we
		 * might loop (bug #95052).
		 */
		if (!MYDBM_DPTR (cont))
		{
			debug ("key was %s\n", MYDBM_DPTR (key));
			error (FATAL, 0,
			       _("Database %s corrupted; rebuild with "
				 "mandb --create"),
			       database);
		}

		if (*MYDBM_DPTR (key) == '$')
			goto nextpage;

		if (*MYDBM_DPTR (cont) == '\t')
			goto nextpage;

		/* a real page */

		split_content (MYDBM_DPTR (cont), &info);

		/* If there are sections given, does any of them match
		 * either the section or extension of this page?
		 */
		if (sections) {
			char * const *section;
			int matched = 0;

			for (section = sections; *section; ++section) {
				if (STREQ (*section, info.sec) ||
				    STREQ (*section, info.ext)) {
					matched = 1;
					break;
				}
			}

			if (!matched)
				goto nextpage;
		}

		tab = strrchr (MYDBM_DPTR (key), '\t');
		if (tab) 
			 *tab = '\0';

		memset (found_here, 0, num_pages * sizeof (*found_here));
		if (am_apropos) {
			char *whatis;

			parse_name ((const char **) lowpages, num_pages,
				    MYDBM_DPTR (key), found, found_here);
			whatis = info.whatis ? xstrdup (info.whatis) : NULL;
			if (!combine (num_pages, found_here) && whatis)
				parse_whatis (pages, lowpages, num_pages,
					      whatis, found, found_here);
			free (whatis);
		} else
			parse_name (pages, num_pages,
				    MYDBM_DPTR (key), found, found_here);
		if (combine (num_pages, found_here))
			display (dbf, &info, MYDBM_DPTR (key));

		if (tab)
			*tab = '\t';
nextpage:
#ifndef BTREE
		nextkey = MYDBM_NEXTKEY (dbf, key);
		MYDBM_FREE_DPTR (cont);
		MYDBM_FREE_DPTR (key);
		key = nextkey; 
#else /* BTREE */
		MYDBM_FREE_DPTR (cont);
		MYDBM_FREE_DPTR (key);
		end = btree_nextkeydata (dbf, &key, &cont);
#endif /* !BTREE */
		info.addr = NULL; /* == MYDBM_DPTR (cont), freed above */
		free_mandata_elements (&info);
	}

	for (i = 0; i < num_pages; ++i)
		free (lowpages[i]);
	free (lowpages);
}

/* loop through the man paths, searching for a match */
static int search (const char * const *pages, int num_pages)
{
	int *found = XCALLOC (num_pages, int);
	char *catpath, **mp;
	int any_found, i;

	for (mp = manpathlist; *mp; mp++) {
		MYDBM_FILE dbf;

		catpath = get_catpath (*mp, SYSTEM_CAT | USER_CAT);
		
		if (catpath) {
			database = mkdbname (catpath);
			free (catpath);
		} else
			database = mkdbname (*mp);

		debug ("path=%s\n", *mp);

		dbf = MYDBM_RDOPEN (database);
		if (dbf && dbver_rd (dbf)) {
			MYDBM_CLOSE (dbf);
			dbf = NULL;
		}
		if (!dbf) {
			use_grep (pages, num_pages, *mp, found);
			continue;
		}

		if (am_apropos)
			do_apropos (dbf, pages, num_pages, found);
		else {
			if (regex_opt || wildcard)
				do_apropos (dbf, pages, num_pages, found);
			else
				do_whatis (dbf, pages, num_pages, *mp, found);
		}
		free (database);
		database = NULL;
		MYDBM_CLOSE (dbf);
	}

	chkr_garbage_detector ();

	any_found = 0;
	for (i = 0; i < num_pages; ++i) {
		if (found[i])
			any_found = 1;
		else
			fprintf (stderr, _("%s: nothing appropriate.\n"),
				 pages[i]);
	}

	free (found);
	return any_found;
}
Exemple #2
0
int
main (int argc, char **argv) {
     int status = 0;
     char *nextarg;
     char *tmp;
     char *section = 0;

#ifdef __CYGWIN__
     extern int optind;
#endif


#if 0
     {
	/* There are no known cases of buffer overflow caused by
	   excessively long environment variables. In case you find one,
	   the simplistic way to fix is to enable this stopgap. */
	char *s;
#define CHECK(p,l) s=getenv(p); if(s && strlen(s)>(l)) { fprintf(stderr, "ERROR: Environment variable %s too long!\n", p); exit(1); }
	CHECK("LANG", 32);
	CHECK("LANGUAGE", 128);
	CHECK("LC_MESSAGES", 128);
	CHECK("MANPAGER", 128);
	CHECK("MANPL", 128);
	CHECK("MANROFFSEQ", 128);
	CHECK("MANSECT", 128);
	CHECK("MAN_HP_DIREXT", 128);
	CHECK("PAGER", 128);
	CHECK("SYSTEM", 64);
	CHECK("BROWSER", 64);
	CHECK("HTMLPAGER", 64);
	/* COLUMNS, LC_ALL, LC_CTYPE, MANPATH, MANWIDTH, MAN_IRIX_CATNAMES,
	   MAN_ICONV_PATH, MAN_ICONV_OPT, MAN_ICONV_INPUT_CHARSET,
	   MAN_ICONV_OUTPUT_CHARSET, NLSPATH, PATH */
     }
#endif


#ifndef __FreeBSD__ 
     /* Slaven Rezif: FreeBSD-2.2-SNAP does not recognize LC_MESSAGES. */
     setlocale(LC_CTYPE, "");	/* used anywhere? maybe only isdigit()? */
     setlocale(LC_MESSAGES, "");
#endif

     /* No doubt we'll need some generic language code here later.
	For the moment only Japanese support. */
     setlang();

     /* Handle /usr/man/man1.Z/name.1 nonsense from HP */
     dohp = getenv("MAN_HP_DIREXT");		/* .Z */

     /* Handle ls.z (instead of ls.1.z) cat page naming from IRIX */
     if (getenv("MAN_IRIX_CATNAMES"))
	  do_irix = 1;

     /* Handle lack of ':' in NTFS file names */
#if defined(_WIN32) || defined(__CYGWIN__)
     do_win32 = 1;
#endif

     progname = mkprogname (argv[0]);

     get_permissions ();
     get_line_length();

     /*
      * read command line options and man.conf
      */
     man_getopt (argc, argv);

     /*
      * manpath  or  man --path  or  man -w  will only print the manpath
      */
     if (!strcmp (progname, "manpath") || (optind == argc && print_where)) {
	  init_manpath();
	  prmanpath();
	  exit(0);
     }

     if (optind == argc)
	  gripe(NO_NAME_NO_SECTION);

     section_list = get_section_list ();

     while (optind < argc) {
	  nextarg = argv[optind++];

	  /* is_section correctly accepts 3Xt as section, but also 9wm,
	     so we should not believe is_section() for the last arg. */
	  tmp = is_section (nextarg);
	  if (tmp && optind < argc) {
		  section = tmp;
		  if (debug)
			  gripe (SECTION, section);
		  continue;
	  }

	  if (global_apropos)
	       status = !do_global_apropos (nextarg, section);
	  else if (apropos)
	       status = !do_apropos (nextarg);
	  else if (whatis)
	       status = !do_whatis (nextarg);
	  else {
	       status = man (nextarg, section);

	       if (status == 0) {
		    if (section)
			 gripe (NO_SUCH_ENTRY_IN_SECTION, nextarg, section);
		    else
			 gripe (NO_SUCH_ENTRY, nextarg);
	       }
	  }
     }
     return status ? EXIT_SUCCESS : EXIT_FAILURE;
}