#!/usr/bin/perl use warnings; use strict; my($app_svnid) = '$HeadURL$ $LastChangedRevision$'; ## no critic (RequireInterpolationOfMetachars) use lib substr(`ade-config ade_share_prefix`,0,-1) . '/include'; ## no critic (ProhibitBacktickOperators) use ADE; use lib substr(`js-config js_share_prefix`,0,-1) . '/include'; ## no critic (ProhibitBacktickOperators) use JS; use experimental 'smartmatch'; use IPC::SysV qw(IPC_PRIVATE IPC_RMID IPC_CREAT S_IRUSR S_IWUSR); use Storable; my(%jsm_defined_errors) = ( 'jsm_err_misc' => { fmt => '%s' }, ); # Options # Other globals sub jsm { my($errstack_ref) = @_; my($rc, $jsd_pid, $running_flag, $lock_file, %message_hash, %reply_hash, $server_name, $lock_handle); # Set ADE options ADE::register_error_types(\%jsm_defined_errors); # Defaults for options # Register options if (($rc=ADE::register_options($errstack_ref, '', 'progname:s', 'main::jsm_opt_handler_%s')) != $ADE::OK) { return($rc); } # Register handler functions if (($rc=ADE::set_callbacks($errstack_ref, \&jsm_usage_help, \&jsm_version, \&jsm_paths)) != $ADE::OK) { return($rc); } # Process options if (($rc=ADE::process_options($errstack_ref)) != $ADE::OK) { return($rc); } # Process arguments # Sanity checks and derivations if (($rc=JS::get_server_name($errstack_ref, \$server_name)) != $ADE::OK) { return($rc); } # Check jsd running. $lock_file = "/tmp/jsd-$server_name.lock"; if (not open $lock_handle, '<', $lock_file) { ADE::error($errstack_ref, 'jsm_err_misc', 'jsd: not running (hint: did you start it? is JS_NAME set correctly?)'); return($ADE::FAIL); } $jsd_pid = <$lock_handle>; close $lock_handle; chomp $jsd_pid; if ($jsd_pid !~ /^[1-9][0-9]*$/ or ! -d "/proc/$jsd_pid") { ADE::error($errstack_ref, 'jsm_err_misc', 'jsd: not running (hint: did you start it? is JS_NAME set correctly?)'); return($ADE::FAIL); } # Guts if (($rc=list_to_hash($errstack_ref, \@ARGV, \%message_hash)) != $ADE::OK) { return($rc); } ## Error messages from here are to use whatever $PROGNAME is (jss or jsc). #ADE::set_progname($errstack_ref, $ENV{'PROGNAME'}) if $ENV{'PROGNAME'}; if (($rc=JS::send_message_hash_and_read_reply_hash($errstack_ref, $server_name, \%message_hash, \%reply_hash)) != $ADE::OK) { return($rc); } # If the server passed text back then display it. print $reply_hash{'stdout'} if $reply_hash{'stdout'}; print STDERR $reply_hash{'stderr'} if $reply_hash{'stderr'}; ADE::info($errstack_ref, $reply_hash{'info'}) if $reply_hash{'info'}; # If the server raised a client-side error then handle that. if ($reply_hash{'rc'} != $ADE::OK) { # Copy everything on the client error stack to the real error stack. @{$errstack_ref} = @{$reply_hash{'errstack-ref'}}; return($reply_hash{'rc'}); } # Tidy up return ($ADE::OK); } sub jsm_opt_handler_progname { my($errstack_ref, $progname) = @_; return ADE::set_progname($errstack_ref, $progname); } sub jsm_version { my($errstack_ref, $version_text_ref) = @_; return(ADE::extract_version($errstack_ref, $app_svnid, $version_text_ref)); } sub jsm_paths { my($errstack_ref, $pathlist_text_ref) = @_; my($rc); #${$pathlist_text_ref} = ''; return($ADE::OK); } sub jsm_usage_help { my($errstack_ref, $usage_text_short_ref, $usage_text_long_ref) = @_; ${$usage_text_short_ref} = "= [ ... ]\n"; ${$usage_text_long_ref} = undef; return($ADE::OK); } sub list_to_hash { my($errstack_ref, $list_ref, $hash_ref) = @_; my($key, $val); %{$hash_ref} = (); foreach my $item (@{$list_ref}) { if (!(($key,$val) = ($item=~/^([^=]+)=(.*)$/))) { ADE::error($errstack_ref, 'jsm_err_misc', "$item: failed to parse"); return($ADE::FAIL); } ADE::debug($errstack_ref, 10, "list_to_hash: key=$key, val=$val"); ${$hash_ref}{$key} = $val; } return($ADE::OK); } ADE::main(\&jsm);