]> git.proxmox.com Git - pmg-api.git/blame - PMG/Postfix.pm
PMG/Postfix.pm: add command to parse qshape output
[pmg-api.git] / PMG / Postfix.pm
CommitLineData
006417f9
DM
1package PMG::Postfix;
2
3use strict;
4use warnings;
5use Data::Dumper;
6use File::Find;
7
8my $spooldir = "/var/spool/postfix";
9
10my $postfix_rec_get = sub {
11 my ($fh) = @_;
12
13 my $r = getc($fh);
14 return if !defined($r);
15
16 my $l = 0;
17 my $shift = 0;
18
19 while (defined(my $lb = getc($fh))) {
20 my $o = ord($lb);
21 $l |= ($o & 0x7f) << $shift ;
22 last if (($o & 0x80) == 0);
23 $shift += 7;
24 return if ($shift > 7); # XXX: max rec len of 4096
25 }
26
27 my $d = "";
28 return unless ($l == 0 || read($fh, $d, $l) == $l);
29 return ($r, $l, $d);
30};
31
32my $postfix_qenv = sub {
33 my ($filename) = @_;
34
35 my $fh = new IO::File($filename, "r");
36 return undef if !defined($fh);
37
38 my $dlen;
39 my $res = { receivers => [] };
40 while (my ($r, $l, $d) = $postfix_rec_get->($fh)) {
41 #print "test:$r:$l:$d\n";
42 if ($r eq "C") { $dlen = $1 if $d =~ /^\s*(\d+)\s+\d+\s+\d+/; }
43 elsif ($r eq 'T') { $res->{time} = $1 if $d =~ /^\s*(\d+)\s\d+/; }
44 elsif ($r eq 'S') { $res->{sender} = $d; }
45 elsif ($r eq 'R') { push @{$res->{receivers}}, $d; }
46 elsif ($r eq 'N') {
47 if ($d =~ m/^Subject:\s+(.*)$/i) {
48 $res->{subject} = $1;
49 } elsif (!$res->{messageid} && $d =~ m/^Message-Id:\s+<(.*)>$/i) {
50 $res->{messageid} = $1;
51 }
52 }
53 #elsif ($r eq "M") { last unless defined $dlen; seek($fh, $dlen, 1); }
54 elsif ($r eq "E") { last; }
55 }
56
57 close($fh);
58
59 return $res;
60};
61
c7533620 62# Fixme: it is a bad idea to scan everything - list can be too large
006417f9 63sub show_deferred_queue {
006417f9
DM
64 my $res;
65
66 my $queue = 'deferred';
67
68 my $callback = sub {
69 my $path = $File::Find::name;
70 my $filename = $_;
71
72 my ($dev, $ino, $mode) = lstat($path);
73
74 return if !defined($mode);
75 return if !(-f _ && (($mode & 07777) == 0700));
76
77 if (my $rec = $postfix_qenv->($path)) {
78 $rec->{queue} = $queue;
79 $rec->{qid} = $filename;
80 push @$res, $rec;
81 }
82 };
83
84 find($callback, "$spooldir/deferred");
85
86 return $res;
87}
88
c7533620
DM
89sub qshape {
90 my ($queues) = @_;
91
92 open(my $fh, '-|', '/usr/sbin/qshape', $queues) || die "ERROR: unable to run qshape: $!\n";
93
94 my $line = <$fh>;
95 if (!$line || !($line =~ m/^\s+T\s+5\s+10\s+20\s+40\s+80\s+160\s+320\s+640\s+1280\s+1280\+$/)) {
96 close (CMD);
97 die "ERROR: unable to parse qshape output: - $line";
98 }
99
100 my $count = 0;
101 my $res = [];
102 while (($count++ < 10000) && (defined($line = <$fh>))) {
103 if ($line =~ m/^\s+(\S+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+\s+\d+)$/) {
104 push @$res, $1;
105 }
106 }
107
108 close($fh);
109
110 return $res;
111}
112
006417f9 1131;