mailstats-horowitz
上传用户:shbosideng
上传日期:2013-05-04
资源大小:1555k
文件大小:15k
源码类别:

SNMP编程

开发平台:

C/C++

  1. #!/usr/bin/perl
  2. #
  3. # Author by Rick Horowitz <rick@techstop.com> 1998-12-16
  4. # Inspired by, and may show remnants of code from: 
  5. #            "mailstats" by Petter Reinholdtsen <pere@td.org.uit.no> 
  6. #             dated 1997-07-09 and part of mrtg2.54c dist
  7. # Petter credits Rachel Polanskis <rachel@juno.virago.org.au> for 
  8. # the original. 
  9. # Type "perldoc mrtg-mailstat" from a shell prompt for more information
  10. # on this script and its use. 
  11. #
  12. use strict;
  13. use Socket;
  14. use Getopt::Long;
  15. # IMPORTANT: THIS NEXT LINE ENSURE THAT CASE MATTERS ON OPTIONS!!!
  16. $Getopt::Long::ignorecase = 0;    
  17. use vars qw($datafile $server $sourceport $oldfrm $oldto $help
  18.             $newfrm $newto $uptime $mailtype $logbase);
  19. # Assign options.  ("Illegal" options will be possible, 
  20. # but we'll warn about them via Usage().)
  21. #     h = runs the perldoc program to show the mrtg-mailstat manual
  22. #     m = specifies the type of mail we're checking for 
  23. #     p = specifies the port for reaching the mailstats on the mailserver
  24. #     s = specifies the location of the mailserver 
  25. # See the mrtg-mailstat man page for details.  
  26. GetOptions("help"          => $help,
  27.            "logbase=s"     => $logbase, 
  28.            "mailtype=s"    => $mailtype, 
  29.            "port=i"        => $sourceport, 
  30.            "server=s"      => $server, 
  31.    "<>"            => &Usage); 
  32. # HARDCODING SECTION -- MODIFY THESE ONLY IF YOU KNOW WHAT YOU ARE DOING!!!
  33. # Set these ONLY if you don't wish to use command line options.  For more 
  34. # information, type 'mrtg-mailstat -h' or 'perldoc mrtg-mailstat' from a 
  35. # shell prompt.
  36. $logbase    = '/tmp' unless $logbase;
  37. $mailtype   = '' unless $mailtype;
  38. $server     = '' unless $server;
  39. $sourceport = '' unless $sourceport;
  40. # Location for keeping mail statistics.  The numbers stored here are 
  41. # compared to the new numbers at each run of this script. 
  42. $datafile       = "$logbase/${mailtype}-mailstat.old";
  43. # Core portions of the program.  Most of retained code from original 
  44. # comes into play here.  
  45. GetHelp() if $help; 
  46. Usage() unless ($mailtype && $server && $sourceport);
  47. ($oldfrm, $oldto)          = GetOldStats($datafile);
  48. ($newfrm, $newto, $uptime) = GetNewStats($server, $sourceport);
  49. PutOldStats($datafile, $newfrm, $newto) || warn "$0: Unable to save stats to $datafile";
  50. print $newfrm-$oldfrm,"n",$newto-$oldto,"n","$uptimenthe mail servern" if ($oldfrm);
  51. ##
  52. # Returns first line of file given as param split on (a single) space
  53. sub GetOldStats {
  54.     my($datafile) = @_;
  55.     if (-e $datafile) { 
  56.         open(OLD, $datafile) || warn "$0: Unable to open $datafile for reading";
  57.         my($line) = <OLD>;
  58.         close(OLD);
  59.         return split(/ /, $line);
  60.     } else { 
  61.         return(0, 0);
  62.     }
  63.        
  64. }
  65. sub GetNewStats {
  66.     my($server, $sourceport) = @_;
  67.     my(@output, $port, $proto, $iaddr, $paddr, $tempuptime, $curfrm, $curto, $uptime);
  68.     if ( $server eq "localhost" ) {
  69. @output = `/usr/sbin/mailstats`;
  70. chomp(@output);
  71.     } else {
  72.         if ($sourceport =~ /D/) { 
  73.     $port = getservbyname ($sourceport, 'tcp');
  74.          } else { 
  75.             $port = $sourceport;
  76.          }
  77. die "$0: Bad port "$sourceport"" unless ($port);
  78. $proto = getprotobyname ('tcp') || die "$0: Bad prototype tcp";
  79. $iaddr = inet_aton($server) or die "$0: no host "$server"";
  80. $paddr = sockaddr_in($port, $iaddr);
  81. socket (SOCK, PF_INET, SOCK_STREAM, $proto) or die "$0: socket error $!";
  82. connect (SOCK, $paddr) or die "$0: connect error $!";
  83. while (<SOCK>) {
  84.     push(@output, $_);
  85. }
  86. close(SOCK) || warn "$0: socket close error $!";
  87.     }
  88.     # Parse only the interesting lines. 
  89.     foreach (@output) {
  90. ($curfrm, $curto) = (split(/ +/))[2,4] if (/$mailtype/);
  91.         if (/UPTIME.*?ups*(.*?), [0-9]* user/) { 
  92.             $uptime = $1;
  93.             $uptime =~ s/:([0-9]*)/ hours, $1 minutes/;
  94.         }
  95.     }
  96.     # This line ensures no negative numbers.  See "perldoc mrtg-mailstat".
  97.     ($curfrm, $curto) = noNeg($curfrm, $curto);
  98.     return ($curfrm, $curto, $uptime);
  99. }   # End GetNewStats().
  100. # Saves the information to the log file. (Note: Overwrites old contents
  101. # which aren't needed anymore, anyway.)
  102. sub PutOldStats {
  103.     my($datafile, $frm, $to) = @_;
  104.     open(STAT, ">$datafile") || return "";
  105.     print STAT "$frm $ton";
  106.     close(STAT);
  107.     return "1";
  108. }   # End PutOldStats().
  109. # Negative values should only occur the first time the script is ever run.
  110. # These must be converted to positives so subsequent runs of the script 
  111. # correctly compute new values. 
  112. sub noNeg  { 
  113.     
  114.     my ($frm, $to) = @_;
  115.     $frm = -($frm) if ($frm < 0);
  116.     $to = -($to) if ($to < 0);
  117.     return($frm, $to);
  118. }   # End noNeg(). 
  119. # Usage() simply checks to see that no "illegal" options 
  120. # have been entered.  If the program is thus improperly 
  121. # called, it issues a notice explaining how to read the 
  122. # man page for this program.  
  123. sub Usage { 
  124.    my $option = shift; 
  125.    print STDERR "You may wish to read the documentation n";
  126.    print STDERR "(type "perldoc mrtg-mailstat" or "mrtg-mailstat -h")n";
  127.    exit(5); 
  128. } # End Usage(). 
  129. sub GetHelp { 
  130.    system("perldoc mrtg-mailstat");
  131.    exit(0);
  132. }   # End GetHelp().
  133. __END__
  134. =head1 NAME
  135. mrtg-mailstat - Mail Statistics Collector for MRTG
  136. =head1 SYNOPSIS
  137. mrtg-mailstat S<[B<-h>]> S<[B<-m> I<mailtype>]> S<[B<-p> I<sourceport>]> 
  138.               S<[B<-s> I<server>]>
  139. =head1 DESCRIPTION
  140. The B<mrtg-mailstat> program retrieves statistical information from the 
  141. mail server.  It does not matter whether the script is run on the mail 
  142. server itself, or on a machine remote from the mail server.  
  143. =head1  S<   Running mrtg-mailstat >
  144. S<                                                                        >
  145. The proper way to run B<mrtg-mailstat> is to call it from an MRTG configuration
  146. file.  The following provides an example of a valid configuration file entry: 
  147. =over 2
  148. =item 
  149. C<S<Target[smtp-mail]: `mrtg-mailstat -m smtp -p 7258 -s mail.techstop.com`>
  150. S<MaxBytes[smtp-mail]: 150                  >
  151. S<Options[smtp-mail]: gauge                 >
  152. S<Title[smtp-mail]: TechStop Support Services SMTP Mail Statistics>
  153. S<PageTop[smtp-mail]: E<lt>H1E<gt>TechStop SMTP Mail Statistics E<lt>/H1E<gt>>
  154. S<XSize[smtp-mail]: 500                     >
  155. S<YSize[smtp-mail]: 200                     >
  156. S<WithPeak[smtp-mail]: dwmy>
  157. S<YLegend[smtp-mail]: No. of messages>
  158. S<ShortLegend[smtp-mail]: messages>
  159. S<LegendI[smtp-mail]: &nbsp;Incoming:>
  160. S<LegendO[smtp-mail]: &nbsp;Outgoing: > >
  161. =back
  162. This makes certain assumptions which are outlined below under I<Dependencies>.
  163. =head1  S<   Switches >
  164. S<                                                                        >
  165. =head2  Hardcoding versus Using Switches
  166. It is not necessary to provide switches to the program, if you prefer to "hardcode"
  167. the information in the script itself.  "Hardcoding" allows you to call the script 
  168. with less (or no) flags; information needed by the script, and not provided by a 
  169. flag,  must be "hardcoded" by you before this will work.  (This was provided for 
  170. diehards who hate the flexibility of switches.  I provided enough flexibility for 
  171. them to be inflexible. ;))
  172. To "hardcode" your information into the script, look for the section near the 
  173. top of the script labeled "HARDCODING SECTION".  Change the "null" entries 
  174. represented by the double double quotes ("") so that they contain the appropriate
  175. values.  
  176. Example:  
  177. =over 4 
  178. =item 
  179. C<$server     = "" unless $server; >
  180. =back
  181. becomes  
  182. =over 4
  183. =item 
  184. C<$server     = "mail.techstop.com" unless $server; >
  185. =back
  186. As stated, this is not necessary; it is not even preferred.  You may, 
  187. and probably should, use the switches in the next subsection.  
  188. =head2  Invoking Switches
  189. B<mrtg-mailstat> switches adhere to the POSIX syntax for command-line
  190. options.  This means options can take a variety of forms.  
  191. For example, to specify running B<mrtg-mailstat> against port C<7258>
  192. of the mail server to obtain reports on smtp mail (see "I<mailtype> 
  193. under I<Available Switches> below) you could use any of the following forms:  
  194. =over 5
  195. =item    
  196. C<% mrtg-mailstat -m smtp -p 7258>
  197. =item    
  198. C<% mrtg-mailstat -m=smtp -p=7258>       
  199. =item    
  200. C<% mrtg-mailstat -mailtype smtp -port 7258> 
  201. =item    
  202. C<% mrtg-mailstat -mailtype=smtp -port=7258> 
  203. =item    
  204. C<% mrtg-mailstat --m smtp --p 7258> 
  205. =item    
  206. C<% mrtg-mailstat --m=smtp --p=7258>
  207. =item    
  208. C<% mrtg-mailstat --mailtype smtp --port 7258>  
  209. =item    
  210. C<% mrtg-mailstat --mailtype=smtp --port=7258>  
  211. =back
  212. Any of the last four forms are preferred.  One way of doing options 
  213. which is I<not> possible is: 
  214. =over 5
  215. =item    
  216. C<% mrtg-mailstat --msmtp --p7258>
  217. =back
  218. Use of that last form may cause results other than you expected. 
  219. (Important Note: The above examples would also require that the 
  220. server be "hardcoded" into the script as noted in the subsection on 
  221. I<Hardcoding versus Using Switches> above.)
  222. =head2  Available Switches
  223. The following switches are available:  
  224. =over 2
  225. =item B<--h[elp]>
  226. The B<-h> flag causes B<mrtg-mailstat> to print this manual to 
  227. standard output.  For obvious reasons, this is not normally included in an 
  228. MRTG configuration file, nor invoked by cron.  
  229. =item B<--l[ogbase]>
  230. The B<-l> flag can be used to specify the directory in which to store the 
  231. file that holds the values from each run.  By default, this file is created 
  232. in I</tmp>, but if you need to store it in another directory, this is the 
  233. flag for you.  By the way, if the file doesn't exist, one is created.  A side-effect 
  234. of this is that if you try to use one "logbase" one time, and another the next, 
  235. the program has no way of warning you.  It simply creates a new file, and uses zero 
  236. values to begin its calculations.  This can have strange consequences for your 
  237. mail statistics.  Try to remember where you store your log, or use the hardcoding 
  238. option (see I<Hardcoding versus Using Switches> above).  
  239. =item B<--m[ailtype]>
  240. The B<-m> flag is used to specify the mail type.  The two 
  241. types reported by I</usr/bin/mailstat> are "esmtp" and "local".  The 
  242. "esmtp" line reports traffic between the mail server and other systems. 
  243. The "local" line reports traffic between users on the mail server.  For 
  244. most smaller networks, this likely means that "esmtp" reports mail between 
  245. their network and the Internet, and "local" reports mail between users 
  246. within the small network's organization.  Possible values for this flag are 
  247. "smtp" and "local".  B<Note the flag takes "smtp" and not "esmtp".>
  248. =item B<--p[ort]>
  249. The B<-p> flag specifies the port whence the statistics are obtained.  See
  250. the I<Dependencies> section below.  
  251. =item B<--s[erver]>
  252. The B<-s> flag specifies the mail server.  This can be either a DNS name, 
  253. or an IP number. 
  254. =back
  255. =head1 DEPENDENCIES
  256. The B<mrtg-mailstat> program makes certain assumptions.  The following is 
  257. quoted with a few changes from the documentation for the original B<mailstat> script 
  258. upon which B<mrtg-mailstat> is based.  In particular, it is important to note that 
  259. the original instructions were Solaris-centric.  Your system may have different commands 
  260. for starting and stopping the mail server, and your paths may be different (i.e., may 
  261. use /usr/local instead of /opt, or whatever).  You are assumed to be able to figure that 
  262. out yourself.  
  263. =over 2
  264. =item 1:  Ensure you have I</bin/mailstat> (or I</usr/sbin/mailstat>)on your system.
  265. =item 2:  Enable I</var/log/sendmail.st>
  266.     To do this you can just make sure the entry for "sendmail.st" in
  267.     "sendmail.cf" is uncommented.  On the BSD/OS 3.1 system mrtg-mailstat was 
  268.     tested on, the /etc/sendmail.cf entries look like this:  
  269.     OS/var/log/sendmail.st
  270.     O StatusFile=/var/log/sendmail.st
  271.     Then do the command:
  272.         # touch /var/log/sendmail.st
  273.     And restart sendmail:
  274.         # /etc/init.d/sendmail stop
  275.         # /etc/init.d/sendmail start
  276. =item 3:  Create the following shell-script (B<Note!> This section is different than the original version!):
  277.         #!/bin/sh
  278.         #
  279.         # smtp-stats: invoke mailstats from a wrapper for use in inetd.
  280.         #
  281.         PATH=/bin:/sbin
  282.         if [ -x "/usr/sbin/mailstats" ]
  283.            then
  284.            temp1=`/usr/sbin/mailstats -f/var/log/sendmail.st`
  285.         fi
  286.         if [ -x "/usr/bin/uptime" ]
  287.            then
  288.            temp2=`/usr/bin/uptime`
  289.         fi
  290.         echo -e "$temp1nUPTIME: $temp2"
  291. I run this out of /usr/local/bin, and call it "smtp-stats"
  292. =item 4:  Now add the following to /etc/services:
  293.         # /etc/services
  294.         #
  295.         smtp-stats      7256/tcp                        # smtp-stats
  296. I used port 7256 as it was undefined.  You might like to select something
  297. else.
  298. =item 5:  Add the following to /etc/inetd.conf:
  299.         # /etc/inetd.conf
  300.         #
  301.         smtp-stats      stream  tcp     nowait root 
  302.         /usr/local/bin/smtp-stats smtp-stats
  303. ***Ensure that the above is all on *one* line.  The sample above
  304. is broken on 2 lines for legibility!!
  305. =item 6:  Restart inetd
  306. =item 7:  Test the port.  you should see the following:
  307. S<                                                       >
  308. S<unixhost:   {26} % telnet mailserver 7258              >
  309. S<Trying 192.168.1.8...                                  >
  310. S<Connected to mailserver.yourdomain.com.                >
  311. S<Escape character is '^]'.                              >
  312. S<Statistics from Wed Jan 14 03:10:34 1998               >
  313. S< M msgsfr bytes_from  msgsto   bytes_to  Mailer        >
  314. S< 3  79372    3623347K 143989    6954437K  local        >
  315. S< 5   9941     483230K   6669     652586K  esmtp        >
  316. S<========================================               >
  317. S< T  89313    4106577K 150658    7607023K               >
  318. S<UPTIME:  9:02AM  up 52 days, 48 mins, 2 users, load averages: 0.57, 0.56, 0.43>
  319. S<Connection closed by foreign host.                     >
  320. =back
  321. =head1 FILES
  322. Strictly speaking, you needn't worry about the files.  If you've created
  323. the smtp-stats script noted above, and made the appropriate changes, the 
  324. only other I<file> you need to be concerned with is B<mrtg-mailstat> itself.
  325. For completeness sake, I list all the files with which B<mrtg-mailstat> may 
  326. depend upon, utilize, create, or use.  
  327. =over 5
  328. =item 
  329. I<mrtg-mailstat>
  330. =item 
  331. I</etc/sendmail.cf>
  332. =item 
  333. I</usr/local/bin/smtp-stats>
  334. =item 
  335. I</usr/sbin/mailstats>
  336. =item 
  337. I</usr/bin/uptime>
  338. =item 
  339. I</var/log/sendmail.st>
  340. =item 
  341. I<$logbase/${mailtype}-mailstat.old>
  342. =back
  343. =head1 AUTHOR
  344. This B<mrtg-mailstat> program was written by Rick Horowitz <rick@techstop.com>, 
  345. tested, and released to the MRTG mailing list on December 16, 1998.  It was 
  346. inspired by, and contains remnants of code from: 
  347. =over 10
  348. =item
  349.             "mailstats" by Petter Reinholdtsen <pere@td.org.uit.no> 
  350.              dated 1997-07-09 and part of mrtg2.54c dist
  351. =back
  352. Petter credits Rachel Polanskis <rachel@juno.virago.org.au> for 
  353. the original. 
  354. =cut