summaryrefslogtreecommitdiff
path: root/mmuegel/src/cqueue
blob: f94252a9d1f1e07cdbfbe7198fbf3a9c5336e899 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#!/usr/bin/perl

# NAME
#    cqueue - check sendmail queue for problems
#
# SYNOPSIS
#    Type cqueue -usage
#
# AUTHOR
#    Michael S. Muegel <mmuegel@mot.com>
#
# RCS INFORMATION
#    mmuegel
#    /usr/local/ustart/src/mail-tools/dist/foo/src/cqueue,v 1.1 1993/07/28 08:09:02 mmuegel Exp

# So that date.pl does not yell (Domain/OS version does a ``)
$ENV{'PATH'}    = "";

# A better getopts routine
require "newgetopts.pl";
require "timespec.pl";
require "mail.pl";
require "date.pl";
require "mqueue.pl";
require "strings1.pl";
require "elapsed.pl";

($Script_Name = $0) =~ s/.*\///;
         
# Some defaults you may want to change
$DEF_TIME	= "2h";
$DEF_QUEUE      = "/usr/spool/mqueue";
$DEF_COLUMNS	= 80;
$DATE_FORMAT    = "%r %D";

# Constants that probably should not be changed
$USAGE          = "Usage: $Script_Name [ -abdms ] [ -q queue-dir ] [ -t time ] [ -u user ] [ -w width ]\n";
$VERSION        = "${Script_Name} by mmuegel; 1.1 of 1993/07/28 08:09:02";
$SWITCHES       = "abdmst:u:q:w:";
$SPLIT_EXPR	= '\s,\.@!%:';
$ADDR_PART_EXPR	= '[^!@%]+';

# Let getopts parse for switches
$Status = &New_Getopts ($SWITCHES, $USAGE);
exit (0) if ($Status == -1);
exit (1) if (! $Status);

# Check args 
die "${Script_Name}: -u only valid with -m\n" if (($opt_u) && (! $opt_m));
die "${Script_Name}: -a not valid with -t option\n" if ($opt_a && $opt_t);
$opt_u = getlogin || (getpwuid ($<))[0] || $ENV{"USER"} || die "${Script_Name}: can not determine who you are!\n" if (! $opt_u);

# Set defaults
$opt_t = "0s" if ($opt_a);
$opt_t = $DEF_TIME if ($opt_t eq "");
$opt_w = $DEF_COLUMNS if ($opt_w eq "");
$opt_q = $DEF_QUEUE if ($opt_q eq "");
$opt_s = $opt_d = 1 if (! ($opt_s || $opt_d));

# Untaint the users to mail to
$opt_u =~ /^(.*)$/;
$Users = $1;

# Convert time option to seconds and seconds to elapsed form
die "${Script_Name}: $Msg\n" if (! (($Status, $Msg, $Seconds) = &Time_Spec_To_Seconds ($opt_t))[0]);
$Elapsed = &Seconds_To_Elapsed ($Seconds, 1);
$Time_Info = " longer than $Elapsed" if ($Seconds);

# Get the current time
$Current_Time = time;
$Current_Date = &date ($Current_Time, $DATE_FORMAT);

($Status, $Msg, @Queue_IDs) = &Get_Queue_IDs ($opt_q, 1, @Missing_Control_IDs,
   @Missing_Data_IDs);
die "$Script_Name: $Msg\n" if (! $Status);

# Yell about missing data/control files?
if ($opt_b)
{

   $Report = "\nMessages missing control files:\n\n   " . 
             join ("\n   ", @Missing_Control_IDs) . 
             "\n" 
      if (@Missing_Control_IDs);

   $Report .= "\nMessages missing data files:\n\n   " . 
              join ("\n   ", @Missing_Data_IDs) . 
              "\n"
      if (@Missing_Data_IDs);
};

# See if any mail messages are older than $Seconds
foreach $Queue_ID (@Queue_IDs)
{
   # Get lots of info about this sendmail message via the control file
   ($Status, $Msg) = &Parse_Control_File ($opt_q, $Queue_ID, *Sender, 
      *Recipients, *Errors_To, *Creation_Time, *Priority, *Status_Message, 
      *Headers);
   next if ($Status == -1);
   if (! $Status)
   {
      warn "$Script_Name: $Queue_ID: $Msg\n";
      next;
   };

   # Report on message if it is older than $Seconds
   if ($Current_Time - $Creation_Time >= $Seconds)
   {
      # Build summary by host information. Keep track of each host destination
      # encountered.
      if ($opt_s)
      {
         %Host_Map = ();
         foreach (@Recipients)
         {
	    if ((/@($ADDR_PART_EXPR)$/) || (/($ADDR_PART_EXPR)!$ADDR_PART_EXPR$/))
            {
	       ($Host = $1) =~ tr/A-Z/a-z/;
               $Host_Map {$Host} = 1;
	    }
	    else
	    {
	       warn "$Script_Name: could not find host part from $_; contact author\n";
	    };
         };

         # For each unique target host add to its stats
         grep ($Host_Queued {$_}++, keys (%Host_Map));

         # Build summary by message information.
         $Message_Queued {$Status_Message}++ if ($Status_Message);
      };

      # Build long report information for this creation time (there may be
      # more than one message created at the same time)
      if ($opt_d)
      {
         $Creation_Date = &date ($Creation_Time, $DATE_FORMAT);
         $Recipient_Info = &Format_Text_Block (join (", ", @Recipients), 
	    "   Recipient: ", 1, 0, $opt_w, $SPLIT_EXPR);
         $Time_To_Report {$Creation_Time} .= <<"EOS";

   ID:        $Queue_ID
   Date:      $Creation_Date
   Sender:    $Sender
$Recipient_Info
EOS

         # Add the status message if available to long report
         if ($Status_Message)
         {
	    $Time_To_Report {$Creation_Time} .= &Format_Text_Block ($Status_Message, 
   	       "   Status:    ", 1, 0, $opt_w, $SPLIT_EXPR) . "\n";
         };
      };
   };

};

# Add the summary report by target host?
if ($opt_s)
{
   foreach $Host (sort (keys (%Host_Queued)))
   {
      $Host_Report .= &Format_Text_Block ($Host, 
         sprintf ("   %-9d   ", $Host_Queued{$Host}), 1, 0, $opt_w,
         $SPLIT_EXPR) . "\n";
      $Num_Hosts += $Host_Queued{$Host};
   };
   if ($Host_Report)
   {
      chop ($Host_Report);
      $Report .= &Format_Text_Block("\nSummary of messages in queue$Time_Info by destination host:\n", "", 0, 0, $opt_w);

      $Report .= <<"EOS";

   Number of
   Messages    Destination Host
   ---------   ----------------
$Host_Report
   ---------
   $Num_Hosts
EOS
   };
};

# Add the summary by message report?
if ($opt_s)
{
   foreach $Message (sort (keys (%Message_Queued)))
   {
      $Message_Report .= &Format_Text_Block ($Message, 
         sprintf ("   %-9d   ", $Message_Queued{$Message}), 1, 0, $opt_w, 
         $SPLIT_EXPR) . "\n";
      $Num_Messages += $Message_Queued{$Message};
   };
   if ($Message_Report)
   {
      chop ($Message_Report);
      $Report .= &Format_Text_Block ("\nSummary of messages in queue$Time_Info by status message:\n", "", 0, 0, $opt_w);

      $Report .= <<"EOS";

   Number of
   Messages    Status Message
   ---------   --------------
$Message_Report
   ---------
   $Num_Messages
EOS
   };
};

# Add the detailed message reports?
if ($opt_d)
{
   foreach $Time (sort { $a <=> $b} (keys (%Time_To_Report)))
   {
      $Report .= &Format_Text_Block ("\nDetail of messages in queue$Time_Info sorted by creation date:\n","", 0, 0, $opt_w) if (! $Detailed_Header++);
      $Report .= $Time_To_Report {$Time};
   };
};

# Now mail or print the report
if ($Report)
{
   $Report .= "\n";
   if ($opt_m)
   {
      ($Status, $Msg) = &Send_Mail ($Users, "sendmail queue report for $Current_Date", $Report, 0);
      die "${Script_Name}: $Msg" if (! $Status);
   }

   else
   {
      print $Report;
   };

};

# I am outta here...
exit (0);