📄 tcl_util.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 + -