
# Install and configure cups client
#
class cups::client {

    package { "cups":
        ensure => installed,
    }

    file { "/etc/cups/client.conf":
        ensure  => present,
        content => template("cups/client.conf.erb"),
        mode    => "0644",
        owner   => root,
        group   => $::operatingsystem ? {
            "openbsd" => "wheel",
            default   => "lp",
        },
        require => Package["cups"],
    }

    case $::operatingsystem {
        "openbsd": {
            exec { "cups-enable":
                command => "sh -c '. /etc/rc.d/cupsd check ; rc_pre'",
                path    => "/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin",
                user    => "root",
                creates => "/usr/bin/lpr.pre-cups",
                require => Package["cups"],
            }
            file { "/etc/printcap":
                ensure  => present,
                source  => "/etc/cups/printcap",
                mode    => "0644",
                owner   => "root",
                group   => "wheel",
                require => Exec["cups-enable"],
            }
        }
        "ubuntu": {
            package { "cups-bsd":
                ensure => installed,
            }
        }
    }

    service { "cups":
        ensure    => stopped,
        enable    => false,
        hasstatus => true,
        require   => Package["cups"],
    }

}

# Install cups server
#
# === Parameters:
#
#     $admin_group:
#         Group name which is allowed to modify printers.
#
#     $manager_group:
#         Group name which is allowed to remove jobs from print
#         queues.
#
#     $ssl_cert:
#         Path to SSL certificate. Defaults to auto generated
#         certificate.
#
#     $ssl_key:
#         Path to SSL key. Defaults to auto generated key.
#
class cups::server($admin_group=undef, $manager_group=undef,
                   $ssl_cert=undef, $ssl_key=undef) inherits cups::client {

    require ssl

    package { [ "ghostscript", "system-config-printer" ]:
        ensure => installed,
    }

    if $ssl_key and $ssl_cert {
        file { "${ssl::private}/cups.key":
            ensure => present,
            source => $ssl_key,
            mode   => "0600",
            owner  => "root",
            group  => "root",
            notify => Service["cups"],
        }
        file { "${ssl::certs}/cups.crt":
            ensure => present,
            source => $ssl_cert,
            mode   => "0644",
            owner  => "root",
            group  => "root",
            notify => Service["cups"],
        }
    }

    file { "/etc/cups/cupsd.conf":
        ensure  => present,
        content => template("cups/cupsd.conf.erb"),
        mode    => "0640",
        owner   => "root",
        group   => "lp",
        require => Package["cups"],
        notify  => Service["cups"],
    }

    Service["cups"] {
        ensure  => running,
        enable  => true,
    }

    file { "/etc/cups/ppd":
        ensure  => directory,
        mode    => "0755",
        owner   => root,
        group   => lp,
        require => Package["cups"],
    }

    File["/etc/cups/client.conf"] {
        content => "ServerName 127.0.0.1\n",
    }

}


# Install and configure printer.
#
# === Parameters
#
#   $name:
#       Printer name.
#   $uri:
#       URI to use for connecting to printer device.
#   $location:
#       Printer location. Use "LDAP" to fetch location information from LDAP.
#   $ensure:
#       If set to present printer will be installed and if set to absent
#       printer will be removed.
#
# === Sample usage
#
# cups::printer { "hp1":
#     ensure   => present,
#     uri      => "socket://hp1:9100,
# }
#
define cups::printer($uri, $location = "", $ensure = present) {

    $hostname = regsubst($uri, '^[a-z]*://(.*)[:/].*', '\1')

    if $location == "LDAP" {
      $_location = template("cups/printer-location.erb")
    } else {
      $_location = $location
    }

    case $ensure {
        present: {
            exec { "cups-add-printer-${name}":
                command => "lpadmin -p ${name} -E -v ${uri} -o printer-error-policy=abort-job",
                path    => "/bin:/sbin:/usr/bin:/usr/sbin",
                unless  => "lpq -P ${name}",
                require => Service["cups"],
            }
            exec { "cups-set-location-${name}":
                command => "lpadmin -p ${name} -L '${location}'",
                path    => "/bin:/sbin:/usr/bin:/usr/sbin",
                unless  => $_location ? {
                    ""      => "lpoptions -p ${name} | egrep ' printer-location '",
                    default => "lpoptions -p ${name} | egrep ' printer-location=${_location} '",
                },
                require => Exec["cups-add-printer-${name}"],
            }
        }
        absent: {
            exec { "cups-del-printer-${name}":
                command => "lpadmin -x ${name}",
                path    => "/bin:/sbin:/usr/bin:/usr/sbin",
                onlyif  => "lpq -P ${name}",
                require => Service["cups"],
            }
        }
        default: {
            fail("Unknown argument to ensure.")
        }
    }

    file { "/etc/cups/ppd/${name}.ppd":
        ensure  => $ensure,
        source  => [ "puppet:///files/cups/${name}.ppd",
                     "puppet:///modules/cups/postscript.ppd" ],
        mode    => "0644",
        owner   => root,
        group   => root,
        require => $ensure ? {
            present => [ Exec["cups-add-printer-${name}"],
                         File["/etc/cups/ppd"], ],
            absent  => Exec["cups-del-printer-${name}"],
        },
    }

}


# Install LP support into cups
#
class cups::lpd {

    include cups::server
    include inetd::server

    package { "cups-lpd":
        ensure => installed,
    }

    inetd::service { "cups-lpd":
        ensure  => present,
        require => Package["cups-lpd"],
    }

}


# Install samba support into cups
#
class cups::samba {

    include samba::server

    file { [ "/etc/samba/drivers",
             "/usr/share/cups/drivers",
             "/usr/share/cups/drivers/x64", ]:
        ensure  => directory,
        mode    => "0755",
        owner   => root,
        group   => root,
        require => [ Package["samba"],
                     Package["cups"], ],
    }

    define driverfile() {
        file { "/usr/share/cups/drivers/${name}":
            ensure  => present,
            source  => "puppet:///modules/cups/drivers/${name}",
            mode    => "0644",
            owner   => root,
            group   => root,
            require => [ File["/usr/share/cups/drivers"],
                         File["/usr/share/cups/drivers/x64"], ],
        }
    }

    driverfile { "cups6.inf": }
    driverfile { "cups6.ini": }
    driverfile { "cupsps6.dll": }
    driverfile { "cupsui6.dll": }

    driverfile { "ps5ui.dll": }
    driverfile { "pscript.hlp": }
    driverfile { "pscript.ntf": }
    driverfile { "pscript5.dll": }

    driverfile { "x64/cups6.inf": }
    driverfile { "x64/cups6.ini": }
    driverfile { "x64/cupsps6.dll": }
    driverfile { "x64/cupsui6.dll": }

    driverfile { "x64/ps5ui.dll": }
    driverfile { "x64/pscript.hlp": }
    driverfile { "x64/pscript.ntf": }
    driverfile { "x64/pscript5.dll": }

    file { "/etc/cron.hourly/update-printer-inf.sh":
        ensure => present,
        source => "puppet:///modules/cups/update-printer-inf.sh",
        mode   => "0755",
        owner  => root,
        group  => root,
    }

}


# Install SNMP polling into cups server
#
class cups::snmp {

    package { "net-snmp-utils":
        ensure => installed,
    }

    file { "/etc/cron.hourly/printer-details.py":
        ensure  => present,
        source  => "puppet:///modules/cups/printer-details.py",
        mode    => "0755",
        owner   => root,
        group   => root,
        require => Package["net-snmp-utils"],
    }

    exec { "create-details-dir":
        command => "umask 022 ; mkdir /usr/share/doc/cups-`rpm -q --queryformat='%{VERSION}' cups`/details",
        path    => "/bin:/usr/bin:/sbin:/usr/sbin",
        user    => root,
        unless  => "test -d /usr/share/doc/cups-`rpm -q --queryformat='%{VERSION}' cups`/details",
        require => Package["cups"],
    }

}
