smcontrol.pl
上传用户:xu_441
上传日期:2007-01-04
资源大小:1640k
文件大小:6k
源码类别:

Email客户端

开发平台:

Unix_Linux

  1. #!/usr/local/bin/perl -w
  2. use FileHandle;
  3. use Socket;
  4. $sendmailDaemon = "/usr/sbin/sendmail -q30m -bd";
  5. ##########################################################################
  6. #
  7. #  &get_controlname -- read ControlSocketName option from sendmail.cf
  8. #
  9. # Parameters:
  10. # none.
  11. #
  12. # Returns:
  13. # control socket filename, undef if not found
  14. #
  15. sub get_controlname
  16. {
  17. my $cn = undef;
  18. my $qd = undef;
  19.  
  20. open(CF, "</etc/mail/sendmail.cf") or return $cn;
  21. while (<CF>)
  22. {
  23. chomp;
  24. if (/^O ControlSocketNames*=s*([^#]+)$/o)
  25. {
  26. $cn = $1;
  27. }
  28. if (/^O QueueDirectorys*=s*([^#]+)$/o)
  29. {
  30. $qd = $1;
  31. }
  32. if (/^OQ([^#]+)$/o)
  33. {
  34. $qd = $1;
  35. }
  36. }
  37. close(CF);
  38. if (not defined $cn)
  39. {
  40. return undef;
  41. }
  42. if ($cn !~ /^//o)
  43. {
  44. return undef if (not defined $qd);
  45. $cn = $qd . "/" . $cn;
  46. }
  47. return $cn;
  48. }
  49. ##########################################################################
  50. #
  51. #  &do_command -- send command to sendmail daemon view control socket
  52. #
  53. # Parameters:
  54. # controlsocket -- filename for socket
  55. # command -- command to send
  56. #
  57. # Returns:
  58. # reply from sendmail daemon
  59. #
  60. sub do_command
  61. {
  62. my $controlsocket = shift;
  63. my $command = shift;
  64. my $proto = getprotobyname('ip');
  65. my @reply;
  66. socket(SOCK, PF_UNIX, SOCK_STREAM, $proto) or return undef;
  67. for ($i = 0; $i < 4; $i++)
  68. {
  69. if (!connect(SOCK, sockaddr_un($controlsocket)))
  70. {
  71. if ($i == 3)
  72. {
  73. close(SOCK);
  74. return undef;
  75. }
  76. sleep 1;
  77. next;
  78. }
  79. last;
  80. }
  81. autoflush SOCK 1;
  82. print SOCK "$commandn";
  83. @reply = <SOCK>;
  84. close(SOCK);
  85. return join '', @reply;
  86. }
  87. ##########################################################################
  88. #
  89. #  &sendmail_running -- check if sendmail is running via SMTP
  90. #
  91. # Parameters:
  92. # none
  93. #
  94. # Returns:
  95. # 1 if running, undef otherwise
  96. #
  97. sub sendmail_running
  98. {
  99. my $port = getservbyname("smtp", "tcp") || 25;
  100. my $proto = getprotobyname("tcp");
  101. my $iaddr = inet_aton("localhost");
  102. my $paddr = sockaddr_in($port, $iaddr);
  103. socket(SOCK, PF_INET, SOCK_STREAM, $proto) or return undef;
  104. if (!connect(SOCK, $paddr))
  105. {
  106. close(SOCK);
  107. return undef;
  108. }
  109. autoflush SOCK 1;
  110. while (<SOCK>)
  111. {
  112. if (/^(d{3})([ -])/)
  113. {
  114. if ($1 != 220)
  115. {
  116. close(SOCK);
  117. return undef;
  118. }
  119. }
  120. else
  121. {
  122. close(SOCK);
  123. return undef;
  124. }
  125. last if ($2 eq " ");
  126. }
  127. print SOCK "QUITn";
  128. while (<SOCK>)
  129. {
  130. last if (/^d{3} /);
  131. }
  132. close(SOCK);
  133. return 1;
  134. }
  135. ##########################################################################
  136. #
  137. #  &munge_status -- turn machine readable status into human readable text
  138. #
  139. # Parameters:
  140. # raw -- raw results from sendmail daemon STATUS query
  141. #
  142. # Returns:
  143. # human readable text
  144. #
  145. sub munge_status
  146. {
  147. my $raw = shift;
  148. my $cooked = "";
  149. my $daemonStatus = "";
  150. if ($raw =~ /^(d+)/(d+)/(d+)/(d+)$/mg)
  151. {
  152. $cooked .= "Current number of children: $1";
  153. if ($2 > 0)
  154. {
  155. $cooked .= " (maximum $2)";
  156. }
  157. $cooked .= "n";
  158. $cooked .= "QueueDir free disk space (in blocks): $3n";
  159. $cooked .= "Load average: $4n";
  160. }
  161. while ($raw =~ /^(d+) (.*)$/mg)
  162. {
  163. if (not $daemonStatus)
  164. {
  165. $daemonStatus = "(process $1) " . ucfirst($2) . "n";
  166. }
  167. else
  168. {
  169. $cooked .= "Child Process $1 Status: $2n";
  170. }
  171. }
  172. return ($daemonStatus, $cooked);
  173. }
  174. ##########################################################################
  175. #
  176. #  &start_daemon -- fork off a sendmail daemon
  177. #
  178. # Parameters:
  179. # control -- control socket name
  180. #
  181. # Returns:
  182. # Error message or "OK" if successful
  183. #
  184. sub start_daemon
  185. {
  186. my $control = shift;
  187. my $pid;
  188. if ($pid = fork)
  189. {
  190. my $exitstat;
  191. waitpid $pid, 0 or return "Could not get status of created process: $!n";
  192. $exitstat = $? / 256;
  193. if ($exitstat != 0)
  194. {
  195. return "sendmail daemon startup exited with exit value $exitstat";
  196. }
  197. }
  198. elsif (defined $pid)
  199. {
  200. exec($main::sendmailDaemon);
  201. die "Unable to start sendmail daemon: $!.n";
  202. }
  203. else
  204. {
  205. return "Could not create new process: $!n";
  206. }
  207. return "OKn";
  208. }
  209. ##########################################################################
  210. #
  211. #  &stop_daemon -- stop the sendmail daemon using control socket
  212. #
  213. # Parameters:
  214. # control -- control socket name
  215. #
  216. # Returns:
  217. # Error message or status message
  218. #
  219. sub stop_daemon
  220. {
  221. my $control = shift;
  222. my $status;
  223. if (not defined $control)
  224. {
  225. return "The control socket is not configured so the daemon can not be stopped.n";
  226. }
  227. return &do_command($control, "SHUTDOWN");
  228. }
  229. ##########################################################################
  230. #
  231. #  &restart_daemon -- restart the sendmail daemon using control socket
  232. #
  233. # Parameters:
  234. # control -- control socket name
  235. #
  236. # Returns:
  237. # Error message or status message
  238. #
  239. sub restart_daemon
  240. {
  241. my $control = shift;
  242. my $status;
  243. if (not defined $control)
  244. {
  245. return "The control socket is not configured so the daemon can not be restarted.";
  246. }
  247. return &do_command($control, "RESTART");
  248. }
  249. ##########################################################################
  250. #
  251. #  &help -- get help from the daemon using the control socket
  252. #
  253. # Parameters:
  254. # control -- control socket name
  255. #
  256. # Returns:
  257. # Error message or status message
  258. #
  259. sub help
  260. {
  261. my $control = shift;
  262. my $status;
  263. if (not defined $control)
  264. {
  265. return "The control socket is not configured so the daemon can not be queried for help.";
  266. }
  267. return &do_command($control, "HELP");
  268. }
  269. my $command = shift;
  270. my $control = &get_controlname;
  271. my $status = undef;
  272. my $daemonStatus = undef;
  273. if (not defined $control)
  274. {
  275. die "No control socket available.n";
  276. }
  277. if (not defined $command)
  278. {
  279. die "Usage: $0 commandn";
  280. }
  281. if ($command eq "status")
  282. {
  283. $status = &do_command($control, "STATUS");
  284. if (not defined $status)
  285. {
  286. # Not responding on control channel, query via SMTP
  287. if (&sendmail_running)
  288. {
  289. $daemonStatus = "Sendmail is running but not answering status queries.";
  290. }
  291. else
  292. {
  293. $daemonStatus = "Sendmail does not appear to be running.";
  294. }
  295. }
  296. else
  297. {
  298. # Munge control channel output
  299. ($daemonStatus, $status) = &munge_status($status);
  300. }
  301. }
  302. elsif (lc($command) eq "shutdown")
  303. {
  304. $status = &stop_daemon($control);
  305. }
  306. elsif (lc($command) eq "restart")
  307. {
  308. $status = &restart_daemon($control);
  309. }
  310. elsif (lc($command) eq "start")
  311. {
  312. $status = &start_daemon($control);
  313. }
  314. elsif (lc($command) eq "help")
  315. {
  316. $status = &help($control);
  317. }
  318. else
  319. {
  320. die "Unrecognized command $commandn";
  321. }
  322. if (defined $daemonStatus)
  323. {
  324. print "Daemon Status: $daemonStatusn";
  325. }
  326. if (defined $status)
  327. {
  328. print "$statusn";
  329. }
  330. else
  331. {
  332. die "No responsen";
  333. }