1 | #! /bin/env perl |
---|
2 | |
---|
3 | use strict; |
---|
4 | use warnings; |
---|
5 | use Sophie::Bot; |
---|
6 | use Getopt::Long; |
---|
7 | use Pod::Usage; |
---|
8 | use Config::General; |
---|
9 | use File::Temp; |
---|
10 | |
---|
11 | GetOptions( |
---|
12 | 'c=s' => \my $configfile, |
---|
13 | 'u=s' => \my $url, |
---|
14 | 'l=s' => \my $login, |
---|
15 | 'p=s' => \my $pass, |
---|
16 | 't=s' => \my $type, |
---|
17 | 'd=s' => \my @options, |
---|
18 | 'proxy' => \my $proxy, |
---|
19 | 'daemon' => \my $daemon, |
---|
20 | 'runas=s' => \my $runas, |
---|
21 | 'pidfile=s' => \my $pidfile, |
---|
22 | |
---|
23 | # Command option: |
---|
24 | 'set-password=s' => \my $password, |
---|
25 | 'edit-var=s' => \my $data, |
---|
26 | ) or pod2usage; |
---|
27 | |
---|
28 | my %options; |
---|
29 | foreach (@options) { |
---|
30 | m/([^=]+)\s*=\s*(.*)/ or next; |
---|
31 | $options{$1} = $2; |
---|
32 | } |
---|
33 | |
---|
34 | $configfile ||= "/etc/sophie/sophie-bot.conf"; |
---|
35 | |
---|
36 | if (my $conf = Config::General->new($configfile)) { |
---|
37 | my %config = $conf->getall; |
---|
38 | $url ||= $config{url}; |
---|
39 | $login ||= $config{login}; |
---|
40 | $pass ||= $config{pass}; |
---|
41 | $daemon ||= $config{daemon}; |
---|
42 | $proxy ||= $config{proxy}; |
---|
43 | $runas ||= $config{runas}; |
---|
44 | $pidfile ||= $config{pidfile}; |
---|
45 | $type ||= $config{type}; |
---|
46 | } |
---|
47 | |
---|
48 | my $sc = Sophie::Bot->new( |
---|
49 | server => $url, |
---|
50 | login => $login, |
---|
51 | password => $pass, |
---|
52 | type => $type || 'Term', |
---|
53 | proxy => $proxy, |
---|
54 | ) or die "Cannot get sophie object\n"; |
---|
55 | |
---|
56 | if ($password) { |
---|
57 | my $res = $sc->send_request('user.set_password', $password); |
---|
58 | if (ref $res && !$res->is_fault) { |
---|
59 | print $res->value . "\n"; |
---|
60 | exit(0); |
---|
61 | } else { |
---|
62 | print( (ref $res ? $res->string : $res) . "\n"); |
---|
63 | exit(1); |
---|
64 | } |
---|
65 | } elsif ($data) { |
---|
66 | my $res = $sc->send_request('user.dumpdata', $data); |
---|
67 | if (ref $res && !$res->is_fault) { |
---|
68 | my $tmp = File::Temp->new(); |
---|
69 | print $tmp $res->value . "\n"; |
---|
70 | close($tmp); |
---|
71 | system($ENV{EDITOR} || 'vi', $tmp->filename); |
---|
72 | if (open(my $fh, '<', $tmp->filename)) { |
---|
73 | my $string = join('', <$fh>); |
---|
74 | close($fh); |
---|
75 | unlink($tmp->filename); |
---|
76 | my $res2 = $sc->send_request('user.loaddata', $data, $string); |
---|
77 | if (ref $res2 && !$res2->is_fault) { |
---|
78 | print $res2->value . "\n"; |
---|
79 | exit(0); |
---|
80 | } else { |
---|
81 | print( (ref $res2 ? $res2->string : $res2) . "\n"); |
---|
82 | exit(1); |
---|
83 | } |
---|
84 | } |
---|
85 | } else { |
---|
86 | print( (ref $res ? $res->string : $res) . "\n"); |
---|
87 | exit(1); |
---|
88 | } |
---|
89 | } |
---|
90 | |
---|
91 | if ($daemon) { |
---|
92 | my $pid = fork(); |
---|
93 | |
---|
94 | if (defined($pid)) { |
---|
95 | if ($pid) { |
---|
96 | # father, exiting; |
---|
97 | exit(0); |
---|
98 | } else { |
---|
99 | # child |
---|
100 | } |
---|
101 | } |
---|
102 | } |
---|
103 | |
---|
104 | if ($pidfile) { |
---|
105 | if (open(my $handle, '>', $pidfile)) { |
---|
106 | print $handle $$ . "\n"; |
---|
107 | close($handle); |
---|
108 | } else { |
---|
109 | } |
---|
110 | } |
---|
111 | |
---|
112 | if ($runas) { |
---|
113 | my ($login,$pass,$uid,$gid) = $runas =~ /^\d/ |
---|
114 | ? getpwuid($runas) |
---|
115 | : getpwnam($runas); |
---|
116 | |
---|
117 | $> = $uid; $) = $gid; |
---|
118 | if ($> ne $uid) { |
---|
119 | die "Cannot change to user $runas\n"; |
---|
120 | } |
---|
121 | } |
---|
122 | |
---|
123 | $sc->run; |
---|
124 | |
---|