1 #!/usr/local/bin/perl -w
8 my $sendmailDaemon = "/usr/sbin/sendmail -q30m -bd";
10 ##########################################################################
12 # &get_controlname -- read ControlSocketName option from sendmail.cf
18 # control socket filename, undef if not found
26 open(CF, "</etc/mail/sendmail.cf") or return $cn;
30 if (/^O ControlSocketName\s*=\s*([^#]+)$/o)
34 if (/^O QueueDirectory\s*=\s*([^#]+)$/o)
50 return undef if (not defined $qd);
52 $cn = $qd . "/" . $cn;
57 ##########################################################################
59 # &do_command -- send command to sendmail daemon view control socket
62 # controlsocket -- filename for socket
63 # command -- command to send
66 # reply from sendmail daemon
71 my $controlsocket = shift;
73 my $proto = getprotobyname('ip');
77 socket(SOCK, PF_UNIX, SOCK_STREAM, $proto) or return undef;
79 for ($i = 0; $i < 4; $i++)
81 if (!connect(SOCK, sockaddr_un($controlsocket)))
94 print SOCK "$command\n";
97 return join '', @reply;
100 ##########################################################################
102 # &sendmail_running -- check if sendmail is running via SMTP
108 # 1 if running, undef otherwise
113 my $port = getservbyname("smtp", "tcp") || 25;
114 my $proto = getprotobyname("tcp");
115 my $iaddr = inet_aton("localhost");
116 my $paddr = sockaddr_in($port, $iaddr);
118 socket(SOCK, PF_INET, SOCK_STREAM, $proto) or return undef;
119 if (!connect(SOCK, $paddr))
127 if (/^(\d{3})([ -])/)
151 ##########################################################################
153 # &munge_status -- turn machine readable status into human readable text
156 # raw -- raw results from sendmail daemon STATUS query
159 # human readable text
166 my $daemonStatus = "";
168 if ($raw =~ /^(\d+)\/(\d+)\/(\d+)\/(\d+)/mg)
170 $cooked .= "Current number of children: $1";
173 $cooked .= " (maximum $2)";
176 $cooked .= "QueueDir free disk space (in blocks): $3\n";
177 $cooked .= "Load average: $4\n";
179 while ($raw =~ /^(\d+) (.*)$/mg)
181 if (not $daemonStatus)
183 $daemonStatus = "(process $1) " . ucfirst($2) . "\n";
187 $cooked .= "Child Process $1 Status: $2\n";
190 return ($daemonStatus, $cooked);
193 ##########################################################################
195 # &start_daemon -- fork off a sendmail daemon
198 # control -- control socket name
201 # Error message or "OK" if successful
213 waitpid $pid, 0 or return "Could not get status of created process: $!\n";
214 $exitstat = $? / 256;
217 return "sendmail daemon startup exited with exit value $exitstat";
222 exec($sendmailDaemon);
223 die "Unable to start sendmail daemon: $!.\n";
227 return "Could not create new process: $!\n";
232 ##########################################################################
234 # &stop_daemon -- stop the sendmail daemon using control socket
237 # control -- control socket name
240 # Error message or status message
248 if (not defined $control)
250 return "The control socket is not configured so the daemon can not be stopped.\n";
252 return &do_command($control, "SHUTDOWN");
255 ##########################################################################
257 # &restart_daemon -- restart the sendmail daemon using control socket
260 # control -- control socket name
263 # Error message or status message
271 if (not defined $control)
273 return "The control socket is not configured so the daemon can not be restarted.";
275 return &do_command($control, "RESTART");
278 ##########################################################################
280 # &memdump -- get memdump from the daemon using the control socket
283 # control -- control socket name
286 # Error message or status message
294 if (not defined $control)
296 return "The control socket is not configured so the daemon can not be queried for memdump.";
298 return &do_command($control, "MEMDUMP");
301 ##########################################################################
303 # &help -- get help from the daemon using the control socket
306 # control -- control socket name
309 # Error message or status message
317 if (not defined $control)
319 return "The control socket is not configured so the daemon can not be queried for help.";
321 return &do_command($control, "HELP");
325 my $daemonStatus = undef;
328 getopts('f:', $opts) || die "Usage: $0 [-f /path/to/control/socket] command\n";
330 my $control = $opts->{f} || &get_controlname;
333 if (not defined $control)
335 die "No control socket available.\n";
337 if (not defined $command)
339 die "Usage: $0 [-f /path/to/control/socket] command\n";
341 if ($command eq "status")
343 $status = &do_command($control, "STATUS");
344 if (not defined $status)
346 # Not responding on control channel, query via SMTP
347 if (&sendmail_running)
349 $daemonStatus = "Sendmail is running but not answering status queries.";
353 $daemonStatus = "Sendmail does not appear to be running.";
358 # Munge control channel output
359 ($daemonStatus, $status) = &munge_status($status);
362 elsif (lc($command) eq "shutdown")
364 $status = &stop_daemon($control);
366 elsif (lc($command) eq "restart")
368 $status = &restart_daemon($control);
370 elsif (lc($command) eq "start")
372 $status = &start_daemon($control);
374 elsif (lc($command) eq "memdump")
376 $status = &memdump($control);
378 elsif (lc($command) eq "help")
380 $status = &help($control);
382 elsif (lc($command) eq "mstat")
384 $status = &do_command($control, "mstat");
385 if (not defined $status)
387 # Not responding on control channel, query via SMTP
388 if (&sendmail_running)
390 $daemonStatus = "Sendmail is running but not answering status queries.";
394 $daemonStatus = "Sendmail does not appear to be running.";
400 die "Unrecognized command $command\n";
402 if (defined $daemonStatus)
404 print "Daemon Status: $daemonStatus\n";