#!/usr/bin/perl -w

# Copyright 2008 Andres Mejia
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
# A copy of the GPL version 3 is found in Debian systems under
# /usr/share/common-licenses/GPL-3.

# We always want to be careful about things.
use strict;
use warnings;

# Various modules to use
use LWP::UserAgent; # Needed for downloading files and proxy support.
use Getopt::Long; # Needed for retrieving options.
use File::Temp qw/ tempfile tempdir /; # For temporary files and directories.
use File::Path 'rmtree'; # Needed for removing directories recursively.
use File::Copy; # Needed for copying files.
use File::Basename; # Used in retrieving the basename/dirname of a file.
use File::Glob ':glob'; # Needed for selecting specific files from a directory.
use Compress::Zlib; # Needed for compressing files in gzip format.
use Digest::MD5; # Needed to verify MD5 checksums.
use Time::HiRes qw ( time ); # Needed for high resolution timers

# Determine the architecture we're in.
my $arch = `/usr/bin/dpkg --print-architecture`;
chomp $arch;

# Write constant variables here for downloading the NVIDIA Cg Toolkit and spec
# file.
my @CG_LIBRARIES = ('libCg.so', 'libCgGL.so');
my $CG_URL = 'http://developer.download.nvidia.com/cg/Cg_2.1/2.1.0017/';
my $CG_SPEC_FILE = 'Cg-2.1_February2009_LanguageSpecification.pdf';
my $CG_SPEC_MD5 = 'f10b74966b3eafb344fb49bf29921647';
my $CG_FILE; # Determine for system architecture.
my $CG_MD5; # Determine for system architecture.
my $CG_USR_LIB; # Determine for system architecture.
if ($arch =~ m/^i386$/) {
    $CG_FILE = 'Cg-2.1_February2009_x86.tgz';
    $CG_MD5  = '8752286743ddd9d5997e698714fcc556';
    $CG_USR_LIB = '/usr/lib';
} elsif ($arch =~ m/^amd64$/) {
    $CG_FILE = 'Cg-2.1_February2009_x86_64.tgz';
    $CG_MD5  = '01a3d1e0936c3f221ede5b6bfd8d2e0c';
    $CG_USR_LIB = '/usr/lib64';
} else {
    die "Error: architecture $arch is not supported.\n";
}

# Use an array to hold the file paths of all files installed by this script.
my @manifest;
# Keep track of the combined total size of all files installed by this script.
my $total_size = 0;

# This next block of code is used to determine the options that were specified
# on the command line.
my $help; # Display help message
my $install; # Install NVIDIA Cg Toolkit and Spec File
my $uninstall; # Uninstall NVIDIA Cg Toolkit and Spec File
my $remove_cache; # Remove NVIDIA Cg Toolkit and Spec File from cache directory
my $toolkit_file; # Use a toolkit file as the NVIDIA Cg Toolkit
my $spec_file; # Use spec file as the Spec File
my $search_path; # Specify a search path
my $delete_after; # Delete any retrieved files once they are installed
my $proxy; # Specify a proxy URL to use
my $no_proxy; # Disable use of a proxy
my $generate_manifest; # Generate a manifest file
GetOptions ('h|help!' => \$help,
            'i|install!' => \$install,
            'u|uninstall!' => \$uninstall,
            'r|remove-cache!' => \$remove_cache,
            't|toolkit-file=s' => \$toolkit_file,
            's|spec-file=s' => \$spec_file,
            'p|search-path=s' => \$search_path,
            'd|delete-after!' => \$delete_after,
            'proxy=s' => \$proxy,
            'no-proxy!' => \$no_proxy,
            'generate-manifest!' => \$generate_manifest);

# This method prints the options available for this program
sub help {
print "
Usage: nvidia-cg-toolkit-installer [options] <file or URL>

Options:
  -h, --help            show this help message and exit
  -i, --install         install the NVIDIA Cg Toolkit
  -u, --uninstall       uninstall the NVIDIA Cg Toolkit
  -t TOOLKIT_FILE, --toolkit-file TOOLKIT_FILE
                        install from given toolkit archive file
  -s SPEC_FILE, --spec-file SPEC_FILE
                        install from given spec file
  -p SEARCH_PATH, --search-path SEARCH_PATH
                        search for files in given path
  -d, --delete-after    remove toolkit and spec file after install
  --proxy PROXY_URL     specify a proxy to use
  --no-proxy            disable any use of a proxy (overrides --proxy)
  --generate-manifest   Generate a manifest showing where files are installed.
"; exit 1;
}

# This method is used to retrieve a file, usually from a location on the
# Internet, but it can also be used for files in the local system.
sub download {
    # The parameters will be any URL and a location to save the file to.
    my($url, $file) = @_;
    print "Downloading $url on the $arch architecture.\n";

    # Setup the user agent.
    my $ua = LWP::UserAgent->new;

    # Determine if we need to specify any proxy settings.
    $proxy = getProxy();
    if ($proxy) {
        $ua->proxy(['http', 'ftp'], $proxy);
    }

    # Download the file.
    my $expected_length; # Total size we expect of content
    my $bytes_received = 0; # Size of content as it is received
    my $percent; # The percentage downloaded
    my $tick; # Used for counting.
    my $start_time = time; # Record of the start time
    open(FILE, '>', $file); # Destination file to download content to
    my $response = $ua->get($url, ":content_cb" =>
        sub {
            my ($chunk, $response) = @_;

            $bytes_received += length($chunk);
            unless (defined $expected_length) {
                $expected_length = $response->content_length or undef;
            }
            if ($expected_length) {
                # Here we calculate the speed of the download to print out later
                my $speed;
                my $duration = time - $start_time;
                if ($bytes_received/$duration >= 1024 * 1024) {
                    $speed = sprintf("%.3g MB",
                        ($bytes_received/$duration) / (1024.0 * 1024)) . "/s";
                } elsif ($bytes_received/$duration >= 1024) {
                    $speed = sprintf("%.3g KB",
                        ($bytes_received/$duration) / 1024.0) . "/s";
                } else {
                    $speed = $bytes_received/$duration . " bytes/s";
                }
                # Calculate the percentage downloaded
                $percent = sprintf("%d",
                    100 * $bytes_received / $expected_length);
                $tick++; # Keep count
                # Here we print out a progress of the download. We start by
                # printing out the amount of data retrieved so far, and then
                # show a progress bar. After 50 ticks, the percentage is printed
                # and the speed of the download is printed. A new line is
                # started and the process repeats until the download is
                # complete.
                if (($tick == 250) or ($percent == 100)) {
                    print STDERR ".]";
                    printf STDERR "%5s", "$percent%";
                    printf STDERR "%12s", "$speed\n";
                    $tick = 0;
                } elsif ($tick == 1) {
                    printf STDERR "%8s", sprintf("%d",
                        $bytes_received / 1024) . "KB";
                    print STDERR " [.";
                } elsif ($tick % 5 == 0) {
                    print STDERR ".";
                }
            }
            # Write the contents of the download to our specified file
            if ($response->is_success) {
                print FILE $chunk; # Print content to file
            } else {
                # Print message upon failure during download
                print STDERR "\n" . $response->status_line . "\n";
                return undef;
            }
        }
    ); # Our GET request
    close FILE; # Close the destination file

    # Print error message in case we couldn't get a response at all.
    if (!$response->is_success) {
        print $response->status_line . "\n";
        return undef;
    }

    # At this point, the download should have been successful. Print a success
    # message and return true.
    print "Download successful.\n";
    print "Total size of content downloaded: " .
        sprintf("%d", $bytes_received/1024) . "KB\n";
    return 1;
}

# This method is used to determine the proxy settings used on the local system.
# It will return the proxy URL if a proxy setting is found.
sub getProxy {
    # Determine if a proxy is going to be used at all
    if ($no_proxy) {
        return undef;
    }

    # Determine if the proxy option was specified in the command line.
    # If it was, return it.
    if ($proxy) {
        return $proxy;
    }

    # Attempt to acquire a proxy URL from apt-config.
    if (open(APT_CONFIG, "apt-config dump |")) {
        my @apt_config = <APT_CONFIG>;
        close(APT_CONFIG);
        foreach my $tmp (@apt_config) {
            if ($tmp =~ m/^.*Acquire::http::Proxy\s+/) {
                $proxy = $tmp;
                chomp($proxy);
                # Trim the line to only the proxy URL
                $proxy =~ s/^.*Acquire::http::Proxy\s+"|";$//g;
                return $proxy;
            }
        }
    }

    # Attempt to acquire a proxy URL from the user's or system's wgetrc
    # configuration.
    # First try the user's wgetrc
    if (open(WGETRC, '<', "$ENV{'HOME'}/.wgetrc")) {
        my @wgetrc = <WGETRC>;
        close(WGETRC);
        foreach my $tmp (@wgetrc) {
            if ($tmp =~ m/^[^#]*http_proxy/) {
                $proxy = $tmp;
                chomp($proxy);
                # Trim the line to only the proxy URL
                $proxy =~ s/^.*http_proxy\s*=\s*|\s+$//g;
                return $proxy;
            }
        }
    }
    # Now try the system's wgetrc
    if (open(WGETRC, '<', '/etc/wgetrc')) {
        my @wgetrc = <WGETRC>;
        close(WGETRC);
        foreach my $tmp (@wgetrc) {
            if ($tmp =~ m/^[^#]*http_proxy/) {
                $proxy = $tmp;
                chomp($proxy);
                # Trim the line to only the proxy URL
                $proxy =~ s/^.*http_proxy\s*=\s*|\s+$//g;
                return $proxy;
            }
        }
    }

    # At this point there should be no proxy settings. Return undefined.
    return undef;
}

# This method is used to search for the NVIDIA Cg Toolkit and the Spec File in a
# given path. It tests whether the the files reside in the search path and
# whether they are readable. If so, it assigns the path to the files to the
# appropriate variable.
sub search {
    if (-r $search_path . $CG_FILE) {
        $toolkit_file = $search_path . $CG_FILE;
    }
    if (-r $search_path . $CG_SPEC_FILE) {
        $spec_file = $search_path . $CG_SPEC_FILE;
    }
}

# This method is used to copy files and directories to a new location
sub copyUtil {
    # The parameters are the original source and the destination to copy the
    # source to. There's also a parameter that's used to compress files that are
    # bigger than the parameter taken in (in bytes).
    my($orig, $new, $compress_size) = @_;

    # For directories, ensure that the directory actually exists in the
    # destination and copy the contents of the directory by recursively calling
    # this method.
    if (-d $orig) {
        if (! -d $new) { # Make directories if necessary
            mkdir($new);
            # Directories will show up with slashes at the end in the manifest.
            push(@manifest, $new . '/');
            $total_size = $total_size + (stat($new))[7]; # Add to size
        }
        opendir(DIR, $orig) or die "Couldn't open $orig: $!";
        foreach my $tmp (grep(!/^\.{1,2}$/, readdir(DIR))) {
            copyUtil($orig . '/' . $tmp, $new . '/' . $tmp, $compress_size);
        }
	# FIXME: Is this call needed? It raise some errors and we're about
	# to exit anyway. We're an installer script after all.
        #closedir DIR;
    } else {
        # Use copy() for regular files. Compress files if they are bigger than
        # the specified size.
        if (($compress_size) and ($compress_size < (stat($orig))[7])) {
            my $compress_orig = gzipCompress($orig);
            if (!copy($compress_orig, $new . '.gz')) {
                my $msg = "Failed to copy file $compress_orig to ";
                $msg .= $new . '.gz' . ": $!";
                die $msg;
            }
            push(@manifest, $new . '.gz'); # Add to manifest
            $total_size = $total_size + (stat($new . '.gz'))[7]; # Add to size
        } else {
            copy($orig, $new) or
                die "Failed to copy file $orig to $new: $!";
            push(@manifest, $new); # Add to manifest
            $total_size = $total_size + (stat($new))[7]; # Add to size
        }
    }
}

# This method will check any data for its MD5 checksum and compare it to one
# that is provided. If they match, it returns true, else it returns false.
sub verifyMD5 {
    # The parameters are any data and the MD5 that is supposed to be correct.
    my($data, $correct_md5) = @_;

    # Open the data and read it as a binary (or text if applicable).
    open(DATA, $data) or die "Can't open '$data': $!";
    binmode(DATA);

    # Check if the computed MD5 matches the correct MD5 and return an
    # appropriate value.
    if (Digest::MD5->new->addfile(*DATA)->hexdigest eq $correct_md5) {
        close DATA;
        return 1;
    } else {
        close DATA;
        return undef;
    }
}

# This method is used to compress any file in gzip format. This returns the name
# of a temporary file that will be the compressed file of a file taken in as a
# parameter. The idea is to use this method to return the file path of a
# compressed file for use with the copyUtil() method.
sub gzipCompress {
    my($file) = @_;

    # Create a temporary file and open it for creating the compressed file.
    my($tmpfile, $tmpfilename) = tempfile(UNLINK => 1, SUFFIX => '.gz');
    my $gz = gzopen($tmpfile, 'wb9');
    if (!$gz) {
        die "Couldn't initialize compression library: $gzerrno";
    }

    # Attempt to open the file.
    if (!open(SOURCE, '<', $file)) {
        die "Couldn't open source file $file: $!";
    }

    # Read the contents of the file and write them to the compressed file.
    while (1) {
        my $buffer;
        my $bytesread = read SOURCE, $buffer, 4096;
        if (!defined $bytesread) {
            close SOURCE;
            die "Error reading from '$file': $!";
        }
        last if $bytesread == 0;
        my $byteswritten = $gz->gzwrite($buffer);
        if ($byteswritten < $bytesread) {
            close SOURCE;
            die "Error gzwriting to temporary file: " . $gz->gzerror;
        }
    }

    # Flush all pending output to the compressed file and ensure that no errors
    # occurred.
    my $gzflush = $gz->gzflush(Z_FINISH);
    if (($gzflush != Z_OK) and ($gzflush != Z_STREAM_END)) {
        close SOURCE;
        die "Error flushing compressed file: " . $gz->gzerror;
    }

    # Close the file and compressed file and return the path of the compressed
    # file.
    close SOURCE;
    $gz->gzclose;
    return $tmpfilename;
}

# This method is used to install the NVIDIA Cg Toolkit and the Spec File.
sub install {
    # If a search path was given, do a search
    if ($search_path) {
        search();
    }
    # If the files are not in a given search path and are not specified in the
    # options, look inside to cache to see if they're there, else download them.
    if (!$toolkit_file) {
        (undef, $toolkit_file) = tempfile(SUFFIX => '.tar.gz', UNLINK => 1);
        if ((-r '/var/cache/nvidia-cg-toolkit/' . $CG_FILE) and
                (!$remove_cache)) {
            print STDERR "Using '" . '/var/cache/nvidia-cg-toolkit/' .
                $CG_FILE . "'\n";
            $toolkit_file = '/var/cache/nvidia-cg-toolkit/' . $CG_FILE;
        } else {
            download($CG_URL . $CG_FILE, $toolkit_file) or
                die "Failed to download NVIDIA Cg Toolkit.\n";
        }
    }
    if (!$spec_file) {
        (undef, $spec_file) = tempfile(SUFFIX => '.pdf', UNLINK => 1);
        if ((-r '/var/cache/nvidia-cg-toolkit/' . $CG_SPEC_FILE) and
                (!$remove_cache)) {
            print STDERR "Using '" . '/var/cache/nvidia-cg-toolkit/' .
                $CG_SPEC_FILE . "'\n";
            $spec_file = '/var/cache/nvidia-cg-toolkit/' . $CG_SPEC_FILE;
        } else {
            download($CG_URL . $CG_SPEC_FILE, $spec_file) or
                die "Failed to download NVIDIA Cg Toolkit spec file.\n";
        }
    }
    # Verify that the MD5 checksums are correct.
    print STDERR "Checking MD5 sum for NVIDIA Cg Toolkit file...";
    if (!verifyMD5($toolkit_file, $CG_MD5)) {
        print STDERR "failed.\n";
        my $msg = "Checksum mismatch. Expected checksum $CG_MD5 for the ";
        $msg .= "NVIDIA Cg Toolkit file.\n";
        die $msg;
    } else {
        print STDERR "passed.\n";
    }
    print STDERR "Checking MD5 sum for NVIDIA Cg Toolkit spec file...";
    if (!verifyMD5($spec_file, $CG_SPEC_MD5)) {
        print STDERR "failed.\n";
        my $msg = "Checksum mismatch. Expected checksum $CG_SPEC_MD5 for the ";
        $msg .= "NVIDIA Cg Toolkit spec file.\n";
        die $msg;
    } else {
        print STDERR "passed.\n";
    }

    # Uninstall the components of the NVIDIA Cg Toolkit before attempting to
    # install.
    uninstall();

    # Unpack the contents of the toolkit tarball into a temporary directory.
    # Here we simply use '/bin/tar' as opposed to 'Archive::Tar'.
    my $tempdir = tempdir( CLEANUP => 1 );
    print "Uncompressing NVIDIA Cg Toolkit.\n";
    system('/bin/tar', 'xzf', $toolkit_file, '-C', $tempdir) eq 0 or
        die "Uncompressing NVIDIA Cg Toolkit failed: $!";

    # Start installing the files
    print STDERR "Installing NVIDIA Cg Toolkit components: ";

    # Install the Cg compiler.
    print STDERR "Cg compiler, ";
    copyUtil($tempdir . '/usr/bin/cgc', '/usr/bin/cgc');
    chmod 0755, '/usr/bin/cgc';

    # Install the NVIDIA Cg Toolkit header files.
    print STDERR "header files, ";
    copyUtil($tempdir. '/usr/include/Cg', '/usr/include/Cg');

    # Install the NVIDIA Cg Toolkit libraries.
    print STDERR "libraries, ";
    foreach my $tmp (@CG_LIBRARIES) {
        copyUtil($tempdir . $CG_USR_LIB . '/' . $tmp, $CG_USR_LIB . '/' . $tmp);
    }

    # Install documentation for the NVIDIA Cg Toolkit including the spec file.
    # Here we pass the compression size parameter to compress files bigger than
    # 4kb (512B).
    print STDERR "documentation, ";
    foreach my $tmp (<$tempdir/usr/local/Cg/docs/*.pdf>) {
        copyUtil($tmp,
            '/usr/share/doc/nvidia-cg-toolkit/' . fileparse($tmp), 512);
    }
    copyUtil($tempdir . '/usr/local/Cg/README',
        '/usr/share/doc/nvidia-cg-toolkit/README', 512);
    copyUtil($tempdir . '/usr/local/Cg/docs/html',
        '/usr/share/doc/nvidia-cg-toolkit/html');
    copyUtil($spec_file, '/usr/share/doc/nvidia-cg-toolkit/' . $CG_SPEC_FILE,
        512);

    # Install examples for the NVIDIA Cg Toolkit.
    print STDERR "examples, ";
    copyUtil($tempdir . '/usr/local/Cg/examples',
        '/usr/share/doc/nvidia-cg-toolkit/examples');

    # Install manual pages for the NVIDIA Cg Toolkit. We compress the manual
    # pages first before installing them.
    print STDERR "manual pages, ";
    foreach my $tmp (<$tempdir/usr/share/man/man3/*>) {
        copyUtil(gzipCompress($tmp),
            '/usr/share/man/man3/' . fileparse($tmp) . 'Cg.gz');
    }
    foreach my $tmp (<$tempdir/usr/share/man/manCg/*>) {
        my $tmpname = fileparse($tmp);
        $tmpname =~ s/Cg$//; # Takes out 'Cg' extension in file name.
        copyUtil(gzipCompress($tmp),
            '/usr/share/man/man3/' . $tmpname . '3Cg.gz');
    }

    # Run ldconfig.
    print STDERR "(running ldconfig), ";
    system('/sbin/ldconfig') eq 0 or die "ldconfig processing failed: $!";

    # Copy toolkit and spec file into cache if they're not already there
    if ( ! -r '/var/cache/nvidia-cg-toolkit/' . $CG_FILE ) {
        print STDERR "saving toolkit to cache, ";
        copyUtil($toolkit_file, '/var/cache/nvidia-cg-toolkit/' . $CG_FILE);
    }
    if ( ! -r '/var/cache/nvidia-cg-toolkit/' . $CG_SPEC_FILE ) {
        print STDERR "saving spec file to cache, ";
        copyUtil($spec_file, '/var/cache/nvidia-cg-toolkit/' . $CG_SPEC_FILE);
    }

    # We're done installing.
    print STDERR "done.\n";

    # Generate a manifest file if it was requested.
    if ($generate_manifest) {
        @manifest = sort(@manifest); # Sort manifest
        open (MANIFEST, '>', '/tmp/nvidia-cg-toolkit-manifest');
        print MANIFEST "Manifest for nvidia-cg-toolkit $arch package.\n";
        # Convert total size from bytes to kilobytes.
        my $msg = "Combined total size of all files installed is ";
        $msg .= sprintf("%.0f", $total_size/1024) ." KB.\n\n";
        print MANIFEST $msg;
        foreach my $tmp (@manifest) {
            print MANIFEST "$tmp\n";
        }
        close MANIFEST;
    }

    # Delete the NVIDIA Cg Toolkit and the spec file if it was requested to do
    # so.
    if ($delete_after) {
        if (dirname($toolkit_file) !~ m|\Q/var/cache/nvidia-cg-toolkit\E|g) {
            unlink $toolkit_file;
        }
        if (dirname($spec_file) !~ m|\Q/var/cache/nvidia-cg-toolkit\E|g) {
            unlink $spec_file;
        }
    }
}

# This method is used to uninstall the NVIDIA Cg Toolkit and the Spec File.
sub uninstall {
    # Start uninstalling the files.
    print STDERR "Uninstalling NVIDIA Cg Toolkit components: ";

    # Uninstall the Cg compiler.
    print STDERR "Cg compiler, ";
    unlink '/usr/bin/cgc';

    # Uninstall any header files from the NVIDIA Cg Toolkit.
    print STDERR "header files, ";
    rmtree('/usr/include/Cg');
    rmtree('/usr/include/CgFX');

    # Uninstall any libraries from the NVIDIA Cg Toolkit.
    print STDERR "libraries, ";
    foreach my $tmp (@CG_LIBRARIES) {
        unlink $CG_USR_LIB . '/' . $tmp;
    }
    # Also ensure that libraries from an older version of NVIDIA Cg Toolkit are
    # uninstalled.
    unlink $CG_USR_LIB . '/' . 'libCgFX.so',
        $CG_USR_LIB . '/' . 'libCgFXGL.so';

    # Uninstall any documentation for the NVIDIA Cg Toolkit.
    print STDERR "documentation, ";
    unlink </usr/share/doc/nvidia-cg-toolkit/*.pdf*>;
    unlink '/usr/share/doc/nvidia-cg-toolkit/README.gz',
        '/usr/share/doc/nvidia-cg-toolkit/README';
    rmtree('/usr/share/doc/nvidia-cg-toolkit/html');
    rmtree('/usr/share/doc/nvidia-cg-toolkit/txt');

    # Uninstall any examples for the NVIDIA Cg Toolkit.
    print STDERR "examples, ";
    rmtree('/usr/share/doc/nvidia-cg-toolkit/examples');

    # Uninstall any manual pages from the NVIDIA Cg Toolkit.
    print STDERR "manual pages, ";
    unlink </usr/share/man/man3/*.3nvidiacg*>;
    unlink </usr/share/man/man3/*.3Cg*>;

    # Run ldconfig.
    print STDERR "(running ldconfig), ";
    system('/sbin/ldconfig') eq 0 or die "ldconfig processing failed: $!";

    # Remove files in /var/cache/nvidia-cg-toolkit if it was requested.
    if ($remove_cache) {
        print STDERR "removing files from cache, ";
        unlink </var/cache/nvidia-cg-toolkit/*>;
    }

    # We're done uninstalling.
    print STDERR "done.\n";
}

# These next lines are the main part of the program
if ($help) { help(); }
if ($install) {
    install();
} elsif ($uninstall) {
    uninstall();
} else {
    # Either the install or uninstall option must be used.
    my $msg = "This program must be run with either the --install or ";
    $msg .= "--uninstall options.\n";
    die $msg;
}

__END__

=head1 NAME

B<nvidia-cg-toolkit-installer> - Program to install/uninstall the NVIDIA Cg Toolkit

=head1 SYNOPSIS

B<nvidia-cg-toolkit-installer> [ options ]

=head1 DESCRIPTION

B<nvidia-cg-toolkit-installer> is a program that will download the NVIDIA Cg Toolkit
from the NVIDIA Developer's website and install it onto your system.

=head1 OPTIONS

B<-h, --help>
    Display a short help summary.

B<-i, --install>
    Install the NVIDIA Cg Toolkit.

B<-u, --uninstall>
    Uninstall the NVIDIA Cg Toolkit.

B<-r, --remove-cache>
    Remove saved NVIDIA Cg Toolkit and Spec files from
    /var/cache/nvidia-cg-toolkit. When using this with --install
    option, All files are deleted from the cache directory except
    files used to install the toolkit and spec file.

B<-t --toolkit-file> I<TOOLKIT_FILE>
    Use I<TOOLKIT_FILE> as the NVIDIA Cg Toolkit tarball.

B<-s, --spec-file> I<SPEC_FILE>
    Use I<SPEC_FILE> as the NVIDIA Cg Toolkit spec file.

B<-p, --search-path> I<PATH>
    Search I<PATH> for the NVIDIA Cg Toolkit tarball and spec file.

B<-d, --delete-after>
    Delete the NVIDIA Cg Toolkit tarball and spec file after program
    is finished executing. This won't delete the files if they were
    retrieved from /var/cache/nvidia-cg-toolkit.

B<--proxy> I<PROXY_URL>
    Use I<PROXY_URL> as the proxy URL that will be used to download the
    NVIDIA Cg Toolkit and spec file.

B<--no-proxy>
    Disable any use of a proxy. This option overrides the --proxy
    option.

B<--generate-manifest>
    Generate a manifest file showing where this script installs files
    from the NVIDIA Cg Toolkit tarball. The file will be saved under
    /tmp/nvidia-cg-toolkit-manifest. Use this file to compare it with
    manifest-$arch.Debian in the nvidia-cg-toolkit documentation.

=head1 BUGS

** PLEASE DO NOT REPORT BUGS OF THE NVIDIA CG TOOLKIT TO THE BTS **

This program is just an *INSTALLER* for the NVIDIA Cg Toolkit. The NVIDIA Cg
Toolkit is not free software. Please report any problem with the NVIDIA Cg
Toolkit directly to NVIDIA. Their contact information is located at:

    http://developer.nvidia.com/object/contact_us.html

Report any bugs with the nvidia-cg-toolkit package or the installer to the
Debian BTS.

=head1 SEE ALSO

http://developer.nvidia.com/object/cg_toolkit.html

=head1 AUTHOR

Andres Mejia

This manual page is autogenerated using pod2man during build time of the
nvidia-cg-toolkit package.

=cut
