Blame extensions.c

Packit Service 501009
/* extensions.c - core analysis suite
Packit Service 501009
 *
Packit Service 501009
 * Copyright (C) 2001, 2002 Mission Critical Linux, Inc.
Packit Service 501009
 * Copyright (C) 2002-2013, 2018 David Anderson
Packit Service 501009
 * Copyright (C) 2002-2013, 2018 Red Hat, Inc. All rights reserved.
Packit Service 501009
 *
Packit Service 501009
 * This program is free software; you can redistribute it and/or modify
Packit Service 501009
 * it under the terms of the GNU General Public License as published by
Packit Service 501009
 * the Free Software Foundation; either version 2 of the License, or
Packit Service 501009
 * (at your option) any later version.
Packit Service 501009
 *
Packit Service 501009
 * This program is distributed in the hope that it will be useful,
Packit Service 501009
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 501009
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 501009
 * GNU General Public License for more details.
Packit Service 501009
 */
Packit Service 501009
Packit Service 501009
#include "defs.h"
Packit Service 501009
#include <dlfcn.h>
Packit Service 501009
Packit Service 501009
static int in_extensions_library(char *, char *);
Packit Service 501009
static char *get_extensions_directory(char *);
Packit Service 501009
Packit Service 501009
#define DUMP_EXTENSIONS   (0)
Packit Service 501009
#define LOAD_EXTENSION    (1)
Packit Service 501009
#define UNLOAD_EXTENSION  (2)
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Load, unload, or list the extension libaries.
Packit Service 501009
 */
Packit Service 501009
void
Packit Service 501009
cmd_extend(void)
Packit Service 501009
{
Packit Service 501009
        int c;
Packit Service 501009
	int flag;
Packit Service 501009
Packit Service 501009
	flag = DUMP_EXTENSIONS;
Packit Service 501009
Packit Service 501009
        while ((c = getopt(argcnt, args, "lu")) != EOF) {
Packit Service 501009
                switch(c)
Packit Service 501009
                {
Packit Service 501009
		case 'l':
Packit Service 501009
			if (flag & UNLOAD_EXTENSION) {
Packit Service 501009
				error(INFO, 
Packit Service 501009
					"-l and -u are mutually exclusive\n");
Packit Service 501009
				argerrs++;
Packit Service 501009
			} else
Packit Service 501009
				flag |= LOAD_EXTENSION;
Packit Service 501009
			break;
Packit Service 501009
Packit Service 501009
		case 'u':
Packit Service 501009
                        if (flag & LOAD_EXTENSION) {
Packit Service 501009
                                error(INFO, 
Packit Service 501009
                                        "-u and -l are mutually exclusive\n");
Packit Service 501009
                                argerrs++;
Packit Service 501009
                        } else
Packit Service 501009
                                flag |= UNLOAD_EXTENSION;
Packit Service 501009
			break;
Packit Service 501009
Packit Service 501009
                default:
Packit Service 501009
                        argerrs++;
Packit Service 501009
                        break;
Packit Service 501009
                }
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
        if (argerrs)
Packit Service 501009
                cmd_usage(pc->curcmd, SYNOPSIS);
Packit Service 501009
Packit Service 501009
	switch (flag)
Packit Service 501009
	{
Packit Service 501009
	case DUMP_EXTENSIONS:
Packit Service 501009
		if (!args[optind]) {
Packit Service 501009
			dump_extension_table(!VERBOSE);
Packit Service 501009
			return;
Packit Service 501009
		}
Packit Service 501009
		/* FALLTHROUGH */
Packit Service 501009
Packit Service 501009
	case LOAD_EXTENSION:
Packit Service 501009
		if (!args[optind]) { 
Packit Service 501009
			error(INFO, 
Packit Service 501009
		       "-l requires one or more extension library arguments\n");
Packit Service 501009
			cmd_usage(pc->curcmd, SYNOPSIS);
Packit Service 501009
			break;
Packit Service 501009
		}
Packit Service 501009
Packit Service 501009
        	while (args[optind]) {
Packit Service 501009
			load_extension(args[optind]);
Packit Service 501009
			optind++;
Packit Service 501009
		}
Packit Service 501009
		break;
Packit Service 501009
Packit Service 501009
	case UNLOAD_EXTENSION:
Packit Service 501009
		if (!args[optind]) { 
Packit Service 501009
			unload_extension(NULL);
Packit Service 501009
			break;
Packit Service 501009
		}
Packit Service 501009
Packit Service 501009
        	while (args[optind]) {
Packit Service 501009
			unload_extension(args[optind]);
Packit Service 501009
			optind++;
Packit Service 501009
		}
Packit Service 501009
		break;
Packit Service 501009
	}
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  List all extension libaries and their commands in either the extend
Packit Service 501009
 *  command format or for "help -e" (verbose).
Packit Service 501009
 */
Packit Service 501009
void 
Packit Service 501009
dump_extension_table(int verbose)
Packit Service 501009
{
Packit Service 501009
	int i;
Packit Service 501009
	struct extension_table *ext;
Packit Service 501009
	struct command_table_entry *cp;
Packit Service 501009
	char buf[BUFSIZE];
Packit Service 501009
	int longest, others;
Packit Service 501009
Packit Service 501009
	if (!extension_table)
Packit Service 501009
		return;
Packit Service 501009
Packit Service 501009
	if (verbose) {
Packit Service 501009
       		for (ext = extension_table; ext; ext = ext->next) {
Packit Service 501009
                        fprintf(fp, "        filename: %s\n", ext->filename);
Packit Service 501009
                        fprintf(fp, "          handle: %lx\n", (ulong)ext->handle);
Packit Service 501009
Packit Service 501009
Packit Service 501009
			fprintf(fp, "           flags: %lx (", ext->flags);
Packit Service 501009
			others = 0;
Packit Service 501009
			if (ext->flags & REGISTERED)
Packit Service 501009
				fprintf(fp, "%sREGISTERED", others++ ?
Packit Service 501009
					"|" : "");
Packit Service 501009
			fprintf(fp, ")\n");
Packit Service 501009
                        fprintf(fp, "            next: %lx\n", (ulong)ext->next);
Packit Service 501009
                        fprintf(fp, "            prev: %lx\n", (ulong)ext->prev);
Packit Service 501009
Packit Service 501009
                        for (i = 0, cp = ext->command_table; cp->name; cp++, i++) {
Packit Service 501009
                        	fprintf(fp, "command_table[%d]: %lx\n", i, (ulong)cp); 
Packit Service 501009
				fprintf(fp, "                  name: %s\n", cp->name);
Packit Service 501009
				fprintf(fp, "                  func: %lx\n", (ulong)cp->func);
Packit Service 501009
				fprintf(fp, "             help_data: %lx\n", (ulong)cp->help_data); 
Packit Service 501009
				fprintf(fp, "                 flags: %lx (", cp->flags);
Packit Service 501009
				others = 0;
Packit Service 501009
				if (cp->flags & CLEANUP)
Packit Service 501009
					fprintf(fp, "%sCLEANUP", others++ ? "|" : "");
Packit Service 501009
				if (cp->flags & REFRESH_TASK_TABLE)
Packit Service 501009
					fprintf(fp, "%sREFRESH_TASK_TABLE", others++ ? "|" : "");
Packit Service 501009
				if (cp->flags & HIDDEN_COMMAND)
Packit Service 501009
					fprintf(fp, "%sHIDDEN_COMMAND", others++ ? "|" : "");
Packit Service 501009
				fprintf(fp, ")\n");
Packit Service 501009
			}
Packit Service 501009
Packit Service 501009
			if (ext->next) 
Packit Service 501009
				fprintf(fp, "\n");
Packit Service 501009
		}
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
Packit Service 501009
       /*
Packit Service 501009
	*  Print them out in the order they were loaded.
Packit Service 501009
	*/
Packit Service 501009
	for (longest = 0, ext = extension_table; ext; ext = ext->next) {
Packit Service 501009
		if (strlen(ext->filename) > longest)
Packit Service 501009
			longest = strlen(ext->filename);
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	fprintf(fp, "%s  COMMANDS\n", 
Packit Service 501009
		mkstring(buf, longest, LJUST, "SHARED OBJECT"));
Packit Service 501009
	longest = MAX(longest, strlen("SHARED OBJECT"));
Packit Service 501009
Packit Service 501009
	for (ext = extension_table; ext; ext = ext->next) 
Packit Service 501009
		if (ext->next == NULL)
Packit Service 501009
			break;
Packit Service 501009
Packit Service 501009
	do {
Packit Service 501009
                fprintf(fp, "%s  ", 
Packit Service 501009
                        mkstring(buf, longest, LJUST, ext->filename));
Packit Service 501009
                for (cp = ext->command_table; cp->name; cp++)
Packit Service 501009
                        fprintf(fp, "%s ", cp->name);
Packit Service 501009
		fprintf(fp, "\n");
Packit Service 501009
	} while ((ext = ext->prev));
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Load an extension library.
Packit Service 501009
 */
Packit Service 501009
void 
Packit Service 501009
load_extension(char *lib)
Packit Service 501009
{
Packit Service 501009
	struct extension_table *ext, *curext;
Packit Service 501009
	char buf[BUFSIZE];
Packit Service 501009
	size_t size;
Packit Service 501009
	char *env;
Packit Service 501009
	int env_len;
Packit Service 501009
Packit Service 501009
	if ((env = getenv("CRASH_EXTENSIONS")))
Packit Service 501009
		env_len = strlen(env)+1;
Packit Service 501009
	else
Packit Service 501009
		env_len = 0;	
Packit Service 501009
Packit Service 501009
	size = sizeof(struct extension_table) + strlen(lib) + 
Packit Service 501009
		MAX(env_len, strlen("/usr/lib64/crash/extensions/")) + 1;
Packit Service 501009
Packit Service 501009
	if ((ext = (struct extension_table *)malloc(size)) == NULL) 
Packit Service 501009
		error(FATAL, "cannot malloc extension_table space.");
Packit Service 501009
Packit Service 501009
	BZERO(ext, size);
Packit Service 501009
Packit Service 501009
	ext->filename = (char *)((ulong)ext + sizeof(struct extension_table));
Packit Service 501009
	
Packit Service 501009
       /*
Packit Service 501009
	*  If the library is not specified by an absolute pathname, dlopen() 
Packit Service 501009
        *  does not look in the current directory, so modify the filename.
Packit Service 501009
	*  If it's not in the current directory, check the extensions library
Packit Service 501009
	*  directory.
Packit Service 501009
        */
Packit Service 501009
	if ((*lib != '.') && (*lib != '/')) {
Packit Service 501009
		if (file_exists(lib, NULL))
Packit Service 501009
			sprintf(ext->filename, "./%s", lib);
Packit Service 501009
		else if (in_extensions_library(lib, buf))
Packit Service 501009
			strcpy(ext->filename, buf);
Packit Service 501009
		else {
Packit Service 501009
			error(INFO, "%s: %s\n", lib, strerror(ENXIO));
Packit Service 501009
			free(ext);
Packit Service 501009
			return;
Packit Service 501009
		}
Packit Service 501009
	} else 
Packit Service 501009
		strcpy(ext->filename, lib);
Packit Service 501009
Packit Service 501009
	if (!is_shared_object(ext->filename)) {
Packit Service 501009
		error(INFO, "%s: not an ELF format object file\n",
Packit Service 501009
			ext->filename);
Packit Service 501009
		free(ext);
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	for (curext = extension_table; curext; curext = curext->next) {
Packit Service 501009
		if (same_file(curext->filename, ext->filename)) {
Packit Service 501009
			fprintf(fp, "%s: shared object already loaded\n", 
Packit Service 501009
				ext->filename);
Packit Service 501009
			free(ext);
Packit Service 501009
			return;
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
       /*
Packit Service 501009
        *  register_extension() will be called by the shared object's
Packit Service 501009
        *  _init() function before dlopen() returns below.
Packit Service 501009
	*/
Packit Service 501009
	pc->curext = ext;
Packit Service 501009
	ext->handle = dlopen(ext->filename, RTLD_NOW|RTLD_GLOBAL); 
Packit Service 501009
Packit Service 501009
	if (!ext->handle) {
Packit Service 501009
		strcpy(buf, dlerror());
Packit Service 501009
		error(INFO, "%s\n", buf);
Packit Service 501009
		if (strstr(buf, "undefined symbol: register_extension")) {
Packit Service 501009
			error(INFO, "%s may be statically linked: ",
Packit Service 501009
				pc->program_name);
Packit Service 501009
			fprintf(fp, "recompile without the -static flag\n");
Packit Service 501009
		}
Packit Service 501009
		free(ext);
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if (!(ext->flags & REGISTERED)) {
Packit Service 501009
		dlclose(ext->handle);
Packit Service 501009
		if (ext->flags & (DUPLICATE_COMMAND_NAME | NO_MINIMAL_COMMANDS))
Packit Service 501009
			error(INFO, 
Packit Service 501009
		         "%s: shared object unloaded\n", ext->filename);
Packit Service 501009
		else
Packit Service 501009
			error(INFO, 
Packit Service 501009
		         "%s: no commands registered: shared object unloaded\n",
Packit Service 501009
				ext->filename);
Packit Service 501009
		free(ext);
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	fprintf(fp, "%s: shared object loaded\n", ext->filename);
Packit Service 501009
Packit Service 501009
	/*
Packit Service 501009
	 *  Put new libraries at the head of the list.
Packit Service 501009
         */
Packit Service 501009
	if (extension_table) {
Packit Service 501009
		extension_table->prev = ext;
Packit Service 501009
		ext->next = extension_table;
Packit Service 501009
	}
Packit Service 501009
	extension_table = ext;
Packit Service 501009
Packit Service 501009
	help_init();
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Check the extensions library directories.
Packit Service 501009
 */
Packit Service 501009
static int
Packit Service 501009
in_extensions_library(char *lib, char *buf)
Packit Service 501009
{
Packit Service 501009
	char *env;
Packit Service 501009
Packit Service 501009
	if ((env = getenv("CRASH_EXTENSIONS"))) {
Packit Service 501009
		sprintf(buf, "%s%s%s", env,
Packit Service 501009
			LASTCHAR(env) == '/' ? "" : "/",
Packit Service 501009
			lib);
Packit Service 501009
		if (file_exists(buf, NULL))
Packit Service 501009
			return TRUE;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if (BITS64()) {
Packit Service 501009
		sprintf(buf, "/usr/lib64/crash/extensions/%s", lib);
Packit Service 501009
		if (file_exists(buf, NULL))
Packit Service 501009
			return TRUE;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
       	sprintf(buf, "/usr/lib/crash/extensions/%s", lib);
Packit Service 501009
	if (file_exists(buf, NULL))
Packit Service 501009
		return TRUE;
Packit Service 501009
 
Packit Service 501009
       	sprintf(buf, "./extensions/%s", lib);
Packit Service 501009
	if (file_exists(buf, NULL))
Packit Service 501009
		return TRUE;
Packit Service 501009
Packit Service 501009
	return FALSE;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 * Look for an extensions directory using the proper order. 
Packit Service 501009
 */
Packit Service 501009
static char *
Packit Service 501009
get_extensions_directory(char *dirbuf)
Packit Service 501009
{
Packit Service 501009
	char *env;
Packit Service 501009
Packit Service 501009
	if ((env = getenv("CRASH_EXTENSIONS"))) {
Packit Service 501009
		if (is_directory(env)) {
Packit Service 501009
			strcpy(dirbuf, env);
Packit Service 501009
			return dirbuf;
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if (BITS64()) {
Packit Service 501009
		sprintf(dirbuf, "/usr/lib64/crash/extensions");
Packit Service 501009
		if (is_directory(dirbuf))
Packit Service 501009
			return dirbuf;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
       	sprintf(dirbuf, "/usr/lib/crash/extensions");
Packit Service 501009
	if (is_directory(dirbuf))
Packit Service 501009
		return dirbuf;
Packit Service 501009
 
Packit Service 501009
       	sprintf(dirbuf, "./extensions");
Packit Service 501009
	if (is_directory(dirbuf))
Packit Service 501009
		return dirbuf;
Packit Service 501009
Packit Service 501009
	return NULL;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
Packit Service 501009
void
Packit Service 501009
preload_extensions(void)
Packit Service 501009
{
Packit Service 501009
	DIR *dirp;
Packit Service 501009
	struct dirent *dp;
Packit Service 501009
	char dirbuf[BUFSIZE];
Packit Service 501009
	char filename[BUFSIZE*2];
Packit Service 501009
	int found;
Packit Service 501009
Packit Service 501009
	if (!get_extensions_directory(dirbuf))
Packit Service 501009
		return;
Packit Service 501009
Packit Service 501009
        dirp = opendir(dirbuf);
Packit Service 501009
	if (!dirp) {
Packit Service 501009
		error(INFO, "%s: %s\n", dirbuf, strerror(errno));
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	pc->curcmd = pc->program_name;
Packit Service 501009
Packit Service 501009
        for (found = 0, dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
Packit Service 501009
		sprintf(filename, "%s%s%s", dirbuf, 
Packit Service 501009
			LASTCHAR(dirbuf) == '/' ? "" : "/",
Packit Service 501009
			dp->d_name);
Packit Service 501009
Packit Service 501009
		if (!is_shared_object(filename))
Packit Service 501009
			continue;
Packit Service 501009
Packit Service 501009
		found++;
Packit Service 501009
Packit Service 501009
		load_extension(dp->d_name);
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	closedir(dirp);
Packit Service 501009
	
Packit Service 501009
	if (found)
Packit Service 501009
		fprintf(fp, "\n");
Packit Service 501009
	else
Packit Service 501009
		error(NOTE, 
Packit Service 501009
		    "%s: no extension modules found in directory\n\n",
Packit Service 501009
			dirbuf);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Unload all, or as specified, extension libraries.
Packit Service 501009
 */
Packit Service 501009
void 
Packit Service 501009
unload_extension(char *lib)
Packit Service 501009
{
Packit Service 501009
        struct extension_table *ext;
Packit Service 501009
	int found;
Packit Service 501009
	char buf[BUFSIZE];
Packit Service 501009
Packit Service 501009
	if (!lib) {
Packit Service 501009
		while (extension_table) {
Packit Service 501009
			ext = extension_table;
Packit Service 501009
                        if (dlclose(ext->handle))
Packit Service 501009
                                error(FATAL,
Packit Service 501009
                                    "dlclose: %s: shared object not open\n",
Packit Service 501009
                                        ext->filename);
Packit Service 501009
Packit Service 501009
			fprintf(fp, "%s: shared object unloaded\n", 
Packit Service 501009
				ext->filename);
Packit Service 501009
Packit Service 501009
			extension_table = ext->next;
Packit Service 501009
			free(ext);
Packit Service 501009
		}
Packit Service 501009
Packit Service 501009
		help_init();
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if ((*lib != '.') && (*lib != '/')) {
Packit Service 501009
		if (!file_exists(lib, NULL) &&
Packit Service 501009
		    in_extensions_library(lib, buf))
Packit Service 501009
			lib = buf;
Packit Service 501009
	} 
Packit Service 501009
Packit Service 501009
	if (!file_exists(lib, NULL)) {
Packit Service 501009
		error(INFO, "%s: %s\n", lib, strerror(ENXIO));
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
        for (ext = extension_table, found = FALSE; ext; ext = ext->next) {
Packit Service 501009
                if (same_file(lib, ext->filename)) {
Packit Service 501009
			found = TRUE;
Packit Service 501009
			if (dlclose(ext->handle))
Packit Service 501009
				error(INFO, 
Packit Service 501009
				    "dlclose: %s: shared object not open\n", 
Packit Service 501009
					ext->filename);
Packit Service 501009
			else {
Packit Service 501009
				fprintf(fp, "%s: shared object unloaded\n",
Packit Service 501009
					ext->filename);
Packit Service 501009
Packit Service 501009
				if (extension_table == ext) {       /* first */
Packit Service 501009
					extension_table = ext->next;
Packit Service 501009
					if (ext->next)
Packit Service 501009
						ext->next->prev = NULL;
Packit Service 501009
				} else if (ext->next == NULL)       /* last */
Packit Service 501009
					ext->prev->next = NULL;
Packit Service 501009
				else {                              /* middle */
Packit Service 501009
					ext->prev->next = ext->next;
Packit Service 501009
					ext->next->prev = ext->prev;
Packit Service 501009
				}
Packit Service 501009
Packit Service 501009
				free(ext);
Packit Service 501009
				help_init();
Packit Service 501009
				break;
Packit Service 501009
			}
Packit Service 501009
		}
Packit Service 501009
		else if (STREQ(basename(lib), basename(ext->filename))) {
Packit Service 501009
			error(INFO, "%s and %s are different object files\n",
Packit Service 501009
				lib, ext->filename);
Packit Service 501009
			found = TRUE;
Packit Service 501009
		}
Packit Service 501009
        }
Packit Service 501009
Packit Service 501009
	if (!found)
Packit Service 501009
		error(INFO, "%s: not loaded\n", lib);
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/*
Packit Service 501009
 *  Register the command_table as long as there are no command namespace
Packit Service 501009
 *  clashes with the currently-existing command set.  Also delete any aliases
Packit Service 501009
 *  that clash, giving the registered command name priority.
Packit Service 501009
 *
Packit Service 501009
 *  This function is called from the shared object's _init() function
Packit Service 501009
 *  before the dlopen() call returns back to load_extension() above.  
Packit Service 501009
 *  The mark of approval for load_extension() is the setting of the 
Packit Service 501009
 *  REGISTERED bit in the "current" extension_table structure flags.
Packit Service 501009
 */ 
Packit Service 501009
void 
Packit Service 501009
register_extension(struct command_table_entry *command_table)
Packit Service 501009
{
Packit Service 501009
	struct command_table_entry *cp;
Packit Service 501009
Packit Service 501009
	pc->curext->flags |= NO_MINIMAL_COMMANDS;
Packit Service 501009
Packit Service 501009
        for (cp = command_table; cp->name; cp++) {
Packit Service 501009
		if (get_command_table_entry(cp->name)) {
Packit Service 501009
			error(INFO, 
Packit Service 501009
                  "%s: \"%s\" is a duplicate of a currently-existing command\n",
Packit Service 501009
				pc->curext->filename, cp->name);
Packit Service 501009
			pc->curext->flags |= DUPLICATE_COMMAND_NAME;
Packit Service 501009
			return;
Packit Service 501009
		}
Packit Service 501009
		if (cp->flags & MINIMAL)
Packit Service 501009
			pc->curext->flags &= ~NO_MINIMAL_COMMANDS;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if ((pc->flags & MINIMAL_MODE) && (pc->curext->flags & NO_MINIMAL_COMMANDS)) {
Packit Service 501009
		error(INFO, 
Packit Service 501009
		      "%s: does not contain any commands which support minimal mode\n",
Packit Service 501009
		      pc->curext->filename);
Packit Service 501009
		return;
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	if (pc->flags & MINIMAL_MODE) {
Packit Service 501009
		for (cp = command_table; cp->name; cp++) {
Packit Service 501009
			if (!(cp->flags & MINIMAL)) {
Packit Service 501009
				error(WARNING, 
Packit Service 501009
				      "%s: command \"%s\" does not support minimal mode\n",
Packit Service 501009
				      pc->curext->filename, cp->name);
Packit Service 501009
			}
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
        for (cp = command_table; cp->name; cp++) {
Packit Service 501009
		if (is_alias(cp->name)) {
Packit Service 501009
			error(INFO, 
Packit Service 501009
               "alias \"%s\" deleted: name clash with extension command\n",
Packit Service 501009
				cp->name);
Packit Service 501009
			deallocate_alias(cp->name);
Packit Service 501009
		}
Packit Service 501009
	}
Packit Service 501009
Packit Service 501009
	pc->curext->command_table = command_table;   
Packit Service 501009
	pc->curext->flags |= REGISTERED;             /* Mark of approval */
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
/* 
Packit Service 501009
 *  Hooks for sial.
Packit Service 501009
 */
Packit Service 501009
unsigned long 
Packit Service 501009
get_curtask(void) 
Packit Service 501009
{ 
Packit Service 501009
	return CURRENT_TASK(); 
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
char *
Packit Service 501009
crash_global_cmd(void) 
Packit Service 501009
{ 
Packit Service 501009
	return pc->curcmd;
Packit Service 501009
}
Packit Service 501009
Packit Service 501009
struct command_table_entry *
Packit Service 501009
crash_cmd_table(void) 
Packit Service 501009
{ 
Packit Service 501009
	return pc->cmd_table; 
Packit Service 501009
}