summaryrefslogtreecommitdiff
path: root/mmuegel/libs/mqueue.pl
diff options
context:
space:
mode:
Diffstat (limited to 'mmuegel/libs/mqueue.pl')
-rw-r--r--mmuegel/libs/mqueue.pl215
1 files changed, 215 insertions, 0 deletions
diff --git a/mmuegel/libs/mqueue.pl b/mmuegel/libs/mqueue.pl
new file mode 100644
index 0000000..f425ede
--- /dev/null
+++ b/mmuegel/libs/mqueue.pl
@@ -0,0 +1,215 @@
+;# NAME
+;# mqueue.pl - functions to work with the sendmail queue
+;#
+;# DESCRIPTION
+;# Both Get_Queue_IDs and Parse_Control_File are available to get
+;# information about the sendmail queue. The cqueue program is a good
+;# example of how these functions work.
+;#
+;# AUTHOR
+;# Michael S. Muegel (mmuegel@mot.com)
+;#
+;# RCS INFORMATION
+;# mmuegel
+;# /usr/local/ustart/src/mail-tools/dist/foo/libs/mqueue.pl,v
+;# 1.1 of 1993/07/28 08:07:19
+
+package mqueue;
+
+;###############################################################################
+;# Get_Queue_IDs
+;#
+;# Will figure out the queue IDs in $Queue that have both control and data
+;# files. They are returned in @Valid_IDs. Those IDs that have a
+;# control file and no data file are saved to the array globbed by
+;# *Missing_Control_IDs. Likewise, those IDs that have a data file and no
+;# control file are saved to the array globbed by *Missing_Data_IDs.
+;#
+;# If $Skip_Locked is true they a message that has a lock file is skipped
+;# and will not show up in any of the arrays.
+;#
+;# If everything went AOK then $Status is 1; otherwise, $Status is 0 and
+;# $Msg tells what went wrong.
+;#
+;# Globals:
+;# None
+;#
+;# Arguments:
+;# $Queue, $Skip_Locked, *Missing_Control_IDs, *Missing_Data_IDs
+;#
+;# Returns:
+;# $Status, $Msg, @Valid_IDs
+;###############################################################################
+sub main'Get_Queue_IDs
+{
+ local ($Queue, $Skip_Locked, *Missing_Control_IDs,
+ *Missing_Data_IDs) = @_;
+ local (*QUEUE, @Files, %Lock_IDs, %Data_IDs, %Control_IDs, $_);
+
+ # Make sure that the * argument @arrays ar empty
+ @Missing_Control_IDs = @Missing_Data_IDs = ();
+
+ # Save each data, lock, and queue file in @Files
+ opendir (QUEUE, $Queue) || return (0, "error getting directory listing of $Queue");
+ @Files = grep (/^(df|lf|qf)/, readdir (QUEUE));
+ closedir (QUEUE);
+
+ # Create indexed list of data and control files. IF $Skip_Locked is true
+ # then skip either if there is a lock file present.
+ if ($Skip_Locked)
+ {
+ grep ((s/^lf//) && ($Lock_IDs {$_} = 1), @Files);
+ grep ((s/^df//) && (! $Lock_IDs {$_}) && ($Data_IDs {$_} = 1), @Files);
+ grep ((s/^qf//) && (! $Lock_IDs {$_}) && ($Control_IDs {$_} = 1), @Files);
+ }
+ else
+ {
+ grep ((s/^df//) && ($Data_IDs {$_} = 1), @Files);
+ grep ((s/^qf//) && ($Control_IDs {$_} = 1), @Files);
+ };
+
+ # Find missing control and data files and remove them from the lists of each
+ @Missing_Control_IDs = sort (grep ((! $Control_IDs {$_}) && (delete $Data_IDs {$_}), keys (%Data_IDs)));
+ @Missing_Data_IDs = sort (grep ((! $Data_IDs {$_} && (delete $Control_IDs {$_})), keys (%Control_IDs)));
+
+
+ # Return the IDs in an appartently random order
+ return (1, "", keys (%Control_IDs));
+};
+
+
+;###############################################################################
+;# Parse_Control_File
+;#
+;# Will pase a sendmail queue control file for useful information. See the
+;# Sendmail Installtion and Operation Guide (SMM:07) for a complete
+;# explanation of each field.
+;#
+;# The following globbed variables are set (or cleared) by this function:
+;#
+;# $Sender The sender's address.
+;#
+;# @Recipients One or more addresses for the recipient of the mail.
+;#
+;# @Errors_To One or more addresses for addresses to which mail
+;# delivery errors should be sent.
+;#
+;# $Creation_Time The job creation time in time(3) format. That is,
+;# seconds since 00:00:00 GMT 1/1/70.
+;#
+;# $Priority An integer representing the current message priority.
+;# This is used to order the queue. Higher numbers mean
+;# lower priorities.
+;#
+;# $Status_Message The status of the mail message. It can contain any
+;# text.
+;#
+;# @Headers Message headers unparsed but in their original order.
+;# Headers that span multiple lines are not mucked with,
+;# embedded \ns will be evident.
+;#
+;# In all e-mail addresses bounding <> pairs are stripped.
+;#
+;# If everything went AOK then $Status is 1. If the message with queue ID
+;# $Queue_ID just does not exist anymore -1 is returned. This is very
+;# possible and should be allowed for. Otherwise, $Status is 0 and $Msg
+;# tells what went wrong.
+;#
+;# Globals:
+;# None
+;#
+;# Arguments:
+;# $Queue, $Queue_ID, *Sender, *Recipients, *Errors_To, *Creation_Time,
+;# *Priority, *Status_Message, *Headers
+;#
+;# Returns:
+;# $Status, $Msg
+;###############################################################################
+sub main'Parse_Control_File
+{
+ local ($Queue, $Queue_ID, *Sender, *Recipients, *Errors_To, *Creation_Time,
+ *Priority, *Status_Message, *Headers) = @_;
+ local (*Control, $_, $Not_Empty);
+
+ # Required variables and the associated control. If empty at the end of
+ # parsing we return a bad status.
+ @REQUIRED_INFO = ('$Creation_Time', 'T', '$Sender', 'S', '@Recipients', 'R',
+ '$Priority', 'P');
+
+ # Open up the control file for read
+ $Control = "$Queue/qf$Queue_ID";
+ if (! open (Control))
+ {
+ return (-1) if ((-x $Queue) && (! -f "$Queue/qf$Queue_ID") &&
+ (! -f "$Queue/df$Queue_ID"));
+ return (0, "error opening $Control for read: $!");
+ };
+
+ # Reset the globbed variables just in case
+ $Sender = $Creation_Time = $Priority = $Status_Message = "";
+ @Recipients = @Errors_To = @Headers = ();
+
+ # Look for a few things in the control file
+ READ: while (<Control>)
+ {
+ $Not_Empty = 1;
+ chop;
+
+ PARSE:
+ {
+ if (/^T(\d+)$/)
+ {
+ $Creation_Time = $1;
+ }
+ elsif (/^S(<)?([^>]+)/)
+ {
+ $Sender = $2;
+ }
+ elsif (/^R(<)?([^>]+)/)
+ {
+ push (@Recipients, $2);
+ }
+ elsif (/^E(<)?([^>]+)/)
+ {
+ push (@Errors_To, $2);
+ }
+ elsif (/^M(.*)/)
+ {
+ $Status_Message = $1;
+ }
+ elsif (/^P(\d+)$/)
+ {
+ $Priority = $1;
+ }
+ elsif (/^H(.*)/)
+ {
+ $Header = $1;
+ while (<Control>)
+ {
+ chop;
+ last if (/^[A-Z]/);
+ $Header .= "\n$_";
+ };
+ push (@Headers, $Header);
+ redo PARSE if ($_);
+ last if (eof);
+ };
+ };
+ };
+
+ # If the file was empty scream bloody murder
+ return (0, "empty control file") if (! $Not_Empty);
+
+ # Yell if we could not find a required field
+ while (($Var, $Control) = splice (@REQUIRED_INFO, 0, 2))
+ {
+ eval "return (0, 'required control field $Control not found')
+ if (! $Var)";
+ return (0, "error checking \$Var: $@") if ($@);
+ };
+
+ # Everything went AOK
+ return (1);
+};
+
+1;