#! /usr/pkg/bin/perl
################################################################
###
###				imget
###
### Author:  Internet Message Group <img@mew.org>
### Created: Jan 14, 1996
### Revised: Apr 23, 2007
###

BEGIN {
    use lib '/usr/pkg/lib/perl5/vendor_perl/5.38.0';
};

$Prog = 'imget';
my $VERSION_DATE = "20161010";
my $VERSION_NUMBER = "153";
my $VERSION = "${Prog} version ${VERSION_DATE}(IM${VERSION_NUMBER})";
my $VERSION_INFORMATION = "${Prog} (IM ${VERSION_NUMBER}) ${VERSION_DATE}
Copyright (C) 1999 IM developing team
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
";

##
## Require packages
##

use IM::Config;
use IM::MsgStore;
use IM::Scan;
use IM::Util;
use integer;
use strict;
use vars qw($Prog $EXPLANATION @EnvConfig @OptConfig
	    $INSECURE $SUIDROOT
	    $opt_quiet $opt_noscan $opt_scaninboxonly $opt_form $opt_jissafe
	    $opt_width $opt_lock $opt_count $opt_keep $opt_protokeep $opt_src
	    $opt_dst $opt_mode $opt_assoc $opt_verbose $opt_buffer
	    $opt_debug $opt_help $opt_version);

##
## Environments
##

my $NNTP_processed;

$EXPLANATION = "$VERSION
get mail/news messages

Usage: $Prog [OPTIONS]
";

@EnvConfig = (
    'NNTPSERVERS;s;;' => "Default NNTP servers.",
    );

@OptConfig = (
    'src;s;;' =>
	"Message source: 'local[:path_of_mailbox]'\n" .
	"\t\t\t\t'pop[/APOP|/RPOP|/POP][:user][\@host]'\n" .
	"\t\t\t\t'imap[/AUTH|/LOGIN][:user][\@host]'\n" .
	"\t\t\t\t'imap%folder[//AUTH|//LOGIN][:user][\@host]'\n" .
	"\t\t\t\t'nntp:group[\@host]' or\n" .
	"\t\t\t\t'stdin'" ,
    'dst;s;;'    =>
	'Message destination: "+folder" or "=locally.saved.news"',
    'noscan;b;;'       => 'No scan listings',
    'scaninboxonly,o;b;;'=> 'Do not show scanned-lines if InboxFolder != dst',
    'form;s;;'	       => 'Scan format',
    'buffer;B;;'       => 'Make output data buffered',
    'jissafe;b;;'      => 'Safe manner for JIS',
    'width;i;;'        => 'Width of result for scan listings',
#   'thread;b;;'       => 'Make threads',
#   'indent;i;;'       => "Width of thread indent",
    'lock;s;flock;'    => 'Local mailbox locking style. (none,flock,file)',
    'rpath;s;append;'  => "Conversion of UNIX From line into Return-Path:\n" .
	"\t\t(append, ignore, replace)",
    'keep;i;0;'        => "Preserve messages\n" .
	"\t\t(POP: in days; 0=delete immediately, -1=preserve forever)\n" .
	"\t\t(otherwise: 0=delete immediately, non0=preserve forever)",
    'protokeep;s;UIDL;'=> "Protocol type to use for keeping messages on POP\n".
	"\t\t(UIDL, LAST, STATUS, MSGID)\n" .
	"\t\tTimed out deletion is not supported with LAST",
    'usecl;b;;Obey_CL' => "Use value of Content-Length header for delimitation".
	"\n\t\t(effective only if source of messages is local)" ,
    'count;i;;'        => 'Number of messages to be gotten in a process (NNTP)',
    'mode;s;get;'      => 'Processing mode: "get", "from" or "check"',
    'assoc;s;;'        => "Association list: dst1=src1;dst2=src2;...\n" .
	"\t\tThis overrides --dst and --src options",
    'mimedecodequoted,x;b;;' => 'Decode broken mime-encoded strings',
    'SSHServer,S;s;localhost;SSH_server'
		       => 'SSH port relay server',
    'quiet;b;;'        => 'Suppress informational messages',
    'verbose;b;;'      => 'With verbose messages',
    'debug;d;;'        => "With debug message",
    'help;b;;'         => "Display this help and exit",
    'version,V;b;;'      => "Output version information and exit",
    );

##
## Dropping root privilidge
##

if (unixp() && $> == 0 && $< != 0) {
    $SUIDROOT = 1;
    # if RPOP
    {
	require IM::TcpTransaction && import IM::TcpTransaction;
	pool_priv_sock(3);	# XXX number of sockets to be pooled
    }
    im_notice("dropping root privilidge.\n");
    $> = $<;		# drop root
    $< = $<;		# be sure not to gain root again
    $> = 0;		# try to gain root
    if ($> == 0) {	# oops, gained again
	$INSECURE = 1;
	$> = $<;	# drop root
    }
    if ($> == 0) {
	im_die("still having root privilege.\n");
    }
}

##
## Profile and option processing
##

my $selector = read_cfg_selector(\@ARGV);
init_opt(\@OptConfig);
read_env(\@EnvConfig);
read_cfg();
set_selector($selector) == 0 or exit 1 if defined($selector);
my $myinbox = inbox_folder($selector);
$opt_dst = $myinbox if ($opt_dst eq '');
my $cnf_src = $opt_src; $opt_src = '';
my $cnf_dst = $opt_dst; $opt_dst = '';
my $cnf_assoc = $opt_assoc; $opt_assoc = '';
read_opt(\@ARGV); # help?
print("${VERSION_INFORMATION}") && exit $EXIT_SUCCESS if $opt_version;
help($EXPLANATION) && exit $EXIT_SUCCESS if $opt_help;
debug_option($opt_debug) if $opt_debug;

##
## Main
##

$SIG{'ALRM'} = \&alarm_func;

if ($opt_src eq '' && $opt_dst eq '') {
    $opt_src = $cnf_src;
    $opt_dst = $cnf_dst;
    $opt_assoc = $cnf_assoc if ($opt_assoc eq '');
} else {
    $opt_src = $cnf_src if ($opt_src eq '');
    $opt_dst = $cnf_dst if ($opt_dst eq '');
}

read_petnames();

&set_scan_form($opt_form, $opt_width, $opt_jissafe);

my($assoc, $msgs);
if ($opt_assoc ne '') {
    foreach $assoc (split(';', $opt_assoc)) {
	if ($assoc =~ /(\S+)\s*=\s*(\S+)/) {
	    my($dst, $src) = ($1, $2);
	    my $m = &get_sub($src, $dst, $opt_mode, $myinbox);
	    $msgs = $m if ($m > $msgs);
	} else {
	    im_warn("invalid parameter for --assoc: $assoc.\n");
	}
    }
} else {
    $msgs = &get_sub($opt_src, $opt_dst, $opt_mode, $myinbox);
}

&nntp_close if ($NNTP_processed);

if ($msgs > 0) {
    exit $EXIT_SUCCESS;
} else {
    exit $EXIT_ERROR;
}

##
## End of Main
##

sub get_sub {
    my($src, $dst, $mode, $myinbox) = @_;
    my($msgs);

    if ($mode ne "get" && $mode ne "check" && $mode ne "from"
	&& $mode ne "skip") {
	im_die("unknown mode: $mode\n");
    }

    my $noscan = $opt_noscan ||
	($opt_scaninboxonly && ($myinbox ne $dst));

    if ($src =~ /^local/i) {
	require IM::LocalMbox && import IM::LocalMbox;
	$msgs = local_get_msg($src, $dst, $mode, $opt_lock, $noscan);
    } elsif ($src =~ /^pop/i) {
	require IM::Pop && import IM::Pop;
	$msgs = pop_get_msg($src, $dst, $mode, $noscan);
    } elsif ($src =~ /^imap/i) {
	require IM::Imap && import IM::Imap;
	$msgs = imap_get_msg($src, $dst, $mode, $opt_count, $noscan);
    } elsif ($src =~ /^nntp/i || $src =~ /^news/i) {
	require IM::Nntp && import IM::Nntp;
	$msgs = nntp_get_msg($src, $dst, $mode, $opt_count, $noscan);
        $NNTP_processed = 1;
    } elsif ($src =~ /^stdin/i) {
	process_stdin($noscan);
    } else {
	im_die("source \"$src\" is not supported.\n");
	return -1;
    }
    return $msgs;
}

sub process_stdin($) {
    my $noscan = shift;
    my @Message = ();

    while (<STDIN>) {
        push(@Message, $_);
    }

    &store_message(\@Message, $opt_dst, $noscan);
    &exec_getsbrfile($opt_dst);
}

sub alarm_func() {
#   no operation
}

### ToDo list
# code conversion
# auto refile
# filter execution

__END__

=head1 NAME

imget - get mail/news messages

=head1 SYNOPSIS

B<imget> [OPTIONS]

=head1 DESCRIPTION

The I<imget> command incorporates messages from mail/news servers.

This command is provided by IM (Internet Message).

=head1 OPTIONS

=over 5

=item I<-s, --src=STRING>

Message source: 'local[:path_of_mailbox]',
'pop[/APOP|/RPOP|/POP][:user][@host]',
'imap[[/AUTH|/LOGIN]|%folder[//AUTH|//LOGIN]][:user][@host]',
'nntp:group[@host]', or
'stdin'.

=item I<-d, --dst=STRING>

Message destination: "+folder" or "=locally.saved.news".

=item I<-n, --noscan={on,off}>

No scan listings.

=item I<-o, --scaninboxonly={on,off}>

Do not show scanned-lines if InboxFolder != dst.

=item I<-f, --form=STRING>

Scan format.  Default value is "%+5n %m%d %-14A %S || %b".

=item I<-b, --buffer={on,off}>

Make output data buffered.

=item I<-j, --jissafe={on,off}>

Safe manner for JIS.  Default value is "on".

=item I<-w, --width=NUM>

Width of result for scan listings.  Default value is 80.

=item I<-l, --lock=STRING>

Local mailbox locking style (none, flock, file).
Default value is "flock".

=item I<-r, --rpath=STRING>

Conversion of UNIX From line into Return-Path: (append, ignore, replace).
Default value is "append".

=item I<-k, --keep=NUM>

Preserve messages.  Default value is 0.

(POP: in days; 0=delete immediately, -1=preserve forever)

(otherwise: 0=delete immediately, non0=preserve forever)

=item I<-p, --protokeep=STRING>

Protocol type to use for keeping messages on POP (UIDL, LAST, STATUS, MSGID).
Timed out deletion is not supported with LAST.
Default value is "UIDL".

=item I<-u, --usecl={on,off}>

Use value of Content-Length header for delimitation.
(effective only if source of messages is local).

=item I<-c, --count=NUM>

Number of messages to be gotten in a process (NNTP).

=item I<-m, --mode=STRING>

Processing mode: "get", "from" or "check".
Default value is "get".

=item I<-a, --assoc=STRING>

Association list: dst1=src1;dst2=src2;...
This overrides --dst and --src options.

=item I<-x, --mimedecodequoted={on,off}>

Decode broken mime-encoded strings.

=item I<-S, --sshserver=SERVER>

SSH port relay server.

=item I<-q, --quiet={on,off}>

Do not show any messages.

=item I<-v, --verbose={on,off}>

Print verbose messages when running.

=item I<--debug=DEBUG_OPTION>

Print debug messages when running.

=item I<-h, --help>

Display help message and exit.

=item I<--version>

Output version information and exit.

=back

=head1 COPYRIGHT

IM (Internet Message) is copyrighted by IM developing team.
You can redistribute it and/or modify it under the modified BSD
license.  See the copyright file for more details.

=cut

### Copyright (C) 1997, 1998, 1999 IM developing team
### All rights reserved.
### 
### Redistribution and use in source and binary forms, with or without
### modification, are permitted provided that the following conditions
### are met:
### 
### 1. Redistributions of source code must retain the above copyright
###    notice, this list of conditions and the following disclaimer.
### 2. Redistributions in binary form must reproduce the above copyright
###    notice, this list of conditions and the following disclaimer in the
###    documentation and/or other materials provided with the distribution.
### 3. Neither the name of the team nor the names of its contributors
###    may be used to endorse or promote products derived from this software
###    without specific prior written permission.
### 
### THIS SOFTWARE IS PROVIDED BY THE TEAM AND CONTRIBUTORS ``AS IS'' AND
### ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
### PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE TEAM OR CONTRIBUTORS BE
### LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
### CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
### SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
### BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
### WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
### OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
### IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

### Local Variables:
### mode: perl
### End:
