$! ************************************************* $! * KILLUSER_PACKAGE.COM $! * This command procedure will extract all source modules required $! * to create the KILLUSER package. After extracting the files, $! * this procedure will optionally execute the BUILD.COM command $! * procedure included with this package to compile the source files and $! * link the executable image. $! * $! * Created 29-MAR-2000 by the PACKAGE utility $! ************************************************* $! $ Write SYS$OUTPUT "" $ Write SYS$OUTPUT "This procedure extracts and optionally builds the KILLUSER package." $ Write SYS$OUTPUT "All files will be extracted to ",F$Environment("Default") $ Write SYS$OUTPUT "" $ Call Extract_Files $ Write SYS$OUTPUT "" $ Get_Answer: $ Read/Error=Exit/Prompt="Do you wish to build the KILLUSER package? " - SYS$COMMAND Answer $ Answer = F$Extract(0,1,F$Edit(Answer,"Trim,UpCase")) $ If Answer .EQS. "N" Then Goto Exit $ If Answer .NES. "Y" Then Goto Get_Answer $ @BUILD.COM $ Exit: $ Exit $! $! $ Extract_Files: SubRoutine $ Call Extract_BUILD_COM $ Call Extract_CLI_C $ Call Extract_CLI_H $ Call Extract_KILLUSER_C $ Call Extract_KILLUSER_H $ Call Extract_KILLUSER_HLP $ Call Extract_KILLUSER_OPT $ Call Extract_KILLUSER_CLD_CLD $ Call Extract_MESSAGE_H $ Call Extract_MESSAGE_MSG $ Call Extract_UTILS_C $ Call Extract_UTILS_H $ EndSubRoutine ! Extract_Files $! $! $! $ Extract_BUILD_COM: SubRoutine $ Write SYS$OUTPUT "Extracting BUILD.COM..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile BUILD.COM $ WO "$! **********************************************************************" $ WO "$! * BUILD.COM *" $ WO "$! * (Re)build necessary modules and relink program. *" $ WO "$! * *" $ WO "$! * This is a generic ""make"" command procedure. Modify the section *" $ WO "$! * below with the following symbols: *" $ WO "$! * *" $ WO "$! * Image_Name = ""xxx.EXE"" - the name of the output image name *" $ WO "$! * Version = ""Vn.n"" - the version number of the product *" $ WO "$! * Object_List == """" - this symbol must be defined as null *" $ WO "$! * *" $ WO "$! * Then add or modify the ""Call"" lines for each module in the *" $ WO "$! * program: *" $ WO "$! * *" $ WO "$! * Call Compile_C filename.C ''SQ'P1''SQ' - for each C source module *" $ WO "$! * Call Message filename.MSG ''SQ'P1''SQ' - for each message source mod *" $ WO "$! * Call CLD filename.CLD ''SQ'P1''SQ' - for each CLD source module *" $ WO "$! * *" $ WO "$! * BUILD will recompile only those modules which have changed *" $ WO "$! * since last compile and relink the image. *" $ WO "$! * *" $ WO "$! * If you specify ""ALL"" as parameter P1, all source modules are *" $ WO "$! * unconditionally recompiled. *" $ WO "$! * *" $ WO "$! * 18-DEC-1996 RDJ Command Procedure Creation. *" $ WO "$! **********************************************************************" $ WO "$!" $ WO "$ Object_List == """"" $ WO "$ Image_Name = ""KILLUSER.EXE""" $ WO "$ Version = ""V1.0""" $ WO "$!" $ WO "$ Call Compile_C KILLUSER.C ''SQ'P1''SQ'" $ WO "$ Call Compile_C UTILS.C ''SQ'P1''SQ'" $ WO "$ Call Compile_C CLI.C ''SQ'P1''SQ'" $ WO "$ Call Message MESSAGE.MSG ''SQ'P1''SQ'" $ WO "$ Call CLD KILLUSER_CLD.CLD ''SQ'P1''SQ'" $ WO "$!" $ WO "$! **************************************************************************" $ WO "$ Write SYS$OUTPUT ""Linking ",SQ2,"Image_Name''SQ'...""" $ WO "$ PID = F$GetJPI("""",""PID"")" $ WO "$ On Error Then Goto Cleanup" $ WO "$ If F$GetSyi(""Arch_Name"") .EQS. ""VAX""" $ WO "$ Then" $ WO "$ Close/NoLog OutFile" $ WO "$ Open/Write OutFile SYS$SCRATCH:BUILD_TMP.''SQ'PID''SQ'" $ WO "$ Write OutFile ""$ Link/Exec=",SQ2,"Image_Name''SQ'/NoTrace SYS$INPUT/Opt""" $ WO "$ Write OutFile """,SQ2,"Object_List''SQ',SYS$SHARE:VAXCRTL/Share""" $ WO "$ Write OutFile ""IDENTIFICATION=",SQ2,"Version''SQ'""" $ WO "$ Close OutFile" $ WO "$ @SYS$SCRATCH:BUILD_TMP.''SQ'PID''SQ'" $ WO "$ Else" $ WO "$ Close/NoLog OutFile" $ WO "$ Open/Write OutFile SYS$SCRATCH:BUILD_TMP.''SQ'PID''SQ'" $ WO "$ Write OutFile ""$ Link/Exec=",SQ2,"Image_Name''SQ'/NoTrace SYS$INPUT/Opt""" $ WO "$ Write OutFile Object_List" $ WO "$ Write OutFile ""IDENTIFICATION=",SQ2,"Version''SQ'""" $ WO "$ Close OutFile" $ WO "$ @SYS$SCRATCH:BUILD_TMP.''SQ'PID''SQ'" $ WO "$ EndIf" $ WO "$ Cleanup:" $ WO "$ Write SYS$OUTPUT ""Cleaning up..""" $ WO "$ If F$Search(""SYS$SCRATCH:BUILD_TMP.",SQ2,"PID''SQ'"") .NES. """" Then -" $ WO " Delete/NoLog/NoConfirm SYS$SCRATCH:BUILD_TMP.''SQ'PID''SQ';*" $ WO "$ Purge/NoLog/NoConfirm *.OBJ" $ WO "$ Purge/NoLog/NoConfirm *.EXE" $ WO "$ Exit" $ WO "$!" $ WO "$! **********************************************************************" $ WO "$! * Compile_C: Compile a ''SQ'C''SQ' source module. *" $ WO "$! **********************************************************************" $ WO "$ Compile_C: SubRoutine" $ WO "$ If Object_List .EQS. """"" $ WO "$ Then" $ WO "$ Object_List == F$Parse(P1,,,""Name"")" $ WO "$ Else" $ WO "$ Object_List == Object_List + "","" + F$Parse(P1,,,""Name"")" $ WO "$ EndIf" $ WO "$ If P2 .EQS. ""ALL"" Then Goto Compile_It" $ WO "$ O_File = F$Parse(P1,,,""Name"") + "".OBJ""" $ WO "$ If F$Search(""",SQ2,"O_File''SQ'"") .EQS. """" Then Goto Compile_It" $ WO "$ Object_Date = F$CvTime(F$File_Attributes(O_File,""RDT""),""Comparison"")" $ WO "$ Source_Date = F$CvTime(F$File_Attributes(P1,""RDT""),""Comparison"")" $ WO "$ If Source_Date .LTS. Object_Date" $ WO "$ Then" $ WO "$ Write SYS$OUTPUT """,SQ2,"P1''SQ' is up to date; skipping...""" $ WO "$ Exit" $ WO "$ EndIf" $ WO "$ Compile_It:" $ WO "$ Write SYS$OUTPUT ""Compiling ",SQ2,"P1''SQ'...""" $ WO "$ If F$GetSyi(""Arch_Name"") .EQS. ""VAX""" $ WO "$ Then" $ WO "$ CC/NoDebug ''SQ'P1''SQ'" $ WO "$ Else" $ WO "$ CC/NoDebug/Standard=VAXC ''SQ'P1''SQ'" $ WO "$ EndIf" $ WO "$ Exit" $ WO "$ EndSubRoutine" $ WO "$!" $ WO "$! **********************************************************************" $ WO "$! * Message: Compile a message module. *" $ WO "$! **********************************************************************" $ WO "$ Message: SubRoutine" $ WO "$ If Object_List .EQS. """"" $ WO "$ Then" $ WO "$ Object_List == F$Parse(P1,,,""Name"")" $ WO "$ Else" $ WO "$ Object_List == Object_List + "","" + F$Parse(P1,,,""Name"")" $ WO "$ EndIf" $ WO "$ If P2 .EQS. ""ALL"" Then Goto Compile_It" $ WO "$ O_File = F$Parse(P1,,,""Name"") + "".OBJ""" $ WO "$ If F$Search(""",SQ2,"O_File''SQ'"") .EQS. """" Then Goto Compile_It" $ WO "$ Object_Date = F$CvTime(F$File_Attributes(O_File,""RDT""),""Comparison"")" $ WO "$ Source_Date = F$CvTime(F$File_Attributes(P1,""RDT""),""Comparison"")" $ WO "$ If Source_Date .LTS. Object_Date" $ WO "$ Then" $ WO "$ Write SYS$OUTPUT """,SQ2,"P1''SQ' is up to date; skipping...""" $ WO "$ Exit" $ WO "$ EndIf" $ WO "$ Compile_It:" $ WO "$ Write SYS$OUTPUT ""Compiling ",SQ2,"P1''SQ'...""" $ WO "$ Message/Object ''SQ'P1''SQ'" $ WO "$ Exit" $ WO "$ EndSubRoutine" $ WO "$!" $ WO "$! **********************************************************************" $ WO "$! * CLD: Compile a CLD module. *" $ WO "$! **********************************************************************" $ WO "$ CLD: SubRoutine" $ WO "$ If Object_List .EQS. """"" $ WO "$ Then" $ WO "$ Object_List == F$Parse(P1,,,""Name"")" $ WO "$ Else" $ WO "$ Object_List == Object_List + "","" + F$Parse(P1,,,""Name"")" $ WO "$ EndIf" $ WO "$ If P2 .EQS. ""ALL"" Then Goto Compile_It" $ WO "$ O_File = F$Parse(P1,,,""Name"") + "".OBJ""" $ WO "$ If F$Search(""",SQ2,"O_File''SQ'"") .EQS. """" Then Goto Compile_It" $ WO "$ Object_Date = F$CvTime(F$File_Attributes(O_File,""RDT""),""Comparison"")" $ WO "$ Source_Date = F$CvTime(F$File_Attributes(P1,""RDT""),""Comparison"")" $ WO "$ If Source_Date .LTS. Object_Date" $ WO "$ Then" $ WO "$ Write SYS$OUTPUT """,SQ2,"P1''SQ' is up to date; skipping...""" $ WO "$ Exit" $ WO "$ EndIf" $ WO "$ Compile_It:" $ WO "$ Write SYS$OUTPUT ""Compiling ",SQ2,"P1''SQ'...""" $ WO "$ Set Command/Object ''SQ'P1''SQ'" $ WO "$ Exit" $ WO "$ EndSubRoutine" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_BUILD_COM $! $ Extract_CLI_C: SubRoutine $ Write SYS$OUTPUT "Extracting CLI.C..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile CLI.C $ WO "/************************************************************************" $ WO " * CLI.C *" $ WO " * *" $ WO " * This module contains routines to parse the CLI command line. *" $ WO " * *" $ WO " ************************************************************************" $ WO " * Revision History *" $ WO " * *" $ WO " * 17-DEC-1996 RDJ Module completion. *" $ WO " ************************************************************************/" $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include ""cli.h""" $ WO "" $ WO "" $ WO "typedef enum {false,true} boolean;" $ WO "" $ WO "/************************************************************************" $ WO " * cli_parse_command_line: parse the CLI command line for correct *" $ WO " * syntax and set up for other command line parsing calls. *" $ WO " ************************************************************************/" $ WO "unsigned long cli_parse_command_line (command_name, command_module)" $ WO "char *command_name;" $ WO "long *command_module;" $ WO "{" $ WO " char command_buffer[256];" $ WO " $DESCRIPTOR (d_line, command_buffer);" $ WO " $DESCRIPTOR (d_cldline, command_buffer);" $ WO " unsigned long status;" $ WO " short int length;" $ WO " int command_length;" $ WO "" $ WO " sprintf (command_buffer, ""%s "", command_name);" $ WO " command_length = strlen(command_buffer);" $ WO " d_line.dsc$w_length = d_line.dsc$w_length - command_length;" $ WO " d_line.dsc$a_pointer = d_line.dsc$a_pointer + command_length;" $ WO " lib$get_foreign(&d_line,0,&length,0);" $ WO " command_buffer[length + command_length] = ''SQ'\0''SQ';" $ WO " d_cldline.dsc$w_length = length + command_length;" $ WO " status = cli$dcl_parse (&d_cldline,command_module,0,0,0);" $ WO " if (status == 196609)" $ WO " return (SS$_NORMAL);" $ WO " if (status == CLI$_ENTNF)" $ WO " return (SS$_NORMAL);" $ WO " exit (SS$_NORMAL);" $ WO "}" $ WO "" $ WO "" $ WO "" $ WO "" $ WO "" $ WO "/************************************************************************" $ WO " * cli_check_qualifier: search the command line for a specific *" $ WO " * qualifier and set a boolean status variable. *" $ WO " ************************************************************************/" $ WO "void cli_check_qualifier (qualifier_name, status)" $ WO "char *qualifier_name; /* name of qualifier to check for */" $ WO "boolean *status; /* status variable */" $ WO "{" $ WO " $DESCRIPTOR (entity_desc,qualifier_name);" $ WO "" $ WO " entity_desc.dsc$w_length = strlen(qualifier_name);" $ WO " switch (cli$present (&entity_desc)) {" $ WO " case CLI$_PRESENT:" $ WO " case CLI$_DEFAULTED:" $ WO " *status = true;" $ WO " break;" $ WO " default:" $ WO " *status = false;" $ WO " }" $ WO "}" $ WO "" $ WO "" $ WO "" $ WO "" $ WO "" $ WO "/************************************************************************" $ WO " * cli_get_value: get the value of a command line entity. *" $ WO " ************************************************************************/" $ WO "unsigned long cli_get_value (entity, value)" $ WO "char *entity; /* entity to get value of */" $ WO "char *value; /* returned value */" $ WO "{" $ WO " $DESCRIPTOR (entity_desc,entity); /* descriptor for entity string */" $ WO " $DESCRIPTOR (value_desc,value); /* descriptor for value string */" $ WO " unsigned short value_length; /* length of returned value */" $ WO " unsigned long status; /* return status of cli$ call */" $ WO "" $ WO " entity_desc.dsc$w_length = strlen(entity);" $ WO " value_desc.dsc$w_length = 256;" $ WO " status = cli$get_value (&entity_desc,&value_desc,&value_length);" $ WO " value[value_length] = ''SQ'\0''SQ';" $ WO " return (status);" $ WO "}" $ WO "" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_CLI_C $! $ Extract_CLI_H: SubRoutine $ Write SYS$OUTPUT "Extracting CLI.H..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile CLI.H $ WO "" $ WO "" $ WO "unsigned long cli_parse_command_line();" $ WO "void cli_check_qualifier();" $ WO "unsigned long cli_get_value();" $ WO "" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_CLI_H $! $ Extract_KILLUSER_C: SubRoutine $ Write SYS$OUTPUT "Extracting KILLUSER.C..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile KILLUSER.C $ WO "/************************************************************************" $ WO " * KILLUSER.C *" $ WO " * Stops all clusterwide interactive (default) processes belonging *" $ WO " * to the specified username. *" $ WO " * *" $ WO " * GROUP privilege is required to kill another user in your UIC *" $ WO " * group. *" $ WO " * WORLD privilege is required to kill another user outside your *" $ WO " * UIC group. *" $ WO " * *" $ WO " * Format: * " $ WO " * KILLUSER [qualifiers] username *" $ WO " * *" $ WO " * Qualifiers: *" $ WO " * /VERSION Display version number only. *" $ WO " * /NODE=nodename Take action only on specified nodename *" $ WO " * (default is cluster-wide). *" $ WO " * /MODE=(modes) Specify process modes to kill. If no modes are *" $ WO " * given, only INTERACTIVE processes are killed. *" $ WO " * Specify one or more of the following: *" $ WO " * (INTERACTIVE, BATCH, NETWORK, DETACHED, ALL) *" $ WO " * *" $ WO " * --- *" $ WO " * http://richj.home.mindspring.com/richware *" $ WO " * --- *" $ WO " * *" $ WO " * 27-MAR-2000 RDJ Program Creation. *" $ WO " ************************************************************************/" $ WO "" $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include ""killuser.h""" $ WO "#include ""utils.h""" $ WO "" $ WO "" $ WO "" $ WO "" $ WO "main () {" $ WO " struct option_struct option; /* command line options */" $ WO " long pctx = 0; /* process scan context */" $ WO " unsigned long status; /* status of system calls */" $ WO " process *proc = NULL; /* current process */" $ WO "" $ WO " parse(&option); /* parse command line */" $ WO " if ((status = pscan_setup(&pctx,&option)) != SS$_NORMAL) exit (status);" $ WO " while ((proc = get_next_process(&pctx)) != NULL) {" $ WO " if (mode_match(proc,&option)) {" $ WO " if ((status = kill_process(proc)) != SS$_NORMAL) lib$signal(status);" $ WO " }" $ WO " }" $ WO " exit (1);" $ WO "}" $ WO "" $ WO "" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_KILLUSER_C $! $ Extract_KILLUSER_H: SubRoutine $ Write SYS$OUTPUT "Extracting KILLUSER.H..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile KILLUSER.H $ WO "/************************************************************************" $ WO " * KILLUSER.H *" $ WO " * Contains tokens, macros, and data structure definitions for *" $ WO " * KILLUSER utility. *" $ WO " * *" $ WO " * 27-MAR-2000 RDJ Program Creation. *" $ WO " ************************************************************************/" $ WO "" $ WO "#define VERSION ""1.0"" /* current version number */" $ WO "" $ WO "" $ WO "" $ WO "typedef enum {false,true} boolean; /* define boolean type */" $ WO "" $ WO "typedef struct nodestruct { /* holds single node name */" $ WO " char nodename[7]; /* operate on this node */" $ WO " struct dsc$descriptor nodename_desc; /* descriptor for above */" $ WO " struct nodestruct *next; /* next node in linked list */" $ WO "} node;" $ WO "" $ WO "struct option_struct { /* command options */" $ WO " char username[13]; /* username to search */" $ WO " struct dsc$descriptor username_desc; /* descriptor for above */" $ WO " boolean interactive; /* kill interactive processes? */" $ WO " boolean batch; /* kill batch processes? */" $ WO " boolean network; /* kill network processes? */" $ WO " boolean detached; /* kill ''SQ'other''SQ' processes? */" $ WO " node *nodelist; /* list of node names */" $ WO "};" $ WO "" $ WO "typedef struct {" $ WO " long pid; /* proccess identification # */" $ WO " char pname[16]; /* process name */" $ WO " long mode; /* process mode */" $ WO " char node[7]; /* executing node */" $ WO " char username[13]; /* process username */" $ WO "} process;" $ WO "" $ WO "typedef struct { /* item list 2 */" $ WO " short buffer_length; /* length of input buffer */" $ WO " short item_code; /* input/output item code */" $ WO " long buffer_address; /* address of buffer; */" $ WO "} item_list_2;" $ WO "" $ WO "typedef struct { /* item list 3 */" $ WO " short buffer_length; /* length of input buffer */" $ WO " short item_code; /* input/output item code */" $ WO " long buffer_address; /* address of buffer */" $ WO " long return_length_address; /* length of output buffer */" $ WO "} item_list_3;" $ WO "" $ WO "" $ WO "extern KILLUSER_CLD_TABLE();" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_KILLUSER_H $! $ Extract_KILLUSER_HLP: SubRoutine $ Write SYS$OUTPUT "Extracting KILLUSER.HLP..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile KILLUSER.HLP $ WO "1 KILLUSER" $ WO "" $ WO "KILLUSER deletes processes belonging to the indicated username." $ WO "GROUP privilege is required to kill processes belonging to another" $ WO "user in your UIC group; WORLD privlege is required to kill" $ WO "processes belonging to another user outside your UIC group." $ WO "Optional qualifiers include specification of process mode and" $ WO "operation on a particular node in a cluster." $ WO "" $ WO "" $ WO "Format:" $ WO "" $ WO " KILLUSER [qualifiers] username" $ WO "" $ WO "2 Parameter" $ WO "" $ WO "username" $ WO "" $ WO " Specifies the username of the process(es) to be killed. This parameter" $ WO " is required." $ WO "" $ WO " KILLUSER requires GROUP privilege to kill processes belonging to" $ WO " another user in your UIC group. WORLD privilege is required to kill" $ WO " processes belonging to another user outside your UIC group." $ WO "" $ WO "2 Command_Qualifiers" $ WO "" $ WO "/MODE" $ WO " /MODE=(option-list)" $ WO "" $ WO " Specifies the mode of the processes to be killed. Specify one or more" $ WO " of the following keywords. Multiple keywords must be enclosed in" $ WO " parenthesis and separated by a comma." $ WO "" $ WO " INTERACTIVE Kills only interactive processes owned by" $ WO " the specified username." $ WO "" $ WO " BATCH Kills only batch processes owned by the specified" $ WO " username." $ WO "" $ WO " NETWORK Kills only network processes owned by the specified" $ WO " username." $ WO "" $ WO " DETACHED Kills only detached processes owned by the specified" $ WO " username." $ WO "" $ WO " OTHER Same as DETACHED." $ WO "" $ WO " ALL Kill all processes owned by the specified username," $ WO " regardless of mode." $ WO "" $ WO "" $ WO " If /MODE is not specified, only INTERACTIVE processes are killed." $ WO "" $ WO "/NODE" $ WO " /NODE=nodename" $ WO "" $ WO " Indicates a specific node to kill processes on. Specify the name of" $ WO " a valid node in the cluster." $ WO "" $ WO " If /NODE is not specified, processes are killed cluster-wide." $ WO "" $ WO "/VERSION" $ WO " /VERSION" $ WO "" $ WO " Displays the current version number of KILLUSER. Do not specify" $ WO " a username parameter with this qualifier." $ WO "" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_KILLUSER_HLP $! $ Extract_KILLUSER_OPT: SubRoutine $ Write SYS$OUTPUT "Extracting KILLUSER.OPT..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile KILLUSER.OPT $ WO "KILLUSER,UTILS,CLI,MESSAGE,KILLUSER_CLD" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_KILLUSER_OPT $! $ Extract_KILLUSER_CLD_CLD: SubRoutine $ Write SYS$OUTPUT "Extracting KILLUSER_CLD.CLD..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile KILLUSER_CLD.CLD $ WO "" $ WO "" $ WO "Module KILLUSER_CLD_TABLE" $ WO "" $ WO "Define Verb KILLUSER" $ WO " Parameter P1, Value(Required,Type=$Quoted_String)" $ WO " Qualifier MODE, Value(Required,Type=MODETYPES,List)" $ WO " Qualifier NODE Value(Required)" $ WO " Qualifier VERSION, Syntax=VERSION_SYNTAX ! Show version number" $ WO " Disallow VERSION and (INTERACTIVE or BATCH or ALL or NODE)" $ WO " Disallow MODE.ALL and (MODE.INTERACTIVE or MODE.BATCH or MODE.DETACHED or" $ WO " MODE.OTHER or MODE.NETWORK)" $ WO "" $ WO "" $ WO "Define Type MODETYPES" $ WO " Keyword INTERACTIVE, Negatable" $ WO " Keyword BATCH, Negatable" $ WO " Keyword DETACHED, Negatable" $ WO " Keyword OTHER, Negatable" $ WO " Keyword NETWORK, Negatable" $ WO " Keyword ALL" $ WO "" $ WO "Define Syntax VERSION_SYNTAX" $ WO " NoParameters" $ WO " Qualifier VERSION, Default" $ WO "" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_KILLUSER_CLD_CLD $! $ Extract_MESSAGE_H: SubRoutine $ Write SYS$OUTPUT "Extracting MESSAGE.H..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile MESSAGE.H $ WO "" $ WO "" $ WO "globalvalue" $ WO " KILLUSER$NOPROCS, /* no processes found */" $ WO " KILLUSER$MEMORY, /* out of dynamic memory */" $ WO " KILLUSER$VERSION; /* current version is ... */" $ WO "" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_MESSAGE_H $! $ Extract_MESSAGE_MSG: SubRoutine $ Write SYS$OUTPUT "Extracting MESSAGE.MSG..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile MESSAGE.MSG $ WO ".TITLE KillUser Messages" $ WO ".IDENT ''SQ'Version 1.0''SQ'" $ WO ".FACILITY KILLUSER,90/PREFIX=KILLUSER$" $ WO ".BASE 100" $ WO "" $ WO ".SEVERITY FATAL" $ WO "MEMORY " $ WO "" $ WO ".SEVERITY ERROR" $ WO "" $ WO "" $ WO ".SEVERITY WARNING" $ WO "NOPROCS /FAO_COUNT=1" $ WO "" $ WO ".SEVERITY INFORMATIONAL" $ WO "VERSION /FAO_COUNT=1" $ WO "" $ WO ".SEVERITY SUCCESS" $ WO ".END" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_MESSAGE_MSG $! $ Extract_UTILS_C: SubRoutine $ Write SYS$OUTPUT "Extracting UTILS.C..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile UTILS.C $ WO "/************************************************************************" $ WO " * UTILS.C *" $ WO " * Contains code for various utility functions for the KILLUSER *" $ WO " * utility. *" $ WO " * *" $ WO " * 27-MAR-2000 RDJ Program Creation. *" $ WO " ************************************************************************/" $ WO "" $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include " $ WO "#include ""lib$routines.h""" $ WO "#include ""killuser.h""" $ WO "#include ""message.h""" $ WO "#include ""cli.h""" $ WO "#include ""utils.h""" $ WO "" $ WO "" $ WO "/************************************************************************" $ WO " * parse: parse command line for arguments. *" $ WO " ************************************************************************/" $ WO "void parse(option)" $ WO "struct option_struct *option; /* cli options structure */" $ WO "{" $ WO " boolean version; /* was /VERSION specified? */" $ WO " boolean list_modes; /* was /MODE specified? */" $ WO " boolean list_nodes; /* was /NODE specified? */" $ WO " node *nodeptr,*newnode; /* nodename linked list */" $ WO " char tmp[256]; /* temporary string */" $ WO "" $ WO " cli_parse_command_line (""KILLUSER"",&KILLUSER_CLD_TABLE);" $ WO "" $ WO " /* if /VERSION was specified, display version and exit */" $ WO " cli_check_qualifier (""VERSION"",&version);" $ WO " if (version) fatal(KILLUSER$VERSION,VERSION);" $ WO "" $ WO " /* get any /MODE= values */" $ WO " cli_check_qualifier(""MODE"",&list_modes);" $ WO " if (list_modes) { /* /MODE specified, get values.. */" $ WO " option->interactive = false;" $ WO " option->batch = false;" $ WO " option->detached = false;" $ WO " option->network = false;" $ WO " cli_check_qualifier(""MODE.ALL"",&list_modes);" $ WO " if (list_modes) { /* ALL modes */" $ WO " option->interactive = true;" $ WO " option->batch = true;" $ WO " option->detached = true;" $ WO " option->network = true;" $ WO " } else { /* specific modes listed */" $ WO " cli_check_qualifier(""MODE.INTERACTIVE"",&(option->interactive));" $ WO " cli_check_qualifier(""MODE.BATCH"",&(option->batch));" $ WO " cli_check_qualifier(""MODE.DETACHED"",&(option->detached));" $ WO " cli_check_qualifier(""MODE.OTHER"",&(option->detached));" $ WO " cli_check_qualifier(""MODE.NETWORK"",&(option->network));" $ WO " }" $ WO " } else { /* /MODE not specified; Just use interactive */" $ WO " option->interactive = true;" $ WO " option->batch = false;" $ WO " option->detached = false;" $ WO " option->network = false;" $ WO " }" $ WO "" $ WO " /* get username parameter and set up descriptor */" $ WO " cli_get_value(""P1"",tmp);" $ WO " strncpy(option->username,tmp,12);" $ WO " option->username_desc.dsc$a_pointer = (char *) option->username;" $ WO " option->username_desc.dsc$w_length = strlen(option->username);" $ WO " option->username_desc.dsc$b_dtype = DSC$K_DTYPE_T;" $ WO " option->username_desc.dsc$b_class = DSC$K_CLASS_S;" $ WO "" $ WO " /* check if specific nodes were specified with /NODE */" $ WO " option->nodelist = NULL;" $ WO " cli_check_qualifier(""NODE"",&list_nodes);" $ WO " if (list_nodes) { /* get list of nodenames */" $ WO " cli_get_value(""NODE"",&tmp);" $ WO " while(tmp[0] != ''SQ'\0''SQ') {" $ WO " if ((newnode = (node *) malloc (sizeof(node))) == NULL)" $ WO " fatal(KILLUSER$MEMORY,0);" $ WO " newnode->next = NULL;" $ WO " strcpy(newnode->nodename,tmp);" $ WO " newnode->nodename_desc.dsc$a_pointer = (char *) newnode->nodename;" $ WO " newnode->nodename_desc.dsc$w_length = strlen(newnode->nodename);" $ WO " newnode->nodename_desc.dsc$b_dtype = DSC$K_DTYPE_T;" $ WO " newnode->nodename_desc.dsc$b_class = DSC$K_CLASS_S;" $ WO " if (option->nodelist == NULL) {" $ WO " option->nodelist = newnode; " $ WO " nodeptr = newnode;" $ WO " } else {" $ WO " nodeptr->next = newnode;" $ WO " nodeptr = newnode;" $ WO " }" $ WO " cli_get_value(""NODE"",&tmp);" $ WO " }" $ WO " }" $ WO "}" $ WO "" $ WO "" $ WO "" $ WO "/************************************************************************" $ WO " * fatal: signal an error condition. *" $ WO " ************************************************************************/" $ WO "void fatal (error_type, string)" $ WO "unsigned long error_type;" $ WO "char *string;" $ WO "{" $ WO " struct dsc$descriptor string_desc;" $ WO "" $ WO " string_desc.dsc$w_length = strlen(string);" $ WO " string_desc.dsc$b_dtype = DSC$K_DTYPE_T;" $ WO " string_desc.dsc$b_class = DSC$K_CLASS_S;" $ WO " string_desc.dsc$a_pointer = string;" $ WO " if (strlen (string) > 0)" $ WO " lib$signal (error_type,1,&string_desc);" $ WO " else" $ WO " lib$signal (error_type);" $ WO " exit (1);" $ WO "}" $ WO "" $ WO "/************************************************************************" $ WO " * pscan_setup: set up process scan *" $ WO " * since only one process mode may be specified, do not indicate *" $ WO " * any specific mode in the pscan call. modes are checked later, *" $ WO " * before the process is set to be deleted. *" $ WO " ************************************************************************/" $ WO "unsigned long pscan_setup(pctx,option)" $ WO "unsigned long *pctx; /* process scan context */" $ WO "struct option_struct *option; /* cli options */" $ WO "{" $ WO " unsigned long status; /* status of system calls */" $ WO " int itmptr = 0; /* keep track of item list */" $ WO " node *nodeptr; /* temp. node pointer */" $ WO " long all_nodes = 0;" $ WO "" $ WO " item_list_3 scan_itmlst[] = { /* item list for pscan call */" $ WO " {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, /* to be filled in below */" $ WO " {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}," $ WO " {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}," $ WO " {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}};" $ WO "" $ WO " /* specify username for pscan call */" $ WO " scan_itmlst[0].buffer_length = strlen(option->username);" $ WO " scan_itmlst[0].item_code = PSCAN$_USERNAME;" $ WO " scan_itmlst[0].buffer_address = (long) &(option->username);" $ WO "" $ WO " /* specify node names for pscan call */" $ WO " if (option->nodelist == NULL) { /* all nodes */" $ WO " scan_itmlst[++itmptr].buffer_length = 0;" $ WO " scan_itmlst[itmptr].item_code = PSCAN$_NODE_CSID;" $ WO " scan_itmlst[itmptr].buffer_address = (long) &all_nodes;" $ WO " scan_itmlst[itmptr].return_length_address = PSCAN$M_NEQ;" $ WO " } else { /* specify node(s) */" $ WO " nodeptr = option->nodelist;" $ WO " while (nodeptr != NULL) {" $ WO " scan_itmlst[++itmptr].buffer_length = strlen(nodeptr->nodename);" $ WO " scan_itmlst[itmptr].item_code = PSCAN$_NODENAME;" $ WO " scan_itmlst[itmptr].buffer_address = (long) &(nodeptr->nodename);" $ WO " nodeptr = nodeptr->next;" $ WO " }" $ WO " }" $ WO " return(sys$process_scan(pctx,&scan_itmlst));" $ WO "}" $ WO "" $ WO "" $ WO "/************************************************************************" $ WO " * mode_match: check if a process mode matches modes in options. *" $ WO " * this function is necessary because sys$process_scan will only *" $ WO " * accept one mode as input. KILLUSER allows specification of *" $ WO " * multiple modes. function compares mode of given process against *" $ WO " * command line options. *" $ WO " ************************************************************************/" $ WO "int mode_match(proc,option)" $ WO "process *proc; /* process to check mode of */" $ WO "struct option_struct *option; /* command line options */" $ WO "{" $ WO " if (option->interactive && (proc->mode == JPI$K_INTERACTIVE)) return(1);" $ WO " if (option->batch && (proc->mode == JPI$K_BATCH)) return(1);" $ WO " if (option->network && (proc->mode == JPI$K_NETWORK)) return(1);" $ WO " if (option->detached && (proc->mode == JPI$K_OTHER)) return(1);" $ WO " return(0);" $ WO "}" $ WO "" $ WO "" $ WO "/************************************************************************" $ WO " * kill_process: issue a $delprc on the specified process. *" $ WO " ************************************************************************/" $ WO "unsigned long kill_process(proc)" $ WO "process *proc; /* process to kill */" $ WO "{" $ WO " printf(""killing pid: %08X, user %s on node %s, process %s\n""," $ WO " proc->pid,proc->username,proc->node,proc->pname);" $ WO " return(sys$delprc(&(proc->pid),0));" $ WO "}" $ WO "" $ WO "" $ WO "/************************************************************************" $ WO " * get_next_process: get the next matching process from the system. *" $ WO " ************************************************************************/" $ WO "process *get_next_process(pctx)" $ WO "long *pctx; /* process scan context */" $ WO "{" $ WO " static process proc; /* process structure */" $ WO " unsigned short pname_length, /* length of strings returned */" $ WO " node_length, /* from $getjpi */" $ WO " username_length;" $ WO " struct { /* iosb for $getjpi call */" $ WO " unsigned long quad1;" $ WO " unsigned long quad2;" $ WO " } iosb;" $ WO " item_list_3 jpi_itmlst[] = { /* item list for $getjpi call */" $ WO " {15,JPI$_PRCNAM,(long) &proc.pname,(long) &pname_length}," $ WO " {4,JPI$_PID,(long) &proc.pid,0}," $ WO " {6,JPI$_NODENAME,(long) &proc.node,(long) &node_length}," $ WO " {4,JPI$_MODE,(long) &proc.mode,0}," $ WO " {12,JPI$_USERNAME,(long) &proc.username,(long) &username_length}," $ WO " {0,0,0,0}};" $ WO " unsigned long status; /* return status of $getjpi */" $ WO "" $ WO " if ((status = sys$getjpiw(0,pctx,0,&jpi_itmlst,&iosb,0,0)) != SS$_NORMAL) {" $ WO " if (status == SS$_NOMOREPROC) return NULL;" $ WO "#ifdef __debug" $ WO " printf (""get_next_process: status returned from getjpiw is %d\n"", status);" $ WO " printf ("" iosb is %d | %d\n"", iosb.quad1, iosb.quad2);" $ WO " printf ("" proc.pname is [%s]\n"", proc.pname);" $ WO " printf ("" proc.username is [%s]\n"", proc.username);" $ WO "#endif" $ WO " lib$signal(status);" $ WO " return NULL; " $ WO " }" $ WO " proc.pname[pname_length] = ''SQ'\0''SQ';" $ WO " proc.node[node_length] = ''SQ'\0''SQ';" $ WO " proc.username[username_length] = ''SQ'\0''SQ';" $ WO " while (proc.username[--username_length] == ''SQ' ''SQ') /* get rid of trailing blanks */" $ WO " proc.username[username_length] = ''SQ'\0''SQ';" $ WO " return &proc;" $ WO "}" $ WO "" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_UTILS_C $! $ Extract_UTILS_H: SubRoutine $ Write SYS$OUTPUT "Extracting UTILS.H..." $ WO := Write OutFile $ SQ = "'" $ SQ2 = SQ + SQ $ Close/NoLog OutFile $ Open/Write/Share OutFile UTILS.H $ WO "" $ WO "" $ WO "void parse();" $ WO "void fatal();" $ WO "unsigned long pscan_setup();" $ WO "process *get_next_process();" $ WO "unsigned long kill_process();" $ WO "int mode_match();" $ WO "" $ WO " $ Close/NoLog OutFile $ Exit $ EndSubRoutine ! Extract_UTILS_H