]> git.proxmox.com Git - pmg-api.git/blame - PMG/Fetchmail.pm
PMG/API2/Domains.pm - remove dead code
[pmg-api.git] / PMG / Fetchmail.pm
CommitLineData
26be105b
DM
1package PMG::Fetchmail;
2
3use strict;
4use warnings;
cde18a76 5use Data::Dumper;
26be105b
DM
6
7use PVE::Tools;
8use PVE::INotify;
9
cde18a76
DM
10use PMG::Config;
11
26be105b
DM
12my $inotify_file_id = 'fetchmailrc';
13my $config_filename = '/etc/pmg/fetchmailrc';
14
cde18a76
DM
15my $set_fetchmail_defaults = sub {
16 my ($item) = @_;
17
18 $item->{protocol} //= 'pop3';
19 $item->{interval} //= 1;
004cc4f3 20 $item->{enable} //= 0;
cde18a76
DM
21
22 if (!$item->{port}) {
23 if ($item->{protocol} eq 'pop3') {
24 if ($item->{ssl}) {
25 $item->{port} = 995;
26 } else {
27 $item->{port} = 110;
28 }
29 } elsif ($item->{protocol} eq 'imap') {
30 if ($item->{ssl}) {
31 $item->{port} = 993;
32 } else {
33 $item->{port} = 143;
34 }
35 } else {
36 die "unknown fetchmail protocol '$item->{protocol}'\n";
37 }
38 }
39
40 return $item;
41};
42
26be105b
DM
43sub read_fetchmail_conf {
44 my ($filename, $fh) = @_;
45
46 my $cfg = {};
47
48 if ($fh) {
49
cde18a76 50 # scan for proxmox marker - skip non proxmox lines
26be105b 51 while (defined(my $line = <$fh>)) {
cde18a76 52 last if $line =~ m/^\#\s+proxmox\s+settings.*$/;
26be105b 53 }
cde18a76
DM
54 # now parse the rest
55
56 my $data = '';
57 my $linenr = 0;
58
59 my $get_next_token = sub {
60
61 do {
62 while ($data =~ /\G('([^']*)'|\S+|)(?:\s|$)/g) {
63 if ($1 ne '') {
cde18a76
DM
64 return wantarray ? ($1, $2) : $1;
65 }
66 }
67 $data = <$fh>;
68 $linenr = $fh->input_line_number();
69 } while (defined($data));
70
71 return undef; # EOF
72 };
73
74 my $get_token_argument = sub {
75 my ($token, $string) = $get_next_token->();
76 die "line $linenr: missing token arguemnt\n" if !$token;
77 return $string // $token;
78 };
79
80 my $finalize_item = sub {
81 my ($item) = @_;
82 $cfg->{$item->{id}} = $item;
83 };
84
85 my $item;
86 while (my ($token, $string) = $get_next_token->()) {
87 last if !defined($token);
88 if ($token eq 'poll' || $token eq 'skip') {
89 $finalize_item->($item) if defined($item);
90 my $id = $get_token_argument->();
91 $item = { id => $id };
004cc4f3 92 $item->{enable} = $token eq 'pass' ? 1 : 0;
cde18a76
DM
93 next;
94 }
95
96 die "line $linenr: unexpected token '$token'\n"
97 if !defined($item);
98
99 if ($token eq 'user') {
100 $item->{user} = $get_token_argument->();
101 } elsif ($token eq 'via') {
102 $item->{server} = $get_token_argument->();
103 } elsif ($token eq 'pass') {
104 $item->{pass} = $get_token_argument->();
105 } elsif ($token eq 'to') {
106 $item->{target} = $get_token_argument->();
107 } elsif ($token eq 'protocol') {
108 $item->{protocol} = $get_token_argument->();
109 } elsif ($token eq 'port') {
110 $item->{port} = $get_token_argument->();
111 } elsif ($token eq 'interval') {
112 $item->{interval} = $get_token_argument->();
113 } elsif ($token eq 'ssl' || $token eq 'keep' ||
114 $token eq 'dropdelivered') {
115 $item->{$token} = 1;
116 } else {
117 die "line $linenr: unexpected token '$token' inside entry '$item->{id}'\n";
118 }
119 }
120 $finalize_item->($item) if defined($item);
26be105b
DM
121 }
122
123 return $cfg;
124}
125
126sub write_fetchmail_conf {
cde18a76
DM
127 my ($filename, $fh, $fmcfg) = @_;
128
129 foreach my $id (keys %$fmcfg) {
130 my $item = $fmcfg->{$id};
131 $item->{id} = $id;
132 $set_fetchmail_defaults->($item);
133 my $options = [ 'dropdelivered' ];
134 push @$options, 'ssl' if $item->{ssl};
135 push @$options, 'keep' if $item->{keep};
136 $item->{options} = join(' ', @$options);
137 }
26be105b
DM
138
139 my $raw = '';
140
cde18a76
DM
141
142 my $pmgcfg = PMG::Config->new();
143 my $vars = $pmgcfg->get_template_vars();
144 $vars->{fetchmail_users} = $fmcfg;
145
146 my $tt = PMG::Config::get_template_toolkit();
147 $tt->process('fetchmailrc.tt', $vars, \$raw) ||
148 die $tt->error() . "\n";
149
150 my (undef, undef, $uid, $gid) = getpwnam('fetchmail');
151 chown($uid, $gid, $fh) if defined($uid) && defined($gid);
152 chmod(0600, $fh);
26be105b
DM
153
154 PVE::Tools::safe_print($filename, $fh, $raw);
155}
156
157PVE::INotify::register_file(
158 $inotify_file_id, $config_filename,
159 \&read_fetchmail_conf,
160 \&write_fetchmail_conf,
161 undef,
162 always_call_parser => 1);
163
26be105b 1641;