From c444e8ec87b6e2a9291d139d6d02a35a5930f631 Mon Sep 17 00:00:00 2001
From: Zsolt Vasarhelyi
Date: Tue, 4 Nov 2025 12:54:36 +0200
Subject: [PATCH] Initial release [SME: 12853]
---
.gitignore | 3 +-
createlinks | 64 ++-
.../smeserver-pfhandle-update}/.gitignore | 0
.../en-us/etc/e-smith/web/functions/qmh | 103 +++++
root/etc/e-smith/web/functions/qmh | 396 ++++++++++++++++++
.../web/panels/manager/cgi-bin}/.gitignore | 0
.../smanager/lib/SrvMngr/Controller/Qmh.pm | 331 +++++++++++++++
.../lib/SrvMngr/I18N/Modules/Qmh/qmh_en.lex | 21 +
.../lib/SrvMngr/I18N/Modules/Qmh/qmh_fr.lex | 21 +
.../themes/default/templates/qmh.html.ep | 56 +++
smeserver-pfhandle.spec | 68 +--
11 files changed, 998 insertions(+), 65 deletions(-)
rename {additional => root/etc/e-smith/events/smeserver-pfhandle-update}/.gitignore (100%)
create mode 100644 root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/qmh
create mode 100755 root/etc/e-smith/web/functions/qmh
rename root/{ => etc/e-smith/web/panels/manager/cgi-bin}/.gitignore (100%)
create mode 100644 root/usr/share/smanager/lib/SrvMngr/Controller/Qmh.pm
create mode 100644 root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Qmh/qmh_en.lex
create mode 100644 root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Qmh/qmh_fr.lex
create mode 100644 root/usr/share/smanager/themes/default/templates/qmh.html.ep
diff --git a/.gitignore b/.gitignore
index a51b323..742f569 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
*.rpm
*.log
*spec-20*
-*.xz
\ No newline at end of file
+*.tgz
+*.tar.xz
diff --git a/createlinks b/createlinks
index 93b9e78..1d37831 100644
--- a/createlinks
+++ b/createlinks
@@ -1,43 +1,33 @@
#!/usr/bin/perl -w
-
-use esmith::Build::CreateLinks qw(:all);
-use esmith::Build::Backup qw(:all);
-
-# our event specific for updating with yum without reboot
-$event = 'smeserver-pfhandle-update';
-#add here the path to your templates needed to expand
-#see the /etc/systemd/system-preset/49-koozali.preset should be present for systemd integration on all you yum update event
-
-# Maybe need ths in here as well:
-# /etc/dar/DailyBackup.dcf - if backup requested
-
-foreach my $file (qw(
- /etc/systemd/system-preset/49-koozali.preset
-))
-{
- templates2events( $file, $event );
-};
-#action needed in case we have a systemd unit
-event_link('systemd-default', $event, '10');
-event_link('systemd-reload', $event, '50');
-
-#services we might need to restart
-#event_services($event, 'xxxx' => 'restart', 'yyyy' => 'restart');
-
-#Backup contrib files
-# backup_includes("smeserver-pfhandle", qw(
- # files(s) to be backed up
-#));
-
-#Other possible entries:
-#Server manager entry
-#panel_link("smeserver-pfhandle", 'manager');
-#Events to smeserver-pfhandle
-#$event = 'smeserver-pfhandle-smeserver-pfhandle';
-# safe_symlink("restart", "root/etc/e-smith/events/$event/services2adjust/smeserver-pfhandle");
-# templates2events("/etc/smeserver-pfhandle/smeserver-pfhandle.conf", $event);
+# This script creates the symlinks needed by this RPM
+# Specific support exists to create symlinks within e-smith web "panels"
+# and for links from named "events" directories into the "actions" directory
+use esmith::Build::CreateLinks qw(:all);
+#--------------------------------------------------
+# functions for manager panel
+#--------------------------------------------------
+my $panel = "manager";
+panel_link("qmh", $panel);
+#--------------------------------------------------
+# actions for console-save event:
+#--------------------------------------------------
+#--------------------------------------------------
+# actions for smeserver-pfhandle-update event:
+#--------------------------------------------------
+
+my $event = 'smeserver-pfhandle-update';
+
+safe_symlink('restart', "root/etc/e-smith/events/$event/services2adjust/smanager");
+
+event_link('navigation2-conf', "$event", '80');
+event_link('routes2-conf', "$event", '80');
+event_link('locales2-conf', "$event", '80');
+
+#--------------------------------------------------
+# The End
+#--------------------------------------------------
diff --git a/additional/.gitignore b/root/etc/e-smith/events/smeserver-pfhandle-update/.gitignore
similarity index 100%
rename from additional/.gitignore
rename to root/etc/e-smith/events/smeserver-pfhandle-update/.gitignore
diff --git a/root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/qmh b/root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/qmh
new file mode 100644
index 0000000..c22f3ae
--- /dev/null
+++ b/root/etc/e-smith/locale/en-us/etc/e-smith/web/functions/qmh
@@ -0,0 +1,103 @@
+
+
+ QMH_TITLE
+ Postfix queue management
+
+
+ OPERATION_STATUS_REPORT
+ Operation status report
+
+
+ QMH_DESC
+
+ This panel uses pfHandle to manage the postfix message queues. Key
+ features are the ability to view and delete messages in the queues.
+
+ ]]>
+
+
+
+ TRY_SEND_QUEUE
+ Force resending of the Postfix queue
+
+
+ SEND_QUEUE_AT
+ Resend Postfix queue at:
+
+
+ LIST_QUEUE
+ List message queues
+
+
+ LIST_LOCAL_QUEUE
+ List active message queue
+
+
+ SHOWLISTQUEUES
+ List all Postfix queues
+
+
+ LIST_REMOTE_QUEUE
+ List deferred message queue
+
+
+ VIEW_TIME
+ Postfix message queue, viewed at:
+
+
+ LIST_LOCAL_QUEUE
+ List Postfix active queue
+
+
+ LIST_REMOTE_QUEUE
+ List Postfix deferred queue
+
+
+ RESEND_QUEUE
+ Try to send queued messages now (postfix must be running)
+
+
+ DELETE_MSG_TITLEB
+ Queue management: delete Message
+
+
+ DELETE_MESSAGE
+
+ Delete this message from the queue ? (Only the first 100 lines are listed)
+
+
+
+ DELETE
+ Delete
+
+
+ DELETED
+ Message deleted
+
+
+ RETURN_TO_QUEUE
+ Return to queue
+
+
+ SELECT_AN_ACTION
+ Select an action
+
+
+ PERFORM
+ Perform
+
+
+ iFROM_QUEUE
+ from message queue
+
+
+ Administration
+ Administration
+
+
+ E-mail Warteschlange
+ E-Mail queue management
+
+
+
diff --git a/root/etc/e-smith/web/functions/qmh b/root/etc/e-smith/web/functions/qmh
new file mode 100755
index 0000000..2b8c6f7
--- /dev/null
+++ b/root/etc/e-smith/web/functions/qmh
@@ -0,0 +1,396 @@
+#!/usr/bin/perl -wT
+#----------------------------------------------------------------------
+# heading : Administration
+# description : E-mail Warteschlange
+# navigation : 5000 5100
+# Copyright (C) 2005/2008 Peter Schubert, SACO Software and Consulting GmbH
+#----------------------------------------------------------------------
+use strict;
+use esmith::FormMagick;
+use esmith::ConfigDB;
+use esmith::AccountsDB;
+use esmith::config;
+use esmith::cgi;
+use esmith::util;
+use esmith::lockfile;
+
+my $fm = esmith::FormMagick->new();
+
+use CGI;
+$CGI::POST_MAX = -1;
+$CGI::DISABLE_UPLOADS = 0;
+$fm->{cgi} = CGI->new();
+
+$fm->parse_xml();
+
+my $conf = esmith::ConfigDB->open()
+ || die $fm->localise('CANNOT_OPEN').'/home/e-smith/configuration';
+
+# We need this hash for some esmith::cgi calls, so...
+tie my %conf, 'esmith::config', $conf->file;
+
+# Unbuffer standard output so that files and directories are listed as
+# they are restored
+$| = 1;
+
+# Store away current gid of 'www' group.
+my $www_gid = getgrnam("www");
+
+#------------------------------------------------------------
+# examine state parameter and display the appropriate form
+#------------------------------------------------------------
+
+my $q = $fm->{cgi};
+
+if (! grep (/^state$/, $q->param))
+{
+ showInitial ($q, '');
+}
+elsif ($q->param ('state') eq "perform")
+{
+ performAndShowResult ($q);
+}
+else
+{
+ esmith::cgi::genStateError ($q, \%conf);
+}
+
+exit (0);
+
+#------------------------------------------------------------
+# subroutine to display initial form
+#------------------------------------------------------------
+
+sub showInitial
+{
+ my ($q, $msg) = @_;
+
+ if ($msg eq '')
+ {
+ esmith::cgi::genHeaderNonCacheable ($q, \%conf,
+ $fm->localise('QMH_TITLE'));
+ }
+ else
+ {
+ esmith::cgi::genHeaderNonCacheable
+ ($q, \%conf, $fm->localise('OPERATION_STATUS_REPORT'));
+
+ print $q->div ({-class => "sme-error"}, $msg);
+ print $q->hr;
+ }
+
+ # Hack to evaluate embedded vars
+ print eval 'return "'.$fm->localise('QMH_DESC').'\n";';
+
+ my %labels = (
+ "list-queues" => $fm->localise('LIST_QUEUE'),
+ "list-local-queue" => $fm->localise('LIST_LOCAL_QUEUE'),
+ "list-remote-queue" => $fm->localise('LIST_REMOTE_QUEUE'),
+ "resend" => $fm->localise('RESEND_QUEUE'),
+ );
+
+ my @labels = (
+ 'list-queues',
+ 'list-local-queue',
+ 'list-remote-queue',
+ 'resend',
+ );
+
+ my $default_action = 'list-queues';
+
+ print $q->start_form(
+ -method => 'POST',
+ -action => $q->url (-absolute => 1)
+ ),"\n";
+
+ print $q->start_table ({-class => "sme-noborders"}),"\n";
+
+ print $q->Tr(
+ $q->td({-class => "sme-noborders-label"},
+ $fm->localise("SELECT_AN_ACTION")),
+ $q->td({-class => "sme-noborders-content"},
+ $q->popup_menu (
+ -name => 'function',
+ -values => [ @labels ],
+ -default => $default_action,
+ -labels => \%labels
+ )
+ )
+ ),"\n";
+
+ print $q->end_table,"\n";
+
+ print $q->start_table ({width => "100%", -class => "sme-noborders"}),
+ "\n";
+
+ print esmith::cgi::genButtonRow(
+ $q,
+ $q->submit (-name => 'action', -value =>
+ $fm->localise('PERFORM'))
+ );
+
+ print $q->end_table,"\n";
+
+ print $q->hidden (
+ -name => 'state',
+ -override => 1,
+ -default => 'perform'
+ ),"\n";
+
+ print $q->end_form,"\n";
+
+ esmith::cgi::genFooter($fm);
+
+ return;
+}
+
+sub performAndShowResult
+{
+ my ($q) = @_;
+
+ my $function = $q->param ('function');
+
+ if ($function eq 'refresh')
+ {
+ showInitial ($q, '');
+ }
+ elsif ($function eq 'list-queues')
+ {
+ showListQueues ($q);
+ }
+ elsif ($function eq 'list-local-queue')
+ {
+ showListLocalQueue ($q);
+ }
+ elsif ($function eq 'list-remote-queue')
+ {
+ showListRemoteQueue ($q);
+ }
+ elsif ($function eq 'resend')
+ {
+ resend($q);
+ }
+ elsif ($function eq 'confirm-delete-message-number')
+ {
+ showDeleteMessageNumber ($q);
+ }
+ elsif ($function eq 'delete-message-number')
+ {
+ deleteMessageNumber($q);
+ }
+
+ else
+ {
+ # Unknown function - refresh the screen anyway
+ showInitial ($q, 'unknown');
+ }
+
+ return;
+
+ print $q->p ( $function );
+ esmith::cgi::genFooter($fm);
+}
+
+#------------------------------------------------------------
+# subroutine to showListQueues
+#------------------------------------------------------------
+sub showListQueues ($)
+{
+ my ($q) = @_;
+
+
+ esmith::cgi::genHeaderNonCacheable ($q, \%conf,
+ $fm->localise('SHOWLISTQUEUES'));
+
+ {
+ print $q->hr;
+ print $q->p($fm->localise('VIEW_TIME')),scalar localtime(time),"\n";
+
+ my $MailQueues = `/usr/sbin/pfHandle -l`;
+ my $queuetype = 'list-queues';
+
+ $MailQueues =~ s/'/g;
+ $MailQueues =~ s/>/'/g;
+
+ $MailQueues = AddLinks($MailQueues, $queuetype, $q);
+
+ print $q->p ($q->pre ("$MailQueues"));
+ }
+
+ esmith::cgi::genFooter($fm);
+ return;
+}
+
+sub AddLinks
+{
+ my $queues = shift;
+ my $queueType = shift;
+
+ my @splitq = split(/\n/, $queues);
+
+ for (my $i = 0; $i < $#splitq; $i++) {
+ if ($splitq[$i] =~ /^([0-9A-F]+)$/ ) {
+ $splitq[$i] = "url( -absolute => 1 ) .
+ "?state=perform&function=confirm-delete-message-number&queue=$queueType" .
+ "&msgid=$1\">$1 ";
+ }
+ }
+ $queues = join("\n", @splitq);
+
+ return $queues;
+}
+
+#------------------------------------------------------------
+# subroutine to showListLocalQueue
+#------------------------------------------------------------
+sub showListLocalQueue ($)
+{
+ my ($q) = @_;
+
+
+ esmith::cgi::genHeaderNonCacheable ($q, \%conf,
+ $fm->localise('LIST_LOCAL_QUEUE'));
+ {
+ print $q->hr;
+ print $q->p($fm->localise('VIEW_TIME')),scalar localtime(time),"\n";
+ my $LocalQueue = `/usr/sbin/pfHandle -a`;
+ my $queuetype = 'list-local-queue';
+
+ $LocalQueue =~ s/'/g;
+ $LocalQueue =~ s/>/'/g;
+ $LocalQueue = AddLinks($LocalQueue, $queuetype);
+
+ print $q->p ($q->pre ("$LocalQueue"));
+ }
+
+ esmith::cgi::genFooter($fm);
+ return;
+}
+
+#------------------------------------------------------------
+# subroutine to showListRemoteQueue
+#------------------------------------------------------------
+sub showListRemoteQueue ($)
+{
+ my ($q) = @_;
+ esmith::cgi::genHeaderNonCacheable ($q, \%conf,
+ $fm->localise('LIST_REMOTE_QUEUE'));
+
+ {
+ print $q->hr;
+ print $q->p($fm->localise('VIEW_TIME')),scalar localtime(time),"\n";
+
+ my $RemoteQueue = `/usr/sbin/pfHandle -d`;
+ my $queuetype = 'list-remote-queue';
+
+ $RemoteQueue =~ s/'/g;
+ $RemoteQueue =~ s/>/'/g;
+
+ $RemoteQueue = AddLinks($RemoteQueue, $queuetype);
+ print $q->p ($q->pre ("$RemoteQueue"));
+ }
+
+ esmith::cgi::genFooter($fm);
+ return;
+}
+
+#------------------------------------------------------------
+# subroutine to send ALARM to qmail
+#------------------------------------------------------------
+sub resend ($)
+{
+ my ($q) = @_;
+ esmith::cgi::genHeaderNonCacheable ($q, \%conf,
+ $fm->localise('TRY_SEND_QUEUE'));
+
+ {
+ print $q->hr;
+ print $q->p($fm->localise('SEND_QUEUE_AT')),scalar localtime(time),"\n";
+
+ my $res = `/usr/sbin/pfHandle -f`;
+
+ print $q->p ($q->pre ("$res"));
+ print $q->h3 ("Done.");
+ }
+
+ esmith::cgi::genFooter($fm);
+ return;
+}
+
+#------------------------------------------------------------
+# subroutine to showDeleteMessageNumber
+#------------------------------------------------------------
+sub showDeleteMessageNumber ($)
+{
+ my ($q) = @_;
+ my $msgid = $q->param ('msgid');
+ my $queuetype = $q->param ('queue');
+
+ if ($msgid =~ /^([0-9A-F]+)$/ ) {
+ $msgid = $1;
+ } else {
+ $msgid = undef;
+ }
+ esmith::cgi::genHeaderNonCacheable ($q, \%conf,
+ $fm->localise('DELETE_MSG_TITLEB'));
+
+ print $q->hr;
+ print $q->p($fm->localise('DELETE_MESSAGE')),"\n";
+ my $Message = `/usr/sbin/pfHandle -m$msgid|head -100`;
+
+ print $q->textarea (-name => 'message', -override => 1, -default => "$Message", -rows => 30, -cols => 80);
+
+ print $q->start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));
+ print $q->table ({border => 0, cellspacing => 0, cellpadding => 4},
+
+ esmith::cgi::genButtonRow ($q,
+ $q->submit (-name => 'action', -value => $fm->localise('Delete'))));
+ print $q->hidden (-name => 'state', -override => 1, -default => 'perform');
+ print $q->hidden (-name => 'msgid', -override => 1, -default => "$msgid");
+ print $q->hidden (-name => 'function', -override => 1, -default => 'delete-message-number');
+ print $q->hidden (-name => 'queue', -override => 1, -default => "$queuetype");
+ print $q->end_form;
+
+ esmith::cgi::genFooter ($q);
+ return;
+}
+
+sub deleteMessageNumber ($)
+{
+ my ($q) = @_;
+
+ my $msgid = $q->param ('msgid');
+ my $queuetype = $q->param ('queue');
+
+ if ($msgid =~ /^([0-9A-F]+)$/ ) {
+ $msgid = $1;
+ } else {
+ $msgid = undef;
+ }
+ my $Output = `/usr/sbin/pfHandle -D$msgid`;
+
+ esmith::cgi::genHeaderNonCacheable ($q, \%conf,
+ "qmail: ". $fm->localise('QMH_TITLE'));
+
+ print $q->hr;
+ print $q->h3 ($fm->localise('DELETED'))," $msgid ";
+ print $q->br();
+ print $q->br();
+
+ print $q->start_multipart_form(-method => 'POST', -action => $q->url (-absolute => 1));
+ print $q->table ({border => 0, cellspacing => 0, cellpadding => 4},
+ esmith::cgi::genButtonRow ($q,
+ $q->submit (-name => 'action', -value => $fm->localise('RETURN_TO_QUEUE'))));
+
+ print $q->hidden (-name => 'state', -override => 1, -default => 'perform');
+ print $q->hidden (-name => 'function', -override => 1, -default => "$queuetype");
+ print $q->end_form;
+
+ esmith::cgi::genFooter ($q);
+ return;
+}
+
+__DATA__
+
diff --git a/root/.gitignore b/root/etc/e-smith/web/panels/manager/cgi-bin/.gitignore
similarity index 100%
rename from root/.gitignore
rename to root/etc/e-smith/web/panels/manager/cgi-bin/.gitignore
diff --git a/root/usr/share/smanager/lib/SrvMngr/Controller/Qmh.pm b/root/usr/share/smanager/lib/SrvMngr/Controller/Qmh.pm
new file mode 100644
index 0000000..ebae829
--- /dev/null
+++ b/root/usr/share/smanager/lib/SrvMngr/Controller/Qmh.pm
@@ -0,0 +1,331 @@
+package SrvMngr::Controller::Qmh;
+
+#----------------------------------------------------------------------
+# heading : System
+# description : E-Mail queue management
+# navigation : 4000 550
+# menu : A
+#
+# name : qmhandle, method : get, url : /qmh, ctlact : qmh#main
+# name : qmhandle2, method : post, url : /qmh, ctlact : qmh#do_update
+# name : qmhandled, method : get, url : /qmh2, ctlact : qmh#do_update
+
+# routes : end
+# Copyright (C) 2005/2008 Peter Schubert, SACO Software and Consulting GmbH
+#----------------------------------------------------------------------
+use strict;
+use warnings;
+use Mojo::Base 'Mojolicious::Controller';
+
+use esmith::FormMagick qw(gen_locale_date_string);
+use esmith::ConfigDB::UTF8;
+
+use Locale::gettext;
+use SrvMngr::I18N;
+
+use SrvMngr qw(theme_list init_session);
+
+my $cdb;
+
+sub main {
+
+ my $c = shift;
+ $c->app->log->info($c->log_req);
+ $cdb = esmith::ConfigDB::UTF8->open() || die 'Cannot open configuration base';
+
+ my %qmh_datas = ();
+ my $title = $c->l('qmh_QMH_TITLE');
+
+ $qmh_datas{'trt'} = 'LST';
+ $qmh_datas{'altq'} = 0;
+
+ $c->stash( title => $title, qmh_datas => \%qmh_datas );
+ $c->render('qmh');
+};
+
+
+sub do_update {
+
+ my $c = shift;
+ $c->app->log->info($c->log_req);
+ $cdb = esmith::ConfigDB::UTF8->open() || die 'Cannot open configuration base';
+
+ my %qmh_datas = ();
+ my $result = "";
+
+ my $report_type = $c->param('Report_type');
+
+ my $trt = $c->param('trt');
+ $qmh_datas{'trt'} = $trt;
+
+ my $altq = $c->param('altq');
+ $qmh_datas{'altq'} = $altq;
+
+ if ($trt eq 'LST') {
+ if ($report_type =~ /^(\S+)$/) {
+ $report_type = $1;
+ } else {
+ $result = $c->l('INVALID_REPORT_TYPE') . " : $report_type";
+ $report_type = undef;
+ }
+
+ $altq = 0;
+ my $function = $report_type || '';
+ if ($function =~ s/^alt-//) {
+ $altq = 1;
+ }
+ $qmh_datas{'altq'} = $altq;
+
+ if ($function eq 'list-queues') {
+ $result = showListQueues ($c, $altq);
+ } elsif ($function eq 'list-local-queue') {
+ $result = showListLocalQueue ($c, $altq);
+ } elsif ($function eq 'list-remote-queue') {
+ $result = showListRemoteQueue ($c, $altq);
+ } elsif ($function eq 'resend') {
+ $result = resend($c, $altq);
+ }
+
+ $qmh_datas{'trt'} = 'REP';
+ }
+
+
+ if ($trt eq 'REP') {
+ $c->redirect_to('/qmh');
+ }
+
+
+ if ($trt eq 'MSG') {
+ my $msgid = $c->param('msgid');
+ $result = $c->render_to_string(inline => showDeleteMessageNumber($c, $msgid, $altq, $report_type)) if $msgid;
+ $qmh_datas{'msgid'} = $msgid;
+ }
+
+
+ if ($trt eq 'DEL') {
+ my $msgid = $c->param('msgid');
+ $result = $c->render_to_string(inline => deleteMessageNumber($c, $msgid, $altq, $report_type)) if $msgid;
+ my $message = $c->l('qmh_DELETE') . ' ' . $msgid;
+ #$c->app->log->info($message.' '.$result);
+ }
+
+
+ my $title = $c->l('qmh_QMH_TITLE');
+ $c->stash( title => $title, qmh_datas => \%qmh_datas, modul => $result );
+ $c->render('qmh');
+
+};
+
+
+sub reportType_list {
+
+ my $c = shift;
+ $cdb = esmith::ConfigDB::UTF8->open() || die 'Cannot open configuration base';
+
+ my $rec = $cdb->get('altqmail');
+ my $altqmail = ($cdb->get('altqmail')->value || 0) if $rec;
+
+ return [[ $c->l('qmh_LIST_QUEUE') => 'list-queues' ],
+ [ $c->l('qmh_LIST_LOCAL_QUEUE') => 'list-local-queue' ],
+ [ $c->l('qmh_LIST_REMOTE_QUEUE') => 'list-remote-queue' ],
+ [ $c->l('qmh_RESEND_QUEUE') => 'resend' ]]
+ unless $altqmail;
+
+ return [[ $c->l('qmh_LIST_QUEUE') => 'list-queues' ],
+ [ $c->l('qmh_LIST_LOCAL_QUEUE') => 'list-local-queue' ],
+ [ $c->l('qmh_LIST_REMOTE_QUEUE') => 'list-remote-queue' ],
+ [ $c->l('qmh_RESEND_QUEUE') => 'resend' ],
+ [ "altqmail: ". $c->l('qmh_LIST_QUEUE') => 'alt-list-queues' ],
+ [ "altqmail: ". $c->l('qmh_LIST_LOCAL_QUEUE') => 'alt-list-local-queue' ],
+ [ "altqmail: ". $c->l('qmh_LIST_REMOTE_QUEUE') => 'alt-list-remote-queue' ],
+ [ "altqmail: ". $c->l('qmh_RESEND_QUEUE') => 'alt-resend' ]];
+}
+
+
+#------------------------------------------------------------
+# subroutine to showListQueues
+#------------------------------------------------------------
+sub showListQueues {
+
+ my ($c, $altq) = @_;
+ $cdb = esmith::ConfigDB::UTF8->open() || die 'Cannot open configuration base';
+
+ my $out = '';
+ my $reporttype = 'list-queues';
+
+ my $opt = ($altq ? 'altqmail: ' : '');
+ $out .= sprintf("%s ", $opt . $c->l('qmh_SHOWLISTQUEUES'));
+ $out .= sprintf("%s %s", $c->l('qmh_VIEW_TIME'), scalar localtime(time));
+
+ my $MailQueues = `/usr/sbin/pfHandle -l`;
+ $MailQueues =~ s/'/g;
+ $MailQueues =~ s/>/'/g;
+
+ $MailQueues = AddLinks($MailQueues, $altq, $reporttype);
+
+ $out .= sprintf "";
+ $out .= "$MailQueues";
+ $out .= sprintf " ";
+ $out .= sprintf " ";
+ return $out;
+}
+
+
+#------------------------------------------------------------
+# subroutine to showListLocalQueue
+#------------------------------------------------------------
+sub showListLocalQueue {
+
+ my ($c, $altq) = @_;
+ $cdb = esmith::ConfigDB::UTF8->open() || die 'Cannot open configuration base';
+
+ my $out = '';
+ my $reporttype = 'list-local-queue';
+
+ my $opt = ($altq ? 'altqmail: ' : '');
+ $out .= sprintf("%s ", $opt . $c->l('qmh_LIST_LOCAL_QUEUE'));
+ $out .= sprintf("%s %s", $c->l('qmh_VIEW_TIME'), scalar localtime(time));
+
+ my $LocalQueue = `/usr/sbin/pfHandle -a`;
+ $LocalQueue =~ s/'/g;
+ $LocalQueue =~ s/>/'/g;
+
+ $LocalQueue = AddLinks($LocalQueue, $altq, $reporttype);
+
+ $out .= sprintf "";
+ $out .= "$LocalQueue";
+ $out .= sprintf " ";
+ $out .= sprintf " ";
+ return $out;
+}
+
+
+#------------------------------------------------------------
+# subroutine to showListRemoteQueue
+#------------------------------------------------------------
+sub showListRemoteQueue {
+
+ my ($c, $altq) = @_;
+ $cdb = esmith::ConfigDB::UTF8->open() || die 'Cannot open configuration base';
+
+ my $out = '';
+ my $reporttype = 'list-remote-queue';
+
+ my $opt = ($altq ? 'altqmail: ' : '');
+ $out .= sprintf("%s ", $opt . $c->l('qmh_LIST_REMOTE_QUEUE'));
+ $out .= sprintf("%s %s", $c->l('qmh_VIEW_TIME'), scalar localtime(time));
+
+ my $RemoteQueue = `/usr/sbin/pfHandle -d`;
+ $RemoteQueue =~ s/'/g;
+ $RemoteQueue =~ s/>/'/g;
+
+ $RemoteQueue = AddLinks($RemoteQueue, $altq, $reporttype);
+
+ $out .= sprintf "";
+ $out .= "$RemoteQueue";
+ $out .= sprintf " ";
+ $out .= sprintf " ";
+ return $out;
+}
+
+
+#------------------------------------------------------------
+# subroutine to send ALARM to qmail
+#------------------------------------------------------------
+sub resend {
+
+ my ($c, $altq) = @_;
+ $cdb = esmith::ConfigDB::UTF8->open() || die 'Cannot open configuration base';
+
+ my $out = '';
+ my $reporttype = 'resend';
+
+ my $opt = ($altq ? 'altqmail: ' : '');
+ $out .= sprintf("%s ", $opt . $c->l('qmh_TRY_SEND_QUEUE'));
+ $out .= sprintf("%s %s", $c->l('qmh_SEND_QUEUE_AT'), scalar localtime(time));
+
+ my $Res = `/usr/sbin/pfHandle -f`;
+ $Res =~ s/'/g;
+ $Res =~ s/>/'/g;
+
+ $Res = AddLinks($Res, $altq, $reporttype);
+
+ $out .= sprintf "";
+ $out .= "$Res";
+ $out .= sprintf " ";
+ $out .= sprintf " ";
+ $out .= sprintf "Done ";
+ return $out;
+}
+
+
+sub AddLinks {
+
+ my ($queues, $altq, $reporttype) = @_;
+
+ my @splitq = split(/\n/, $queues);
+
+ for (my $i = 0; $i < $#splitq; $i++) {
+ if ($splitq[$i] =~ /^([0-9A-F]+)$/ ) {
+ $splitq[$i] = "$1 ";
+ }
+ }
+ $queues = join("\n", @splitq);
+
+ return $queues;
+}
+
+
+#------------------------------------------------------------
+# subroutine to showDeleteMessageNumber
+#------------------------------------------------------------
+sub showDeleteMessageNumber {
+
+ my ($c, $msgid, $altq, $reporttype) = @_;
+ $cdb = esmith::ConfigDB::UTF8->open() || die 'Cannot open configuration base';
+
+ if ($msgid =~ /^([0-9A-F]+)$/ ) {
+ $msgid = $1;
+ } else {
+ $msgid = undef;
+ }
+
+ my $out = '';
+
+ my $opt = ($altq ? 'altqmail: ' : '');
+ $out .= sprintf("%s ", $opt . $c->l('qmh_DELETE_MSG_TITLEB'));
+ $out .= sprintf("%s", $c->l('qmh_DELETE_MESSAGE'));
+
+ my $Message = `/usr/sbin/pfHandle -m$msgid|head -100`;
+
+ $out .= sprintf "";
+ $out .= "";
+ $out .= sprintf " ";
+ $out .= sprintf " ";
+ return $out;
+}
+
+
+sub deleteMessageNumber {
+
+ my ($c, $msgid, $altq, $reporttype) = @_;
+
+ if ($msgid =~ /^([0-9A-F]+)$/ ) {
+ $msgid = $1;
+ } else {
+ $msgid = undef;
+ }
+
+ my $out = '';
+ my $Output = `/usr/sbin/pfHandle -D$msgid`;
+
+ $out .= sprintf "";
+ $out .= "$Output";
+ $out .= sprintf " ";
+ $out .= sprintf " ";
+ return $out;
+
+}
+
+
+1;
\ No newline at end of file
diff --git a/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Qmh/qmh_en.lex b/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Qmh/qmh_en.lex
new file mode 100644
index 0000000..d03570b
--- /dev/null
+++ b/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Qmh/qmh_en.lex
@@ -0,0 +1,21 @@
+'qmh_QMH_TITLE' => 'Postfix queue management',
+'qmh_OPERATION_STATUS_REPORT' => 'Operation status report',
+'qmh_QMH_DESC' => 'This panel uses pfHandle to manage the postfix message queues. Key features are the ability to view and delete messages in the queues.',
+'qmh_TRY_SEND_QUEUE' => 'Force resending of the Postfix queue',
+'qmh_SEND_QUEUE_AT' => 'Resend Postfix queue at: ',
+'qmh_LIST_QUEUE' => 'List message queues',
+'qmh_LIST_LOCAL_QUEUE' => 'List active message queue',
+'qmh_SHOWLISTQUEUES' => 'List all Postfix queues',
+'qmh_LIST_REMOTE_QUEUE' => 'List deferred message queue',
+'qmh_VIEW_TIME' => 'Postfix message queue, viewed at: ',
+'qmh_LIST_LOCAL_QUEUE' => 'List Postfix active queue',
+'qmh_LIST_REMOTE_QUEUE' => 'List Postfix deferred queue',
+'qmh_RESEND_QUEUE' => 'Try to send queued messages now (postfix must be running)',
+'qmh_DELETE_MSG_TITLEB' => 'Queue management: delete Message',
+'qmh_DELETE_MESSAGE' => 'Delete this message from the queue ? (Only the first 100 lines are listed)',
+'qmh_DELETE' => 'Delete',
+'qmh_SELECT_AN_ACTION' => 'Select an action',
+'qmh_iFROM_QUEUE' => 'from message queue',
+'qmh_RETURN_TO_QUEUE' => 'Return to Queue',
+'qmh_Administration' => 'Administration',
+'E-mail Warteschlange' => 'E-Mail queue management',
diff --git a/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Qmh/qmh_fr.lex b/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Qmh/qmh_fr.lex
new file mode 100644
index 0000000..5ab1713
--- /dev/null
+++ b/root/usr/share/smanager/lib/SrvMngr/I18N/Modules/Qmh/qmh_fr.lex
@@ -0,0 +1,21 @@
+'qmh_QMH_TITLE' => 'Administration de file d\'attente',
+'qmh_OPERATION_STATUS_REPORT' => 'Rapport d\'état de l\'opération',
+'qmh_QMH_DESC' => 'Ce panel utilise pfHandle pour administrer la file d\'attente de Postfix. Les fonctionnalités principales sont de voir et d\'effacer des messages dans la file d\'attente. ',
+'qmh_TRY_SEND_QUEUE' => 'Forcer le renvoi de la file d\'attente de postfix',
+'qmh_SEND_QUEUE_AT' => 'Renvoi la file d\'attente Postfix le : ',
+'qmh_LIST_QUEUE' => 'Message de la file d\'attente',
+'qmh_LIST_LOCAL_QUEUE' => 'File d\'attente active',
+'qmh_SHOWLISTQUEUES' => 'Toutes les files d\'attente',
+'qmh_LIST_REMOTE_QUEUE' => 'File d\'attente différée de Postfix',
+'qmh_VIEW_TIME' => 'La file d\'attente des messages de Postfix le : ',
+'qmh_LIST_LOCAL_QUEUE' => 'File d\'attente active de Postfix',
+'qmh_LIST_REMOTE_QUEUE' => 'File d\'attente différée de Postfix',
+'qmh_RESEND_QUEUE' => 'Renvoyer les messages de la file d\'attente maintenant (Postfix doit être en fonction)',
+'qmh_DELETE_MSG_TITLEB' => 'Administration de file d\'attente : effacer le Message',
+'qmh_DELETE_MESSAGE' => 'Effacez ce message de la file d\'attente? (Seulement les 100 premières lignes sont affichées)',
+'qmh_DELETE' => 'Supprimer',
+'qmh_SELECT_AN_ACTION' => 'Sélectionnez une action :',
+'qmh_iFROM_QUEUE' => 'de la file d\'attente des messages',
+'qmh_RETURN_TO_QUEUE' => 'Retour à la file d\'attente',
+'qmh_Administration' => 'Administration',
+'E-mail Warteschlange' => 'Administration de file d\'attente des courriels',
diff --git a/root/usr/share/smanager/themes/default/templates/qmh.html.ep b/root/usr/share/smanager/themes/default/templates/qmh.html.ep
new file mode 100644
index 0000000..8c00793
--- /dev/null
+++ b/root/usr/share/smanager/themes/default/templates/qmh.html.ep
@@ -0,0 +1,56 @@
+% layout 'default', title => "Sme server 2 - qmh";
+
+% content_for 'module' => begin
+
+ % if (config->{debug} == 1) {
+
+ %= dumper $c->current_route
+ %= dumper $qmh_datas
+
+ %}
+ % if ( stash 'error' ) {
+
+ %= $c->render_to_string(inline => stash 'error')
+
+ %}
+
<%= $title %>
+
+ % my $btn = l('PERFORM');
+ % my $url = '/qmh';
+
+ %= form_for "$url" => (method => 'POST') => begin
+ % if ($qmh_datas->{trt} eq 'LST') {
+ %= $c->render_to_string(inline => $c->l('qmh_QMH_DESC'));
+
+
+ %=l 'qmh_SELECT_AN_ACTION'
+
+
+ %= select_field 'Report_type' => $c->reportType_list()
+
+
+ %}
+ % if ($qmh_datas->{trt} eq 'REP') {
+ % $btn = l('NEXT');
+ %= $c->render_to_string( inline => stash 'modul' )
+ %}
+ % if ($qmh_datas->{trt} eq 'DEL') {
+ % $btn = l('qmh_RETURN_TO_QUEUE');
+ %= $c->render_to_string( inline => stash 'modul' )
+ %= hidden_field 'msgid' => $qmh_datas->{msgid}
+ % $qmh_datas->{trt} = 'LST';
+ %}
+ % if ($qmh_datas->{trt} eq 'MSG') {
+ % $btn = l('Delete');
+ %= $c->render_to_string( inline => stash 'modul' )
+ %= hidden_field 'msgid' => $qmh_datas->{msgid}
+ % $qmh_datas->{trt} = 'DEL';
+ %}
+
+ %= submit_button "$btn", class => 'action'
+
+ %= hidden_field 'trt' => $qmh_datas->{trt}
+ %= hidden_field 'altq' => $qmh_datas->{altq}
+ % end
+
+%end
diff --git a/smeserver-pfhandle.spec b/smeserver-pfhandle.spec
index 1c7a5e2..da75a1b 100644
--- a/smeserver-pfhandle.spec
+++ b/smeserver-pfhandle.spec
@@ -1,55 +1,69 @@
%define name smeserver-pfhandle
+Name: %{name}
%define version 1.0
%define release 1
-Summary: This is what smeserver-pfhandle does.
-Name: %{name}
Version: %{version}
Release: %{release}%{?dist}
-Source: %{name}-%{version}.tar.gz
-License: GNU GPL version 2
-Group: SMEserver/addon
-BuildRoot: %{_tmppath}/%{name}-buildroot
-Prefix: %{_prefix}
-BuildArchitectures: noarch
+BuildArch: noarch
+License: GPL
+Group: Networking/Info
+Summary: adds a panel for managing the Postfix queues using pfhandle
+BuildRoot: /var/tmp/%{name}-%{version}-%{release}-buildroot
+Source: %{name}-%{version}.tar.xz
+
+Obsoletes: qmHandle
+Obsoletes: e-smith-qmail-view
+Obsoletes: e-smith-qmHandle
+Obsoletes: smeserver-saco-qmHandle
+Obsoletes: smeserver-qmHandle
+Provides: smeserver-pfhandle
+Requires: smeserver-base
+Requires: smeserver-lib
+Requires: perl
+Requires: pfHandle >= 1.1-6
+Requires: smeserver-release >= 11
BuildRequires: smeserver-devtools
-Requires: smeserver-release >= 11.0
+
AutoReqProv: no
%description
-Postfix mail queue manager
+A panel for managing the Postfix queues using pfhandle
+(http://launchpad.net/pfhandle)
%changelog
-* Day MMMM DD YYYY 1.0-1.sme
-- Initial code - create RPM [SME:99999]
+* Tue Nov 03 2025 Vasarhelyi Zsolt 1.0-1.sme
+- Initial release [SME: 12853]
%prep
+%setup
-%setup -q
+mkdir -p root/etc/e-smith/events/smeserver-pfhandle-update
%build
perl createlinks
%install
rm -rf $RPM_BUILD_ROOT
+
(cd root ; find . -depth -print | cpio -dump $RPM_BUILD_ROOT)
-rm -f %{name}-%{version}-filelist
-/sbin/e-smith/genfilelist $RPM_BUILD_ROOT \
-> %{name}-%{version}-filelist
-#echo "%doc COPYING" >> %{name}-%{version}-filelist
-#--dir 'attr(755,user,grp)' \
-#--file 'attr(755,root,root)' \
+rm -f e-smith-%{version}-filelist
+/sbin/e-smith/genfilelist $RPM_BUILD_ROOT > %{name}-%{version}-filelist
%clean
-cd ..
-rm -rf %{name}-%{version}
+rm -rf $RPM_BUILD_ROOT
+
+%files -f %{name}-%{version}-filelist
+
+%defattr(-,root,root)
+%attr(4750 root admin) "/etc/e-smith/web/functions/qmh"
%pre
+%post -p /bin/sh
+
+#/etc/e-smith/events/actions/navigation-conf >/dev/null 2>&1
+
%preun
-%post
-
-%postun
-#uninstall
-%files -f %{name}-%{version}-filelist
-%defattr(-,root,root)
+%postun -p /bin/sh
+#/etc/e-smith/events/actions/navigation-conf >/dev/null 2>&1