Context.pm 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package NIC::Bridge::Context;
  2. use strict;
  3. use warnings;
  4. use subs qw(warn exit);
  5. use Module::Load::Conditional qw(can_load);
  6. use NIC::Tie::PrefixedHandleRedirect;
  7. use NIC::Bridge::NICBase;
  8. our %handlers = (
  9. PROMPT => sub { },
  10. );
  11. sub import {
  12. my $package = shift;
  13. my %arg = @_;
  14. for(keys %arg) {
  15. $handlers{$_} = $arg{$_};
  16. }
  17. }
  18. our $bridge = undef;
  19. our $global_ret = undef;
  20. our $errored_out = undef;
  21. sub NIC {
  22. return $bridge;
  23. }
  24. sub warn(@) {
  25. print STDERR "[".$bridge->{FOR}->name."/warning] ",@_,$/;
  26. }
  27. sub error(@) {
  28. print STDERR "[".$bridge->{FOR}->name."/error] ",@_,$/;
  29. $errored_out = 1;
  30. die;
  31. }
  32. sub exit {
  33. $global_ret = shift;
  34. die;
  35. }
  36. sub prompt {
  37. __PACKAGE__->_prompt($bridge->{FOR}, undef, @_);
  38. }
  39. sub _prompt {
  40. my $self = shift;
  41. my $nic = shift;
  42. my $n = scalar @_;
  43. my $opts = $_[$n-1];
  44. if(ref $opts eq "HASH") {
  45. $n--;
  46. } else {
  47. $opts = {};
  48. }
  49. my $variable;
  50. $variable = shift unless $n == 1;
  51. my $promptstring = shift;
  52. $handlers{PROMPT}->($nic, $variable, $promptstring, $opts->{default});
  53. }
  54. sub _wrap {
  55. my $self = shift;
  56. my @r = map {
  57. my $wrap = $_;
  58. my $_wrapType = $wrap ? (ref $wrap) : "_Undefined";
  59. if(!$_wrapType || (ref($wrap) && $wrap->isa("NIC::Bridge::_BridgedObject"))) {
  60. return $wrap;
  61. } else {
  62. $_wrapType =~ s/.*:://;
  63. my $wrappingClass = "NIC::Bridge::$_wrapType";
  64. can_load(modules=>{$wrappingClass=>undef}, verbose=>0) or return undef;
  65. my $wrapper = $wrappingClass->new($self, $wrap);
  66. return $wrapper;
  67. }
  68. } (@_);
  69. return @r if wantarray;
  70. return (@r > 0 ? $r[0] : undef);
  71. }
  72. sub _unwrap {
  73. my $self = shift;
  74. my @r = map { (ref($_) && $_->isa("NIC::Bridge::_BridgedObject")) ? $_->{FOR} : $_; } (@_);
  75. return @r if wantarray;
  76. return (@r > 0 ? $r[0] : undef);
  77. }
  78. sub _execute {
  79. my $self = shift;
  80. my $nic = shift;
  81. my $script = shift;
  82. my $ret = 1;
  83. {
  84. local $global_ret;
  85. local $errored_out;
  86. local $bridge = NIC::Bridge::NICBase->new($self, $nic);
  87. local $SIG{__DIE__} = sub { };
  88. tie *OVERRIDE, "NIC::Tie::PrefixedHandleRedirect", *STDERR, $nic->name;
  89. my $stdout = select(*OVERRIDE);
  90. eval("#line 1 ".$nic->name."/control.pl\n".$script);
  91. select($stdout);
  92. if(defined $errored_out) {
  93. $ret = 0;
  94. } elsif(defined $global_ret) {
  95. $ret = $global_ret;
  96. print STDERR "[".$nic->name."/error] Control script exited with status $ret.",$/;
  97. } elsif($@) {
  98. $ret = 0;
  99. print STDERR "[".$nic->name."/error] Control script exited due to an error: $@";
  100. }
  101. }
  102. return $ret;
  103. }
  104. 1;