sub process_file()

in git-send-email.perl [1741:1994]


sub process_file {
	my ($t) = @_;

	open my $fh, "<", $t or die sprintf(__("can't open file %s"), $t);

	my $author = undef;
	my $sauthor = undef;
	my $author_encoding;
	my $has_content_type;
	my $body_encoding;
	my $xfer_encoding;
	my $has_mime_version;
	@to = ();
	@cc = ();
	@xh = ();
	my $input_format = undef;
	my @header = ();
	$subject = $initial_subject;
	$message = "";
	$message_num++;
	# First unfold multiline header fields
	while(<$fh>) {
		last if /^\s*$/;
		if (/^\s+\S/ and @header) {
			chomp($header[$#header]);
			s/^\s+/ /;
			$header[$#header] .= $_;
	    } else {
			push(@header, $_);
		}
	}
	# Now parse the header
	foreach(@header) {
		if (/^From /) {
			$input_format = 'mbox';
			next;
		}
		chomp;
		if (!defined $input_format && /^[-A-Za-z]+:\s/) {
			$input_format = 'mbox';
		}

		if (defined $input_format && $input_format eq 'mbox') {
			if (/^Subject:\s+(.*)$/i) {
				$subject = $1;
			}
			elsif (/^From:\s+(.*)$/i) {
				($author, $author_encoding) = unquote_rfc2047($1);
				$sauthor = sanitize_address($author);
				next if $suppress_cc{'author'};
				next if $suppress_cc{'self'} and $sauthor eq $sender;
				printf(__("(mbox) Adding cc: %s from line '%s'\n"),
					$1, $_) unless $quiet;
				push @cc, $1;
			}
			elsif (/^To:\s+(.*)$/i) {
				foreach my $addr (parse_address_line($1)) {
					printf(__("(mbox) Adding to: %s from line '%s'\n"),
						$addr, $_) unless $quiet;
					push @to, $addr;
				}
			}
			elsif (/^Cc:\s+(.*)$/i) {
				foreach my $addr (parse_address_line($1)) {
					my $qaddr = unquote_rfc2047($addr);
					my $saddr = sanitize_address($qaddr);
					if ($saddr eq $sender) {
						next if ($suppress_cc{'self'});
					} else {
						next if ($suppress_cc{'cc'});
					}
					printf(__("(mbox) Adding cc: %s from line '%s'\n"),
						$addr, $_) unless $quiet;
					push @cc, $addr;
				}
			}
			elsif (/^Content-type:/i) {
				$has_content_type = 1;
				if (/charset="?([^ "]+)/) {
					$body_encoding = $1;
				}
				push @xh, $_;
			}
			elsif (/^MIME-Version/i) {
				$has_mime_version = 1;
				push @xh, $_;
			}
			elsif (/^Message-Id: (.*)/i) {
				$message_id = $1;
			}
			elsif (/^Content-Transfer-Encoding: (.*)/i) {
				$xfer_encoding = $1 if not defined $xfer_encoding;
			}
			elsif (/^In-Reply-To: (.*)/i) {
				if (!$initial_in_reply_to || $thread) {
					$in_reply_to = $1;
				}
			}
			elsif (/^References: (.*)/i) {
				if (!$initial_in_reply_to || $thread) {
					$references = $1;
				}
			}
			elsif (!/^Date:\s/i && /^[-A-Za-z]+:\s+\S/) {
				push @xh, $_;
			}
		} else {
			# In the traditional
			# "send lots of email" format,
			# line 1 = cc
			# line 2 = subject
			# So let's support that, too.
			$input_format = 'lots';
			if (@cc == 0 && !$suppress_cc{'cc'}) {
				printf(__("(non-mbox) Adding cc: %s from line '%s'\n"),
					$_, $_) unless $quiet;
				push @cc, $_;
			} elsif (!defined $subject) {
				$subject = $_;
			}
		}
	}
	# Now parse the message body
	while(<$fh>) {
		$message .=  $_;
		if (/^([a-z][a-z-]*-by|Cc): (.*)/i) {
			chomp;
			my ($what, $c) = ($1, $2);
			# strip garbage for the address we'll use:
			$c = strip_garbage_one_address($c);
			# sanitize a bit more to decide whether to suppress the address:
			my $sc = sanitize_address($c);
			if ($sc eq $sender) {
				next if ($suppress_cc{'self'});
			} else {
				if ($what =~ /^Signed-off-by$/i) {
					next if $suppress_cc{'sob'};
				} elsif ($what =~ /-by$/i) {
					next if $suppress_cc{'misc-by'};
				} elsif ($what =~ /Cc/i) {
					next if $suppress_cc{'bodycc'};
				}
			}
			if ($c !~ /.+@.+|<.+>/) {
				printf("(body) Ignoring %s from line '%s'\n",
					$what, $_) unless $quiet;
				next;
			}
			push @cc, $c;
			printf(__("(body) Adding cc: %s from line '%s'\n"),
				$c, $_) unless $quiet;
		}
	}
	close $fh;

	push @to, recipients_cmd("to-cmd", "to", $to_cmd, $t)
		if defined $to_cmd;
	push @cc, recipients_cmd("cc-cmd", "cc", $cc_cmd, $t)
		if defined $cc_cmd && !$suppress_cc{'cccmd'};

	if ($broken_encoding{$t} && !$has_content_type) {
		$xfer_encoding = '8bit' if not defined $xfer_encoding;
		$has_content_type = 1;
		push @xh, "Content-Type: text/plain; charset=$auto_8bit_encoding";
		$body_encoding = $auto_8bit_encoding;
	}

	if ($broken_encoding{$t} && !is_rfc2047_quoted($subject)) {
		$subject = quote_subject($subject, $auto_8bit_encoding);
	}

	if (defined $sauthor and $sauthor ne $sender) {
		$message = "From: $author\n\n$message";
		if (defined $author_encoding) {
			if ($has_content_type) {
				if ($body_encoding eq $author_encoding) {
					# ok, we already have the right encoding
				}
				else {
					# uh oh, we should re-encode
				}
			}
			else {
				$xfer_encoding = '8bit' if not defined $xfer_encoding;
				$has_content_type = 1;
				push @xh,
				  "Content-Type: text/plain; charset=$author_encoding";
			}
		}
	}
	$xfer_encoding = '8bit' if not defined $xfer_encoding;
	($message, $xfer_encoding) = apply_transfer_encoding(
		$message, $xfer_encoding, $target_xfer_encoding);
	push @xh, "Content-Transfer-Encoding: $xfer_encoding";
	unshift @xh, 'MIME-Version: 1.0' unless $has_mime_version;

	$needs_confirm = (
		$confirm eq "always" or
		($confirm =~ /^(?:auto|cc)$/ && @cc) or
		($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1));
	$needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc);

	@to = process_address_list(@to);
	@cc = process_address_list(@cc);

	@to = (@initial_to, @to);
	@cc = (@initial_cc, @cc);

	if ($message_num == 1) {
		if (defined $cover_cc and $cover_cc) {
			@initial_cc = @cc;
		}
		if (defined $cover_to and $cover_to) {
			@initial_to = @to;
		}
	}

	my $message_was_sent = send_message();
	if ($message_was_sent == -1) {
		do_edit($t);
		return 0;
	}

	# set up for the next message
	if ($thread) {
		if ($message_was_sent &&
		  ($chain_reply_to || !defined $in_reply_to || length($in_reply_to) == 0 ||
		  $message_num == 1)) {
			$in_reply_to = $message_id;
			if (length $references > 0) {
				$references .= "\n $message_id";
			} else {
				$references = "$message_id";
			}
		}
	} elsif (!defined $initial_in_reply_to) {
		# --thread and --in-reply-to manage the "In-Reply-To" header and by
		# extension the "References" header. If these commands are not used, reset
		# the header values to their defaults.
		$in_reply_to = undef;
		$references = '';
	}
	$message_id = undef;
	$num_sent++;
	if (defined $batch_size && $num_sent == $batch_size) {
		$num_sent = 0;
		$smtp->quit if defined $smtp;
		undef $smtp;
		undef $auth;
		sleep($relogin_delay) if defined $relogin_delay;
	}

	return 1;
}