#! /usr/bin/perl

use strict;
use Getopt::Long;

sub usage;

my $opt_show;
my $opt_stop;

GetOptions(
  'show'           => \$opt_show,
  'stop'           => \$opt_stop,
  'help'           => sub { usage 0 },
) || usage 1;

my $service = shift;

usage 2 unless defined $service;

my $service_file;
$service_file = "/usr/lib/systemd/system/$service.service" if -f "/usr/lib/systemd/system/$service.service";
$service_file = "/etc/systemd/system/$service.service" if -f "/etc/systemd/system/$service.service";

die "$service: no such service\n" if !defined $service_file;

my @todo;

open my $f, $service_file;
while (<$f>) {
  if(/^\[Service\]/ ... /^\[/) {
    chomp;
    push @todo, $_ if !/^\[/ && !/^\s*$/;
  }
}
close $f;

my $cmd;
my $type = 'simple';

for (@todo) { $type = $1 if /^Type=(.+)/ }

my $suffix = " &" if $type !~ /^(forking|oneshot)$/;

for (@todo) { $cmd .= ". $_\n" if s/^EnvironmentFile=[\-@]*// }
for (@todo) { $cmd .= "export $1\n" if /^Environment=(.+)/ }
if($opt_stop) {
  my $has_stop;
  for (@todo) { $cmd .= "$_\n", $has_stop = 1 if s/^ExecStop=[\-@]*// }
  for (@todo) { $cmd .= "$_\n" if s/^ExecStopPost=[\-@]*// }
  if(!$has_stop) {
    undef $cmd;
    for (@todo) { $cmd .= "killproc $1\n" if /^ExecStart=[\-@]*(\S+)/ }
    if($cmd) {
      $cmd .= "sleep 1\n";
      for (@todo) { $cmd .= "killproc -KILL $1\n" if /^ExecStart=[\-@]*(\S+)/ }
    }
  }
  $cmd .= "exit 0\n";
}
else {
  for (@todo) { $cmd .= "$_\n" if s/^ExecStartPre=[\-@]*// }
  for (@todo) { $cmd .= "$_$suffix\n" if s/^ExecStart=[\-@]*// }
  for (@todo) { $cmd .= "$_\n" if s/^ExecStartPost=[\-@]*// }
}

if($opt_show) {
  print $cmd;
}
else {
  if(open $f, ">>/var/log/service_start.log") {
    print $f "=== $service " . ($opt_stop ? "stop" : "start") . " ===\n";
    close $f;
  }
  open $f, "| /bin/sh >>/var/log/service_start.log 2>&1";
  print $f $cmd;
  exit $? >> 8 if !close $f;
}


# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# usage($exit_code)
#
# Print help text and exit.
#
sub usage
{
  print <<"= = = = = = = =";
Usage: service_start [OPTIONS] SERVICE
Start or stop systemd service SERVICE.

Note: this is a simplified tool that may or may not work for a particular
service.

Options:
  --stop           Stop service.
  --show           Don't start/stop service but show necessary commands.
  --help           Write this help text.

= = = = = = = =

  exit shift;
}

