$ basic superuser $ link superuser $ set command superuser $ library/insert sys$help:helplib.hlb superuser define verb superuser image dev$disk:[russ.super]superuser qualifier username value nonnegatable qualifier process value nonnegatable qualifier image value (type=$file) nonnegatable qualifier select value (type=process_options) nonnegatable qualifier output value (type=$file, default="SUPERUSER.LIS") nonnegatable qualifier stop nonnegatable qualifier force_exit nonnegatable qualifier confirm default disallow stop and force_exit disallow stop and output disallow force_exit and output disallow (confirm or neg confirm) and not (stop or force_exit) define type process_options keyword other keyword network keyword batch keyword interactive, default keyword detached keyword local keyword dialup keyword remote keyword all program superuser ! + ! author : Russell Salerno ! ! module name : superuser ! ! description : A program that works like $ SHOW USERS ! but shows you the image name and base ! priority. It will also let you specify ! users by the image they are running, and ! allow you to stop a process or terminate ! the image. ! ! - option type = explicit on error goto error_handler %include "$jpidef" %from %library "sys$library:basic$starlet.tlb" external long function sys$getjpiw & , sys$fao & , sys$delprc & , sys$forcex & , lib$trim_filespec & , lib$date_time & , cli$get_value & , cli$present & , sor$begin_sort & , sor$release_rec & , sor$sort_merge & , sor$return_rec external long constant ss$_normal & , ss$_badparam & , ss$_accvio & , ss$_ivlognam & , ss$_nomoreproc & , ss$_nonexpr & , ss$_nopriv & , ss$_suspended & , ss$_endoffile external word constant dsc$k_dtype_t record item word buff_len word item_code long buff_addr long ret_addr end record map (itms) item item_list(10%) map (iostat) string iosb = 8% map (iostat) long iosb_1 & , iosb_2 map (prt) string p_user = 12% & , fill = 1% & , p_proc = 15% & , fill = 1% & , p_pid = 8% & , fill = 1% & , p_prib = 3% & , fill = 1% & , p_term = 7% & , fill = 1% & , p_image = 29% & , fill = 1% & , p_xtra = 1% map (prt) string p_all = 79% map (str) string timestamp = 23% & , out_str = 80% map (srtrec) string user_name = 12% & , process_name = 15% & , term_name = 7% & , image_name = 80% & , long pid & , prib map (srtrec) string srt_all = 122% declare byte username_choice & , image_choice & , output_choice & , process_choice & , select_choice & , stop_choice & , exit_choice & , confirm_choice declare word key_info(4%) declare long sys_status & , pidadr & , proc_mode & , jobtype & , item_list_addr & , iosb_addr & , ret_len(10) & , username_choice_str_len & , image_choice_str_len & , output_choice_str_len & , process_choice_str_len & , select_choice_str_len & , record_count & , record_length & , out_chan declare string username_choice_str & , image_choice_str & , output_choice_str & , process_choice_str & , select_choice_str & , answer & , title_str1 & , title_str2 & , out_device declare byte constant true = -1% & , false = 0% & , out_file = 1% ! Main program block gosub get_cli_info gosub initialize_getjpi gosub get_user_info gosub process_user_info goto exit_program get_cli_info: ! Get qualifiers and values chosen by the user username_choice = true if (cli$get_value('USERNAME', username_choice_str, username_choice_str_len) and X"00000001"L) = 1% image_choice = true if (cli$get_value('IMAGE', image_choice_str, image_choice_str_len) and X"00000001"L) = 1% output_choice = true if (cli$get_value('OUTPUT', output_choice_str, output_choice_str_len) and X"00000001"L) = 1% process_choice = true if (cli$get_value('PROCESS', process_choice_str, process_choice_str_len) and X"00000001"L) = 1% stop_choice = true if (cli$present('STOP') and X"00000001"L) = 1% exit_choice = true if (cli$present('FORCE_EXIT') and X"00000001"L) = 1% confirm_choice = true if (cli$present('CONFIRM') and X"00000001"L) = 1% call cli$get_value('SELECT', select_choice_str, select_choice_str_len) sys_status = lib$date_time(timestamp) ! If /OUTPUT was chosen, our output device is the filename. ! Otherwise, it is SYS$OUTPUT if output_choice then out_device = output_choice_str else out_device = "sys$output" end if call lib$get_lun(out_chan) open out_device for output as file #out_chan nomargin #out_chan return initialize_getjpi: ! set up item list item_list_addr = loc(item_list(0)::buff_len) iosb_addr = loc(iosb_1) pidadr = -"1"l item_list(0)::buff_len = len(image_name) item_list(0)::item_code = jpi$_imagname item_list(0)::buff_addr = loc(image_name) item_list(0)::ret_addr = loc(ret_len(0)) item_list(1)::buff_len = 4% item_list(1)::item_code = jpi$_pid item_list(1)::buff_addr = loc(pid) item_list(1)::ret_addr = loc(ret_len(1)) item_list(2)::buff_len = len(process_name) item_list(2)::item_code = jpi$_prcnam item_list(2)::buff_addr = loc(process_name) item_list(2)::ret_addr = loc(ret_len(2)) item_list(3)::buff_len = len(user_name) item_list(3)::item_code = jpi$_username item_list(3)::buff_addr = loc(user_name) item_list(3)::ret_addr = loc(ret_len(3)) item_list(4)::buff_len = len(term_name) item_list(4)::item_code = jpi$_terminal item_list(4)::buff_addr = loc(term_name) item_list(4)::ret_addr = loc(ret_len(4)) item_list(5)::buff_len = 4% item_list(5)::item_code = jpi$_mode item_list(5)::buff_addr = loc(proc_mode) item_list(5)::ret_addr = loc(ret_len(5)) item_list(6)::buff_len = 4% item_list(6)::item_code = jpi$_prib item_list(6)::buff_addr = loc(prib) item_list(6)::ret_addr = loc(ret_len(6)) item_list(7)::item_code,item_list(7)::buff_len = 0 ! set up report titles select_choice = true select left$(select_choice_str, 1%) case "O" title_str1 = "Other Processes" title_str2 = "other processes" jobtype = jpi$k_other case "N" title_str1 = "Network Users" title_str2 = "network users" jobtype = jpi$k_network case "B" title_str1 = "Batch Processes" title_str2 = "batch processes" jobtype = jpi$k_batch case "D" title_str1 = "Detached Processes" title_str2 = "detached processes" jobtype = jpi$k_detached case "L" title_str1 = "Local Processes" title_str2 = "local processes" jobtype = jpi$k_local case "D" title_str1 = "Dialup Users" title_str2 = "dialup users" jobtype = jpi$k_dialup case "R" title_str1 = "Remote Users" title_str2 = "remote users" jobtype = jpi$k_dialup case "A" title_str1 = "Processes" title_str2 = "processes" select_choice = false case else title_str1 = "Interactive Users" title_str2 = "interactive users" jobtype = jpi$k_interactive end select return get_user_info: ! call getjpi, and see which processes meet our criteria while sys_status <> ss$_nomoreproc sys_status = sys$getjpiw ( ! efn ! & , pidadr by ref ! pid wildcard ! & , ! proc name ! & , item_list(0) by ref ! addr of i.l. ! & , iosb by ref ! iosb ! & , ! astadr ! & , ! astprm ! ) select sys_status case ss$_normal, ss$_suspended if ((not select_choice) or (proc_mode = jobtype)) & and & ((not username_choice) or (edit$(user_name,4%) = username_choice_str)) & and & ((not process_choice) or (edit$(process_name,4%) = process_choice_str)) & and & ((not image_choice) or (pos(edit$(image_name,4%), image_choice_str, 1%) <> 0%)) then gosub send_to_sort end if case ss$_nomoreproc, ss$_nopriv case else call lib$stop(sys_status by value) end select next return send_to_sort: ! init sort first time through gosub initialize_sort if record_count = 0% ! send record to the sort utility sys_status = sor$release_rec(srt_all) call lib$stop(sys_status by value) if sys_status <> ss$_normal record_count = record_count + 1% return initialize_sort: ! set up sort parameters... record_length = len(srt_all) key_info(0%) = 1% ! 1 key key_info(1%) = dsc$k_dtype_t ! key type is 'string' key_info(2%) = 0% ! ascending order key_info(3%) = 0% ! start position key_info(4%) = 12% ! key length ! ...and initialize sort utility sys_status = sor$begin_sort(key_info(0%), record_length) call lib$stop(sys_status by value) if sys_status <> ss$_normal return process_user_info: ! If we found any matching processes, lets ! sort them and take approprite action: if record_count = 0% then print #out_chan print #out_chan; "No matching processes found." else sys_status = sor$sort_merge() p_all = " " if stop_choice or exit_choice then gosub stop_or_forcex else gosub show_users end if end if return stop_or_forcex: set no prompt ! we don't want BASIC's default prompt record_count = 0% sys_status = sor$return_rec(srt_all) while sys_status <> ss$_endoffile gosub format_output if confirm_choice then if stop_choice then print #out_chan; "STOP PROCESS " + edit$(p_all, 144%) + " ? [N]: "; \ input answer else print #out_chan; "FORCE IMAGE EXIT ON PROCESS " + edit$(p_all, 144%) + " ? [N]: "; \ input answer end if answer = edit$(answer, 32%) select answer case "A" confirm_choice = false ! Process all the rest w/o asking case "Q" sys_status = ss$_endoffile ! Flag the exit condition iterate end select end if if (not confirm_choice) or edit$(answer, 32%) = "Y" then if stop_choice then sys_status = sys$delprc(pid by ref,) print #out_chan; "PROCESS " + edit$(p_all, 144%) + " STOPPED" else sys_status = sys$forcex(pid,,) print #out_chan; "IMAGE " + edit$(p_image, 128%) + " TERMINATED " end if record_count = record_count + 1% end if sys_status = sor$return_rec(srt_all) next if record_count = 1% then print #out_chan if stop_choice then print #out_chan; "Total of 1 process stopped." else print #out_chan; "Total of 1 image terminated." end if else print #out_chan if stop_choice then print #out_chan; "Total of " + num1$(record_count) + " processes stopped." else print #out_chan; "Total of " + num1$(record_count) + " images terminated." end if end if return show_users: print #out_chan; edit$(format$("VAX/VMS " + title_str1, "'" + string$(79%, ascii("C"))), 128%) print #out_chan; edit$(format$(timestamp, "'" + string$(79%, ascii("C"))), 128%) print #out_chan; edit$(format$("Total number of " + title_str2 + " = " + num1$(record_count), "'" + string$(79%, ascii("C"))), 128%) print #out_chan print #out_chan; "Username Process Name PID BPR Term Image" sys_status = sor$return_rec(srt_all) while sys_status <> ss$_endoffile gosub format_output print #out_chan; p_all sys_status = sor$return_rec(srt_all) next sys_status = sys$fao("Total of !SL user!%S.",,out_str, record_count by value) print #out_chan print #out_chan; edit$(out_str, 132%) return format_output: p_user = edit$(user_name, 4%) p_proc = edit$(process_name, 4%) p_prib = format$(prib, "###") p_term = edit$(term_name, 4%) sys_status = sys$fao("!XL",,p_pid,pid by value) sys_status = lib$trim_filespec(image_name,p_image,"29"W) return error_handler: print #out_chan; err,ert$(err);" sys_status:";sys_status resume exit_program exit_program: close #out_chan end program 1 SUPERUSER Displays the terminal name, username, process name, PID, image and base priority of either specific users or all users on the system. Optionally will terminate the selected processes or force an image exit to the DCL prompt. Format: SUPERUSER [qualifier(s)] 2 /FORCE_EXIT Directs that an $EXIT service call be issued to the displayed process, forcing its currently running image to terminate. 3 /CONFIRM /CONFIRM [default] /NOCONFIRM Controls whether a request is issued before each force exit operation to confirm that the operation should be performed on that process. When the system issues the prompt, you can issue any of the following responses: Y - yes N - no Q - quit A - all 2 /IMAGE /IMAGE=file-spec Specifies the image name search string. If a process is currently executing an image whose file-spec contains this string, it will be displayed. 2 /OUTPUT /OUTPUT[=file-spec] Specifies the file to which the display is written; by default, the display is written to the current SYS$OUTPUT device. If no file-spec is specified, output will be written to SUPERUSER.LIS. 3 Examples $ SUPERUSER /OUTPUT=MYFILE.TXT Writes the output of SUPERUSER to the file MYFILE.TXT 2 /PROCESS /PROCESS=string Specifies the process name the users whose process information is to be displayed. If the process name contains any lowercase letters or or nonalphanumeric characters (including spaces) you must enclose it in quotation marks. 2 /SELECT /SELECT=process-type Defines process type of the users whose process information is to be displayed. The following keywords are used to specify the process type: INTERACTIVE (default) BATCH DETACHED NETWORK LOCAL DIALUP REMOTE OTHER ALL 2 /STOP Directs that each displayed process be terminated. 3 /CONFIRM /CONFIRM [default] /NOCONFIRM Controls whether a request is issued before each stop process operation to confirm that the operation should be performed on that process. When the system issues the prompt, you can issue any of the following responses: Y - yes N - no Q - quit A - all 2 /USERNAME /USERNAME=username Specifies the username of the users whose process information is to be displayed.