⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcl_util.c

📁 网络数据管理协议的开发
💻 C
字号:
/*                               -*- Mode: C -*-  * tcl_util.c *  * Description     : Miscellaneous Tcl utility functions. *  * Copyright (c) 1996,1997 PDC, Network Appliance. All Rights Reserved. * * $Id: tcl_util.c,v 1.10 1998/02/16 21:08:13 tim Exp $ */#if !defined(lint) && !defined(SABER)static char rcsId[] __attribute__ ((unused)) = "@(#) $Id: tcl_util.c,v 1.10 1998/02/16 21:08:13 tim Exp $";#endif#include <tcl.h>#include <string.h>#include "ndmp_common.h"#include "ndmpc.h"typedef int	CommandFunc(void*, Tcl_Interp*, int, char*[]);bool_t	optionVerboseFh = TRUE;static CommandFunc	helpCmd;static CommandFunc	ndmpcOptionCmd;extern CommandFunc	connectOpenCmd;extern CommandFunc	connectClientAuthCmd;extern CommandFunc	connectCloseCmd;extern CommandFunc	connectServerAuthCmd;extern CommandFunc	configGetHostInfoCmd;extern CommandFunc	configGetConnectionTypeCmd;extern CommandFunc	configGetAuthAttrCmd;extern CommandFunc	configGetButypeInfoCmd;extern CommandFunc	configGetFsInfoCmd;extern CommandFunc	configGetTapeInfoCmd;extern CommandFunc	configGetScsiInfoCmd;extern CommandFunc	configGetServerInfoCmd;extern CommandFunc	scsiOpenCmd;extern CommandFunc	scsiCloseCmd;extern CommandFunc	scsiGetStateCmd;extern CommandFunc	scsiResetDeviceCmd;extern CommandFunc	scsiResetBusCmd;extern CommandFunc	scsiSetTargetCmd;extern CommandFunc	scsiExecuteCdbCmd;extern CommandFunc	tapeOpenCmd;extern CommandFunc	tapeCloseCmd;extern CommandFunc	tapeGetStateCmd;extern CommandFunc	tapeMtioCmd;extern CommandFunc	tapeWriteCmd;extern CommandFunc	tapeFWriteCmd;extern CommandFunc	tapeReadCmd;extern CommandFunc	tapeFReadCmd;extern CommandFunc	tapeExecuteCdbCmd;extern CommandFunc	dataGetStateCmd;extern CommandFunc	dataStartBackupCmd;extern CommandFunc	dataStartRecoverCmd;extern CommandFunc	dataAbortCmd;extern CommandFunc	dataGetEnvCmd;extern CommandFunc	dataStopCmd;extern CommandFunc	dataListenCmd;extern CommandFunc	dataConnectCmd;extern CommandFunc	moverGetStateCmd;extern CommandFunc	moverListenCmd;extern CommandFunc	moverContinueCmd;extern CommandFunc	moverAbortCmd;extern CommandFunc	moverStopCmd;extern CommandFunc	moverSetWindowCmd;extern CommandFunc	moverReadCmd;extern CommandFunc	moverCloseCmd;extern CommandFunc	moverSetRecordSizeCmd;extern CommandFunc	moverConnectCmd;extern CommandFunc	addNotifyProcCmd;extern CommandFunc	addEnvCmd;extern CommandFunc	clearEnvCmd;extern CommandFunc	printEnvCmd;extern CommandFunc	addNlistCmd;extern CommandFunc	clearNlistCmd;extern CommandFunc	printNlistCmd;struct Command{	char			*name;	CommandFunc		*func;	char			*usage;};static struct Command Commands[] ={	{"connect_open",		connectOpenCmd,			"?version?"},	{"connect_client_auth",	connectClientAuthCmd,	"none|text|md5 ?username password?"},	{"connect_server_auth",	connectServerAuthCmd,	"none|text|md5"},	{"connect_close",		connectCloseCmd,		""},	{"config_get_host_info", configGetHostInfoCmd,	""},	{"config_get_connection_type", configGetConnectionTypeCmd,	""},	{"config_get_auth_attr", configGetAuthAttrCmd,	"none|text|md5"},	{"config_get_butype_info",	configGetButypeInfoCmd,	""},	{"config_get_fs_info",	configGetFsInfoCmd,		""},	{"config_get_tape_info",	configGetTapeInfoCmd,	""},	{"config_get_scsi_info",	configGetScsiInfoCmd,	""},	{"config_get_server_info",	configGetServerInfoCmd,	""},	{"tape_open",			tapeOpenCmd,			"device-name ?r|rw?"},	{"tape_close",			tapeCloseCmd,			""},	{"tape_get_state",		tapeGetStateCmd,		""},	{"tape_mtio",			tapeMtioCmd,			"fsf|bsf|fsr|bsr|rew|weof|off ?count?"},	{"tape_write",			tapeWriteCmd,			"data"},	{"tape_fwrite",			tapeFWriteCmd,			"data-file ?record-size?"},	{"tape_read",			tapeReadCmd,			"length"},	{"tape_fread",			tapeFReadCmd,			"data-file ?record-size?"},	{"tape_execute_cdb",	tapeExecuteCdbCmd,		"flags timeout alloc-len cdb-num"},	{"data_get_state", 		dataGetStateCmd, 		""},	{"data_start_backup", 	dataStartBackupCmd,		"backup-type"},	{"data_start_recover", 	dataStartRecoverCmd, 	"backup-type"},	{"data_abort", 			dataAbortCmd, 			""},	{"data_stop", 			dataStopCmd, 			""},	{"data_get_env", 		dataGetEnvCmd, 			""},	{"data_listen", 		dataListenCmd, 			"local|tcp|fc|ipc"},	{"data_connect", 		dataConnectCmd,			"local|tcp|fc|ipc address"},	{"scsi_open", 			scsiOpenCmd, 			"device-name"},	{"scsi_close", 			scsiCloseCmd,			""},	{"scsi_get_state", 		scsiGetStateCmd,		""},	{"scsi_reset_device",	scsiResetDeviceCmd,		""},	{"scsi_reset_bus", 		scsiResetBusCmd,		""},	{"scsi_set_target",		scsiSetTargetCmd,		"controller id lun"},	{"scsi_execute_cdb", 	scsiExecuteCdbCmd,		"flags timeout alloc-len cdb-num"},	{"mover_get_state", 	moverGetStateCmd,		""},	{"mover_listen",	 	moverListenCmd,			"read|write local|tcp|fc|ipc"},	{"mover_continue", 		moverContinueCmd,		""},	{"mover_abort",		 	moverAbortCmd,			""},	{"mover_stop",		 	moverStopCmd,			""},	{"mover_set_window", 	moverSetWindowCmd,		"offset length"},	{"mover_read", 			moverReadCmd,			"offset length"},	{"mover_close", 		moverCloseCmd,			""},	{"mover_set_record_size",	moverSetRecordSizeCmd,	"size"},	{"mover_connect", 		moverConnectCmd,		"local|tcp|fc|ipc address"},	{"add_notify_proc",		addNotifyProcCmd,		"proc"},	{"add_env", 			addEnvCmd,				"name value"},	{"clear_env", 			clearEnvCmd,			""},	{"print_env", 			printEnvCmd,			""},	{"add_nlist", 			addNlistCmd,			"name destination ?fh_info?"},	{"clear_nlist", 		clearNlistCmd,			""},	{"print_nlist", 		printNlistCmd,			""},	{"ndmpc_option", 		ndmpcOptionCmd,			"?fh_terse|fh_verbose?"},	{"help",				helpCmd,				""},	{"", 0, 0},};const u_long numCmds = ((sizeof(Commands) /						 sizeof(struct Command)) - 1);struct Tcl_DString	tclCommand;/* * ndmpcTclInit * * Create the Tcl interpreter and register the ndmpc Tcl commands. * * Parameters: *   client_data (Input) - pointer to be passed to each ndmpc Tcl *                         command when the command is called. * Returns: *   void */Tcl_Interp*ndmpcTclInit(void*	client_data){	Tcl_Interp*	interp;	u_long		i;		interp = Tcl_CreateInterp();	for (i = 0; i < numCmds; i++) 		Tcl_CreateCommand(interp, Commands[i].name,						  Commands[i].func, client_data, 0);	Tcl_DStringInit(&tclCommand);	printf("ndmpc> ");	fflush(stdout);	return(interp);}voidndmpcNewTclInit(Tcl_Interp*	interp,				void*		client_data){	u_long i;	for (i = 0; i < numCmds; i++) 		Tcl_CreateCommand(interp, Commands[i].name,						  Commands[i].func, client_data, 0);}/* * ndmpcProcessTclCmdString * * Process Tcl command data. * * Parameters: *   s (Input) - command string. * * Returns: *   void */voidndmpcProcessTclCmdString(Tcl_Interp*	interp,						 char*			s){	char	*cmd;	int		code; 	cmd = Tcl_DStringAppend(&tclCommand, s, -1);	if (!Tcl_CommandComplete(cmd))		return; 	code = Tcl_RecordAndEval(interp, cmd, 0);	Tcl_DStringFree(&tclCommand);	if (code != TCL_OK)	{		fprintf(stderr, "%s\n", interp->result);	}	else if ((*interp->result != 0))	{		printf("%s\n", interp->result);	}		printf("ndmpc> ");	fflush(stdout);}/* * ndmpErrToName *   Returns the name of the specified error code. * * Parameters: *   err (input) - NDMP error code. * * Returns: *   Name of error. */char*ndmpErrToName(ndmp_error	err){	switch (err)	{		case NDMP_NO_ERR:			return "NDMP_NO_ERR";		case NDMP_NOT_SUPPORTED_ERR:			return "NDMP_NOT_SUPPORTED_ERR";		case NDMP_DEVICE_BUSY_ERR:			return "NDMP_DEVICE_BUSY_ERR";		case NDMP_DEVICE_OPENED_ERR:			return "NDMP_DEVICE_OPENED_ERR";		case NDMP_NOT_AUTHORIZED_ERR:			return "NDMP_NOT_AUTHORIZED_ERR";		case NDMP_PERMISSION_ERR:			return "NDMP_PERMISSION_ERR";		case NDMP_DEV_NOT_OPEN_ERR:			return "NDMP_DEV_NOT_OPEN_ERR";		case NDMP_IO_ERR:			return "NDMP_IO_ERR";		case NDMP_TIMEOUT_ERR:			return "NDMP_TIMEOUT_ERR";		case NDMP_ILLEGAL_ARGS_ERR:			return "NDMP_ILLEGAL_ARGS_ERR";		case NDMP_NO_TAPE_LOADED_ERR:			return "NDMP_NO_TAPE_LOADED_ERR";		case NDMP_WRITE_PROTECT_ERR:			return "NDMP_WRITE_PROTECT_ERR";		case NDMP_EOF_ERR:			return "NDMP_EOF_ERR";		case NDMP_EOM_ERR:			return "NDMP_EOM_ERR";		case NDMP_FILE_NOT_FOUND_ERR:			return "NDMP_FILE_NOT_FOUND_ERR";		case NDMP_BAD_FILE_ERR:			return "NDMP_BAD_FILE_ERR";		case NDMP_NO_DEVICE_ERR:			return "NDMP_NO_DEVICE_ERR";		case NDMP_NO_BUS_ERR:			return "NDMP_NO_BUS_ERR";		case NDMP_XDR_DECODE_ERR:			return "NDMP_XDR_DECODE_ERR";		case NDMP_ILLEGAL_STATE_ERR:			return "NDMP_ILLEGAL_STATE_ERR";		case NDMP_UNDEFINED_ERR:			return "NDMP_UNDEFINED_ERR";		case NDMP_XDR_ENCODE_ERR:			return "NDMP_XDR_ENCODE_ERR";		case NDMP_NO_MEM_ERR:			return "NDMP_NO_MEM_ERR";		default:			return "Unknown";	}}/* * ndmpErrToStr *   Returns the error string for the specified error code. * * Parameters: *   err (input) - NDMP error code. * * Returns: *   Error string. */char*ndmpErrToStr(ndmp_error	err){	switch (err)	{		case NDMP_NO_ERR:			return "No error";		case NDMP_NOT_SUPPORTED_ERR:			return "Error: Call is not supported";		case NDMP_DEVICE_BUSY_ERR:			return "Error: The device is in use";		case NDMP_DEVICE_OPENED_ERR:			return "Error: Another tape or scsi device is already open";		case NDMP_NOT_AUTHORIZED_ERR:			return "Error: Connection has not been authorized";		case NDMP_PERMISSION_ERR:			return "Error: Permission denied";		case NDMP_DEV_NOT_OPEN_ERR:			return "Error: Device is not open";		case NDMP_IO_ERR:			return "Error: I/O error";		case NDMP_TIMEOUT_ERR:			return "Error: Command timed out";		case NDMP_ILLEGAL_ARGS_ERR:			return "Error: Illegal arguments in request";		case NDMP_NO_TAPE_LOADED_ERR:			return "Error: Cannot open because there is no tape loaded";		case NDMP_WRITE_PROTECT_ERR:			return "Error: Tape cannot be open for write";		case NDMP_EOF_ERR:			return "Error: Command encountered EOF";		case NDMP_EOM_ERR:			return "Error: Command encountered EOM";		case NDMP_FILE_NOT_FOUND_ERR:			return "Error: File not found during restore";		case NDMP_BAD_FILE_ERR:			return "Error: Bad file";		case NDMP_NO_DEVICE_ERR:			return "Error: Invalid device";		case NDMP_NO_BUS_ERR:			return "Error: Invalid bus";		case NDMP_XDR_DECODE_ERR:			return "Error: Decoding arguments";		case NDMP_ILLEGAL_STATE_ERR:			return "Error: Invalid state to process request";		case NDMP_UNDEFINED_ERR:			return "Error: Undefined";		case NDMP_XDR_ENCODE_ERR:			return "Error: Encoding arguments";		case NDMP_NO_MEM_ERR:			return "Error: Allocating memory";		default:			return "Error: unknown error";	}}/* * ndmpcCheckNdmpSend *   Sets the Tcl result after a call to ndmpSendRequest. * * Parameters: *   interp    (input) - Tcl interpreter. *   sendErr   (input) - error returned from ndmpSendRequest. *   bodyErr   (input) - error returned in the reply message body. * * Returns: *   error code if the request failed. *   0 if request was successful.  */intndmpcCheckNdmpSend(Tcl_Interp*	interp,				   int			sendErr,				   int			bodyErr){	if (sendErr < 0)	{		Tcl_SetResult(interp, "ndmpSendRequest failed", TCL_STATIC);		return(sendErr);	}	if (sendErr)	{		Tcl_SetResult(interp, ndmpErrToStr(sendErr), TCL_STATIC);		return(sendErr);	}	if (bodyErr)	{		Tcl_SetResult(interp, ndmpErrToStr(bodyErr), TCL_STATIC);		return(bodyErr);	}	return(0);}/* * ndmpcTclAddToResult *   Add a element/value pair sublist to the current *   command result list. *   The NDMP tcl commands return NDMP structures in a connoical format. *   The format represents the XDR structure like this: *     { element1 value1 } { element2 value2 } ... * *   The command return value is a list of sub-lists, where each *   sublist has the element name as its first element, and the value of *   the element as its second argument. * * Parameters: *   interp  (input) - Tcl interpreter. *   element (input) - element name. *   value   (input) - element value as a string. * * Returns: *   void */voidndmpcTclAddToResult(Tcl_Interp*	interp,					char*		element,					char*		value){    Tcl_AppendResult(interp, "{", element, NULL);    Tcl_AppendElement(interp, value);    Tcl_AppendResult(interp, "}\n", NULL);}/* * ndmpcTclAddHexToResult *   Add a element/value pair sublist to the current *   command result list. The binary value data is displayed *   in hex format. *   The NDMP tcl commands return NDMP structures in a connoical format. *   The format represents the XDR structure like this: *     { element1 value1 } { element2 value2 } ... * *   The command return value is a list of sub-lists, where each *   sublist has the element name as its first element, and the value of *   the element as its second argument. * * Parameters: *   interp  (input) - Tcl interpreter. *   element (input) - element name. *   value   (input) - binary element value. *   length  (input) - length of value. * * Returns: *   void */voidndmpcTclAddHexToResult(Tcl_Interp*	interp,					   char*		element,					   char*		value,					   u_long		length){	u_long	i;	    Tcl_AppendResult(interp, "{", element, "\n", NULL);	for (i = 0; i < length; i+= 16)	{		char	buf[128];		char	*p = buf;		u_long	j;				for (j = 0; j < 16 && i+j < length; j++)		{			sprintf(p, "%02x ", (u_int)value[i+j]&0xff);			p += 3;		}		*p++ = '\n';		*p = '\0';		Tcl_AppendResult(interp, buf, NULL);	}	    Tcl_AppendResult(interp, "}\n", NULL);}/* * helpCmd *   Tcl command. *   Displays a list of all ndmpc Tcl commands and their usage. * * Parameters: *   clientData (input) - connection handle. *   interp     (input) - Tcl interpreter. *   argc       (input) - argument count. *   argv       (input) - arguments. * * Returns: *   Tcl error code. */static inthelpCmd(void*		clientData __attribute__ ((unused)),		Tcl_Interp*	interp,		int			argc __attribute__ ((unused)),		char*		argv[] __attribute__ ((unused))){	u_long	i;	for (i = 0; i < numCmds; i++)	{		printf("%s %s\n",			   Commands[i].name,			   Commands[i].usage);		fflush(stdout);	}		Tcl_SetResult(interp, "", TCL_STATIC);	return TCL_OK;}/* * ndmpcOptionCmd *   Tcl command. *   Sets options that control ndmpc behavior. * * Parameters: *   clientData (input) - connection handle. *   interp     (input) - Tcl interpreter. *   argc       (input) - argument count. *   argv       (input) - arguments. * * Returns: *   Tcl error code. */static intndmpcOptionCmd(void*		clientData __attribute__ ((unused)),			   Tcl_Interp*	interp,			   int			argc,			   char*		argv[]){	int	i;	if (argc == 1)	{		if (optionVerboseFh == TRUE)			printf("fh_verbose\n");		else			printf("fh_terse\n");		Tcl_SetResult(interp, "", TCL_STATIC);		return TCL_OK;	}		for (i = 1; i < argc; i++)	{		if (strcmp(argv[i], "fh_terse") == 0)			optionVerboseFh = FALSE;		else if (strcmp(argv[i], "fh_verbose") == 0)			optionVerboseFh = TRUE;		else		{			Tcl_SetResult(interp,						  "usage: ndmpc_option ?fh_terse|fh_verbose?",						  TCL_STATIC);			return(TCL_ERROR);		}			}		Tcl_SetResult(interp, "", TCL_STATIC);	return TCL_OK;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -