Unlike Linux/Unix hosts, which use SSH by default, Windows hosts are configured with WinRM. This topic covers how to configure and use WinRM with Ansible.
Topics
WinRM is a management protocol used by Windows to remotely communicate with another server. It is a SOAP-based protocol that communicates over HTTP/HTTPS, and is included in all recent Windows operating systems. Since Windows Server 2012, WinRM has been enabled by default, but in most cases extra configuration is required to use WinRM with Ansible.
Ansible uses the pywinrm package to communicate with Windows servers over WinRM. It is not installed by default with the Ansible package, but can be installed by running the following:
pip install "pywinrm>=0.3.0"
Note
on distributions with multiple python versions, use pip2 or pip2.x, where x matches the python minor version Ansible is running under.
When connecting to a Windows host, there are several different options that can be used
when authenticating with an account. The authentication type may be set on inventory
hosts or groups with the ansible_winrm_transport
variable.
The following matrix is a high level overview of the options:
| Option | Local Accounts | Active Directory Accounts | Credential Delegation | HTTP Encryption |
|---|---|---|---|---|
| Basic | Yes | No | No | No |
| Certificate | Yes | No | No | No |
| Kerberos | No | Yes | Yes | Yes |
| NTLM | Yes | Yes | No | Yes |
| CredSSP | Yes | Yes | Yes | Yes |
Basic authentication is one of the simplest authentication options to use, but is also the most insecure. This is because the username and password are simply base64 encoded, and if a secure channel is not in use (eg, HTTPS) then it can be decoded by anyone. Basic authentication can only be used for local accounts (not domain accounts).
The following example shows host vars configured for basic authentication:
ansible_user: LocalUsername
ansible_password: Password
ansible_connection: winrm
ansible_winrm_transport: basic
Basic authentication is not enabled by default on a Windows host but can be enabled by running the following in PowerShell:
Set-Item -Path WSMan:\localhost\Service\Auth\Basic -Value $true
Certificate authentication uses certificates as keys similar to SSH key pairs, but the file format and key generation process is different.
The following example shows host vars configured for certificate authentication:
ansible_connection: winrm
ansible_winrm_cert_pem: /path/to/certificate/public/key.pem
ansible_winrm_cert_key_pem: /path/to/certificate/private/key.pem
ansible_winrm_transport: certificate
Certificate authentication is not enabled by default on a Windows host but can be enabled by running the following in PowerShell:
Set-Item -Path WSMan:\localhost\Service\Auth\Certificate -Value $true
Note
Encrypted private keys cannot be used as the urllib3 library that is used by Ansible for WinRM does not support this functionality.
A certificate must be generated before it can be mapped to a local user. This can be done using one of the following methods:
New-SelfSignedCertificate
cmdletActive Directory Certificate Services is beyond of scope in this documentation but may be the best option to use when running in a domain environment. For more information, see the Active Directory Certificate Services documentation.
Note
Using the PowerShell cmdlet New-SelfSignedCertificate
to generate
a certificate for authentication only works when being generated from a
Windows 10 or Windows Server 2012 R2 host or later. OpenSSL is still required to
extract the private key from the PFX certificate to a PEM file for Ansible
to use.
To generate a certificate with OpenSSL
:
# Set the name of the local user that will have the key mapped to
USERNAME="username"
cat > openssl.conf << EOL
distinguished_name = req_distinguished_name
[req_distinguished_name]
[v3_req_client]
extendedKeyUsage = clientAuth
subjectAltName = otherName:<IP_ADDRESS>.4.1.3<IP_ADDRESS>;UTF8:[email protected]
EOL
export OPENSSL_CONF=openssl.conf
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -out cert.pem -outform PEM -keyout cert_key.pem -subj "/CN=$USERNAME" -extensions v3_req_client
rm openssl.conf
To generate a certificate with New-SelfSignedCertificate
:
# Set the name of the local user that will have the key mapped
$username = "username"
$output_path = "C:\temp"
# Instead of generating a file, the cert will be added to the personal
# LocalComputer folder in the certificate store
$cert = New-SelfSignedCertificate -Type Custom `
-Subject "CN=$username" `
-TextExtension @("<IP_ADDRESS>={text}<IP_ADDRESS>.<IP_ADDRESS>.2","<IP_ADDRESS>={text}[email protected]") `
-KeyUsage DigitalSignature,KeyEncipherment `
-KeyAlgorithm RSA `
-KeyLength 2048
# Export the public key
$pem_output = @()
$pem_output += "-----BEGIN CERTIFICATE-----"
$pem_output += [System.Convert]::ToBase64String($cert.RawData) -replace ".{64}", "$&`n"
$pem_output += "-----END CERTIFICATE-----"
[System.IO.File]::WriteAllLines("$output_path\cert.pem", $pem_output)
# Export the private key in a PFX file
[System.IO.File]::WriteAllBytes("$output_path\cert.pfx", $cert.Export("Pfx"))
Note
To convert the PFX file to a private key that pywinrm can use, run
the following command with OpenSSL
openssl pkcs12 -in cert.pfx -nocerts -nodes -out cert_key.pem -passin pass: -passout pass:
Once a certificate has been generated, the issuing certificate needs to be
imported into the Trusted Root Certificate Authorities
of the
LocalMachine
store, and the client certificate public key must be present
in the Trusted People
folder of the LocalMachine
store. For this example,
both the issuing certificate and public key are the same.
Following example shows how to import the issuing certificate:
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import("cert.pem")
$store_name = [System.Security.Cryptography.X509Certificates.StoreName]::Root
$store_location = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location
$store.Open("MaxAllowed")
$store.Add($cert)
$store.Close()
Note
If using ADCS to generate the certificate, then the issuing certificate will already be imported and this step can be skipped.
The code to import the client certificate public key is:
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import("cert.pem")
$store_name = [System.Security.Cryptography.X509Certificates.StoreName]::TrustedPeople
$store_location = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location
$store.Open("MaxAllowed")
$store.Add($cert)
$store.Close()
Once the certificate has been imported, it needs to be mapped to the local user account.
This can be done with the following PowerShell command:
$username = "username"
$password = ConvertTo-SecureString -String "password" -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password
# This is the issuer thumbprint which in the case of a self generated cert
# is the public key thumbprint, additional logic may be required for other
# scenarios
$thumbprint = (Get-ChildItem -Path cert:\LocalMachine\root | Where-Object { $_.Subject -eq "CN=$username" }).Thumbprint
New-Item -Path WSMan:\localhost\ClientCertificate `
-Subject "[email protected]" `
-URI * `
-Issuer $thumbprint `
-Credential $credential `
-Force
Once this is complete, the hostvar ansible_winrm_cert_pem
should be set to
the path of the public key and the ansible_winrm_cert_key_pem
variable should be set to
the path of the private key.
NTLM is an older authentication mechanism used by Microsoft that can support both local and domain accounts. NTLM is enabled by default on the WinRM service, so no setup is required before using it.
NTLM is the easiest authentication protocol to use and is more secure than
Basic
authentication. If running in a domain environment, Kerberos
should be used
instead of NTLM.
Kerberos has several advantages over using NTLM:
This example shows host variables configured to use NTLM authentication:
ansible_user: LocalUsername
ansible_password: Password
ansible_connection: winrm
ansible_winrm_transport: ntlm
Kerberos is the recommended authentication option to use when running in a domain environment. Kerberos supports features like credential delegation and message encryption over HTTP and is one of the more secure options that is available through WinRM.
Kerberos requires some additional setup work on the Ansible host before it can be used properly.
The following example shows host vars configured for Kerberos authentication:
ansible_user: [email protected]
ansible_password: Password
ansible_connection: winrm
ansible_winrm_transport: kerberos
As of Ansible version 2.3, the Kerberos ticket will be created based on
ansible_user
and ansible_password
. If running on an older version of
Ansible or when ansible_winrm_kinit_mode
is manual
, a Kerberos
ticket must already be obtained. See below for more details.
There are some extra host variables that can be set:
ansible_winrm_kinit_mode: managed/manual (manual means Ansible will not obtain a ticket)
ansible_winrm_kinit_cmd: the kinit binary to use to obtain a Kerberos ticket (default to kinit)
ansible_winrm_service: overrides the SPN prefix that is used, the default is ``HTTP`` and should rarely ever need changing
ansible_winrm_kerberos_delegation: allows the credentials to traverse multiple hops
ansible_winrm_kerberos_hostname_override: the hostname to be used for the kerberos exchange
Some system dependencies that must be installed prior to using Kerberos. The script below lists the dependencies based on the distro:
# Via Yum (RHEL/Centos/Fedora)
yum -y install python-devel krb5-devel krb5-libs krb5-workstation
# Via Apt (Ubuntu)
sudo apt-get install python-dev libkrb5-dev krb5-user
# Via Portage (Gentoo)
emerge -av app-crypt/mit-krb5
emerge -av dev-python/setuptools
# Via Pkg (FreeBSD)
sudo pkg install security/krb5
# Via OpenCSW (Solaris)
pkgadd -d http://get.opencsw.org/now
/opt/csw/bin/pkgutil -U
/opt/csw/bin/pkgutil -y -i libkrb5_3
# Via Pacman (Arch Linux)
pacman -S krb5
Once the dependencies have been installed, the python-kerberos
wrapper can
be install using pip
:
pip install pywinrm[kerberos]
Once the dependencies have been installed, Kerberos needs to be configured so
that it can communicate with a domain. This configuration is done through the
/etc/krb5.conf
file, which is installed with the packages in the script above.
To configure Kerberos, in the section that starts with:
[realms]
Add the full domain name and the fully qualified domain names of the primary and secondary Active Directory domain controllers. It should look something like this:
[realms]
MY.DOMAIN.COM = {
kdc = domain-controller1.my.domain.com
kdc = domain-controller2.my.domain.com
}
In the section that starts with:
[domain_realm]
Add a line like the following for each domain that Ansible needs access for:
[domain_realm]
.my.domain.com = MY.DOMAIN.COM
You can configure other settings in this file such as the default domain. See krb5.conf for more details.
Ansible version 2.3 and later defaults to automatically managing Kerberos tickets
when both ansible_user
and ansible_password
are specified for a host. In
this process, a new ticket is created in a temporary credential cache for each
host. This is done before each task executes to minimize the chance of ticket
expiration. The temporary credential caches are deleted after each task
completes and will not interfere with the default credential cache.
To disable automatic ticket management, set ansible_winrm_kinit_mode=manual
via the inventory.
Automatic ticket management requires a standard kinit
binary on the control
host system path. To specify a different location or binary name, set the
ansible_winrm_kinit_cmd
hostvar to the fully qualified path to a MIT krbv5
kinit
-compatible binary.
To manually manage Kerberos tickets, the kinit
binary is used. To
obtain a new ticket the following command is used:
kinit [email protected]
Note
The domain must match the configured Kerberos realm exactly, and must be in upper case.
To see what tickets (if any) have been acquired, use the following command:
klist
To destroy all the tickets that have been acquired, use the following command:
kdestroy
Kerberos is reliant on a properly-configured environment to work. To troubleshoot Kerberos issues, ensure that:
The hostname set for the Windows host is the FQDN and not an IP address.
The forward and reverse DNS lookups are working properly in the domain. To
test this, ping the windows host by name and then use the ip address returned
with nslookup
. The same name should be returned when using nslookup
on the IP address.
The Ansible host’s clock is synchronized with the domain controller. Kerberos is time sensitive, and a little clock drift can cause the ticket generation process to fail.
Ensure that the fully qualified domain name for the domain is configured in
the krb5.conf
file. To check this, run:
kinit -C [email protected]
klist
If the domain name returned by klist
is different from the one requested,
an alias is being used. The krb5.conf
file needs to be updated so that
the fully qualified domain name is used and not an alias.
If the default kerberos tooling has been replaced or modified (some IdM solutions may do this), this may cause issues when installing or upgrading the Python Kerberos library. As of the time of this writing, this library is called pykerberos
and is known to work with both MIT and Heimdal Kerberos libraries. To resolve pykerberos
installation issues, ensure the system dependencies for Kerberos have been met (see: Installing the Kerberos Library), remove any custom Kerberos tooling paths from the PATH environment variable, and retry the installation of Python Kerberos library package.
CredSSP authentication is a newer authentication protocol that allows credential delegation. This is achieved by encrypting the username and password after authentication has succeeded and sending that to the server using the CredSSP protocol.
Because the username and password are sent to the server to be used for double hop authentication, ensure that the hosts that the Windows host communicates with are not compromised and are trusted.
CredSSP can be used for both local and domain accounts and also supports message encryption over HTTP.
To use CredSSP authentication, the host vars are configured like so:
ansible_user: Username
ansible_password: Password
ansible_connection: winrm
ansible_winrm_transport: credssp
There are some extra host variables that can be set as shown below:
ansible_winrm_credssp_disable_tlsv1_2: when true, will not use TLS 1.2 in the CredSSP auth process
CredSSP authentication is not enabled by default on a Windows host, but can be enabled by running the following in PowerShell:
Enable-WSManCredSSP -Role Server -Force
The requests-credssp
wrapper can be installed using pip
:
pip install pywinrm[credssp]
By default the requests-credssp
library is configured to authenticate over
the TLS 1.2 protocol. TLS 1.2 is installed and enabled by default for Windows Server 2012
and Windows 8 and more recent releases.
There are two ways that older hosts can be used with CredSSP:
ansible_winrm_credssp_disable_tlsv1_2=True
in the inventory to run
over TLS 1.0. This is the only option when connecting to Windows Server 2008, which
has no way of supporting TLS 1.2See TLS 1.2 Support for more information on how to enable TLS 1.2 on the Windows host.
CredSSP works by encrypting the credentials through the TLS protocol and uses a self-signed certificate by default. The CertificateThumbprint
option under the WinRM service configuration can be used to specify the thumbprint of
another certificate.
Note
This certificate configuration is independent of the WinRM listener certificate. With CredSSP, message transport still occurs over the WinRM listener, but the TLS-encrypted messages inside the channel use the service-level certificate.
To explicitly set the certificate to use for CredSSP:
# Note the value $certificate_thumbprint will be different in each
# situation, this needs to be set based on the cert that is used.
$certificate_thumbprint = "7C8DCBD5427AFEE6560F4AF524E325915F51172C"
# Set the thumbprint value
Set-Item -Path WSMan:\localhost\Service\CertificateThumbprint -Value $certificate_thumbprint
WinRM is configured by default to only allow connections from accounts in the local
Administrators
group. This can be changed by running:
winrm configSDDL default
This will display an ACL editor, where new users or groups may be added. To run commands
over WinRM, users and groups must have at least the Read
and Execute
permissions
enabled.
While non-administrative accounts can be used with WinRM, most typical server administration tasks require some level of administrative access, so the utility is usually limited.
By default WinRM will fail to work when running over an unencrypted channel. The WinRM protocol considers the channel to be encrypted if using TLS over HTTP (HTTPS) or using message level encryption. Using WinRM with TLS is the recommended option as it works with all authentication options, but requires a certificate to be created and used on the WinRM listener.
The ConfigureRemotingForAnsible.ps1
creates a self-signed certificate and
creates the listener with that certificate. If in a domain environment, ADCS
can also create a certificate for the host that is issued by the domain itself.
If using HTTPS is not an option, then HTTP can be used when the authentication
option is NTLM
, Kerberos
or CredSSP
. These protocols will encrypt
the WinRM payload with their own encryption method before sending it to the
server. The message-level encryption is not used when running over HTTPS because the
encryption uses the more secure TLS protocol instead. If both transport and
message encryption is required, set ansible_winrm_message_encryption=always
in the host vars.
A last resort is to disable the encryption requirement on the Windows host. This should only be used for development and debugging purposes, as anything sent from Ansible can be viewed, manipulated and also the remote session can completely be taken over by anyone on the same network. To disable the encryption requirement, run the following from PowerShell on the target host:
Set-Item -Path WSMan:\localhost\Service\AllowUnencrypted -Value $true
Note
Do not disable the encryption check unless it is absolutely required. Doing so could allow sensitive information like credentials and files to be intercepted by others on the network.
Ansible’s Windows support relies on a few standard variables to indicate the
username, password, and connection type of the remote hosts. These variables
are most easily set up in the inventory, but can be set on the host_vars
/
group_vars
level.
When setting up the inventory, the following variables are required:
# It is suggested that these be encrypted with ansible-vault:
# ansible-vault edit group_vars/windows.yml
ansible_connection: winrm
# May also be passed on the command-line via --user
ansible_user: Administrator
# May also be supplied at runtime with --ask-pass
ansible_password: SecretPasswordGoesHere
Using the variables above, Ansible will connect to the Windows host with Basic
authentication through HTTPS. If ansible_user
has a UPN value like
<EMAIL_ADDRESS>then the authentication option will automatically attempt
to use Kerberos unless ansible_winrm_transport
has been set to something other than
kerberos
.
The following custom inventory variables are also supported for additional configuration of WinRM connections:
ansible_port
: The port WinRM will run over, HTTPS is 5986
which is
the default while HTTP is 5985
ansible_winrm_scheme
: Specify the connection scheme (http
or
https
) to use for the WinRM connection. Ansible uses https
by default
unless ansible_port
is 5985
ansible_winrm_path
: Specify an alternate path to the WinRM endpoint,
Ansible uses /wsman
by defaultansible_winrm_realm
: Specify the realm to use for Kerberos
authentication. If ansible_user
contains @
, Ansible will use the part
of the username after @
by defaultansible_winrm_transport
: Specify one or more authentication transport
options as a comma-separated list. By default, Ansible will use kerberos,
basic
if the kerberos
module is installed and a realm is defined,
otherwise it will be plaintext
ansible_winrm_server_cert_validation
: Specify the server certificate
validation mode (ignore
or validate
). Ansible defaults to
validate
on Python 2.7.9 and higher, which will result in certificate
validation errors against the Windows self-signed certificates. Unless
verifiable certificates have been configured on the WinRM listeners, this
should be set to ignore
ansible_winrm_operation_timeout_sec
: Increase the default timeout for
WinRM operations, Ansible uses 20
by defaultansible_winrm_read_timeout_sec
: Increase the WinRM read timeout, Ansible
uses 30
by default. Useful if there are intermittent network issues and
read timeout errors keep occurringansible_winrm_message_encryption
: Specify the message encryption
operation (auto
, always
, never
) to use, Ansible uses auto
by
default. auto
means message encryption is only used when
ansible_winrm_scheme
is http
and ansible_winrm_transport
supports
message encryption. always
means message encryption will always be used
and never
means message encryption will never be usedansible_winrm_ca_trust_path
: Used to specify a different cacert container
than the one used in the certifi
module. See the HTTPS Certificate
Validation section for more details.ansible_winrm_send_cbt
: When using ntlm
or kerberos
over HTTPS,
the authentication library will try to send channel binding tokens to
mitigate against man in the middle attacks. This flag controls whether these
bindings will be sent or not (default: yes
).ansible_winrm_*
: Any additional keyword arguments supported by
winrm.Protocol
may be provided in place of *
In addition, there are also specific variables that need to be set for each authentication option. See the section on authentication above for more information.
Note
Ansible 2.0 has deprecated the “ssh” from ansible_ssh_user
,
ansible_ssh_pass
, ansible_ssh_host
, and ansible_ssh_port
to
become ansible_user
, ansible_password
, ansible_host
, and
ansible_port
. If using a version of Ansible prior to 2.0, the older
style (ansible_ssh_*
) should be used instead. The shorter variables
are ignored, without warning, in older versions of Ansible.
Note
ansible_winrm_message_encryption
is different from transport
encryption done over TLS. The WinRM payload is still encrypted with TLS
when run over HTTPS, even if ansible_winrm_message_encryption=never
.
IPv6 addresses can be used instead of IPv4 addresses or hostnames. This option is normally set in an inventory. Ansible will attempt to parse the address using the ipaddress package and pass to pywinrm correctly.
When defining a host using an IPv6 address, just add the IPv6 address as you would an IPv4 address or hostname:
[windows-server]
2001:db8::1
[windows-server:vars]
ansible_user=username
ansible_password=password
ansible_connection=winrm
Note
The ipaddress library is only included by default in Python 3.x. To
use IPv6 addresses in Python 2.7, make sure to run pip install ipaddress
which installs
a backported package.
As part of the TLS protocol, the certificate is validated to ensure the host
matches the subject and the client trusts the issuer of the server certificate.
When using a self-signed certificate or setting
ansible_winrm_server_cert_validation: ignore
these security mechanisms are
bypassed. While self signed certificates will always need the ignore
flag,
certificates that have been issued from a certificate authority can still be
validated.
One of the more common ways of setting up a HTTPS listener in a domain environment is to use Active Directory Certificate Service (AD CS). AD CS is used to generate signed certificates from a Certificate Signing Request (CSR). If the WinRM HTTPS listener is using a certificate that has been signed by another authority, like AD CS, then Ansible can be set up to trust that issuer as part of the TLS handshake.
To get Ansible to trust a Certificate Authority (CA) like AD CS, the issuer certificate of the CA can be exported as a PEM encoded certificate. This certificate can then be copied locally to the Ansible controller and used as a source of certificate validation, otherwise known as a CA chain.
The CA chain can contain a single or multiple issuer certificates and each
entry is contained on a new line. To then use the custom CA chain as part of
the validation process, set ansible_winrm_ca_trust_path
to the path of the
file. If this variable is not set, the default CA chain is used instead which
is located in the install path of the Python package
certifi.
Note
Each HTTP call is done by the Python requests library which does not use the systems built-in certificate store as a trust authority. Certificate validation will fail if the server’s certificate issuer is only added to the system’s truststore.
As WinRM runs over the HTTP protocol, using HTTPS means that the TLS protocol is used to encrypt the WinRM messages. TLS will automatically attempt to negotiate the best protocol and cipher suite that is available to both the client and the server. If a match cannot be found then Ansible will error out with a message similar to:
HTTPSConnectionPool(host='server', port=5986): Max retries exceeded with url: /wsman (Caused by SSLError(SSLError(1, '[SSL: UNSUPPORTED_PROTOCOL] unsupported protocol (_ssl.c:1056)')))
Commonly this is when the Windows host has not been configured to support TLS v1.2 but it could also mean the Ansible controller has an older OpenSSL version installed.
Windows 8 and Windows Server 2012 come with TLS v1.2 installed and enabled by default but older hosts, like Server 2008 R2 and Windows 7, have to be enabled manually.
Note
There is a bug with the TLS 1.2 patch for Server 2008 which will stop Ansible from connecting to the Windows host. This means that Server 2008 cannot be configured to use TLS 1.2. Server 2008 R2 and Windows 7 are not affected by this issue and can use TLS 1.2.
To verify what protocol the Windows host supports, you can run the following command on the Ansible controller:
openssl s_client -connect <hostname>:5986
The output will contain information about the TLS session and the Protocol
line will display the version that was negotiated:
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : ECDHE-RSA-AES256-SHA
Session-ID: 962A00001C95D2A601BE1CCFA7831B85A7EEE897AECDBF3D9ECD4A3BE4F6AC9B
Session-ID-ctx:
Master-Key: ....
Start Time:<PHONE_NUMBER>
Timeout : 7200 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1.2
Cipher : ECDHE-RSA-AES256-GCM-SHA384
Session-ID: AE16000050DA9FD44D03BB8839B64449805D9E43DBD670346D3D9E05D1AEEA84
Session-ID-ctx:
Master-Key: ....
Start Time:<PHONE_NUMBER>
Timeout : 7200 (sec)
Verify return code: 21 (unable to verify the first certificate)
If the host is returning TLSv1
then it should be configured so that
TLS v1.2 is enable. You can do this by running the following PowerShell
script:
Function Enable-TLS12 {
param(
[ValidateSet("Server", "Client")]
[String]$Component = "Server"
)
$protocols_path = 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols'
New-Item -Path "$protocols_path\TLS 1.2\$Component" -Force
New-ItemProperty -Path "$protocols_path\TLS 1.2\$Component" -Name Enabled -Value 1 -Type DWORD -Force
New-ItemProperty -Path "$protocols_path\TLS 1.2\$Component" -Name DisabledByDefault -Value 0 -Type DWORD -Force
}
Enable-TLS12 -Component Server
# Not required but highly recommended to enable the Client side TLS 1.2 components
Enable-TLS12 -Component Client
Restart-Computer
The below Ansible tasks can also be used to enable TLS v1.2:
- name: enable TLSv1.2 support
win_regedit:
path: HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\{{ item.type }}
name: '{{ item.property }}'
data: '{{ item.value }}'
type: dword
state: present
register: enable_tls12
loop:
- type: Server
property: Enabled
value: 1
- type: Server
property: DisabledByDefault
value: 0
- type: Client
property: Enabled
value: 1
- type: Client
property: DisabledByDefault
value: 0
- name: reboot if TLS config was applied
win_reboot:
when: enable_tls12 is changed
There are other ways to configure the TLS protocols as well as the cipher suites that are offered by the Windows host. One tool that can give you a GUI to manage these settings is IIS Crypto from Nartac Software.
Due to the design of the WinRM protocol , there are a few limitations when using WinRM that can cause issues when creating playbooks for Ansible. These include:
DPAPI
, which is used by some
installers (like Microsoft SQL Server).Some of these limitations can be mitigated by doing one of the following:
ansible_winrm_transport
to credssp
or kerberos
(with
ansible_winrm_kerberos_delegation=true
) to bypass the double hop issue
and access network resourcesbecome
to bypass all WinRM restrictions and run a command as it would
locally. Unlike using an authentication transport like credssp
, this will
also remove the non-interactive restriction and API restrictions like WUA and
DPAPIwin_scheduled_task
module. Like become
, this bypasses all WinRM
restrictions but can only run a command and not modules.See also


|
| |
|
The Microsoft Band 2 user experience: who would have thought sleep could be so
interesting? |
|
Microsoft recently released their second fitness tracker, the Microsoft Band 2,
and as both a fitness enthusiast and a tech guy, I was excited to test it out. I
haven't tried the original Microsoft band, but I have tried several of the
FitBit releases, and am familiar with the Samsung Gear S, so I was keen to see
how this device would measure up. |
|
|
|
I picked up a bundle of bands at the new Microsoft store to
give to the guys at SSW. It's been enlightening to hear everybody's experiences
over the last month. Of course, they've all had different scenarios and each
have given different opinions of the quirks and foibles of the device. This
review brings together their feedback as well as my own – the good and the bad.
|
|
Keep reading to find out how
the Microsoft Band 2 stacks up. |
|
|
|
|
|
|
|
Featured Video from SSW TV |
|
|
| |
|
VIDEO: Past, Present and Future of MONO with Miguel de
Icaza |
|
In this video, Adam Cogan talks to the creator of
Xamarin – Miguel de Icaza – about MONO, Miguel's
original invention that dealt with cross platform
development. Watch
video. |
| |
|
|
|
|
| |
|
|
|
Mastering ReSharper |
|
Being a great professional requires from you to write
high quality code and being fast at the same time.
Unless you have a great toolset this certainly isn't an
easy task. Luckily the market is full of extensions for
Visual Studio which can boost your productivity.  Participants learn, work and code
together for 10-12 hours per day, 5 days a week,
building a .NET application with an experienced mentor.
Read
More |
|
|
Mar
28
Mon
|
Sydney, Australia |
|
| |
|
|
|
Xamarin Hack Days are free events that make it easy for
anyone to learn cross-platform development using
Xamarin, a product that allows you to use .NET/C# to
create native apps that will run across Android, iOS,
and Windows. Read
More |
Feb
6
Sat
|
Melbourne, Australia |
|
Mar
12
Sat
|
Zagreb, Croatia |
|
| |
|
|
| |
|
| |
|
December User Group - Sydney |
|
IoT/Win10 double header event - featuring Dave Glover and Chris Briggs |
|
For a special December treat, we've got 2 passionate guys presenting on
everything IoT + Win10. |
|
Windows Internet of Things development starts to sizzle – Learn the
Universal Windows Platform - Chris Briggs |
|
Windows 10 is here and will be powering a billion devices shortly. The attendees
will learn how to develop IoT applications that target Windows 10 IoT core, by
developing on the Universal Windows Platform (UWP) and how to integrate the
solution with Windows Azure. Read more. |
|
Windows 10 for IoT: What is it and how do you develop for it - Dave
Glover |
|
Windows 10 for IoT Microsoft brings the Universal Windows Platform app
development to the amazing Raspberry Pi 2 and MinnnowBoard Max devices and that
opens up a whole world of new opportunities. This is a technical developer
session starting from first principles of IoT devices, programming languages and
high level app support. It'll be fun, there will be plenty of bright lights and
hopefully you'll be inspired to go out and build. |
| |
|
|
About the presenters |
|
Chris
Briggs is a Senior Software Developer at SSW,
passionate about IoT, Scrum, Security, Windows Universal
Apps and Xamarin. All the Devs at SSW have been asking
Chris, what he thinks the Internet of Things will mean
for their day to day lives? It ranges from the
impossible to the improbable, from automating their
coffee breaks, to telling them exactly when the next bus
will arrive!
Dave
Glover has worked for Microsoft for over 20
years mostly in our Developer Platform Group, the
first 10 years were with Microsoft UK and he
transfer to Microsoft Australia in 2004. He has
worked in various roles including people management
and across a broad spectrum of infrastructure and
developer technologies with a variety of customers
and partners.
|
|
|
| |
|
Dec
16
Wed
|
SSW Sydney
Gateway Court Suite 15
81-91 Military Road, Neutral Bay
|
|
|
|
|
|
|
|
|
|
|
SSW and Octopus Deploy invite you to join us for pizza! It's a fun
and delicious opportunity for networking with peers and sharing
thoughts after the Sydney .NET User Group. Read More |
Dec
16
Wed
|
SSW Sydney
Gateway Court Suite 15
81-91 Military Road, Neutral Bay
|
|
| |
|
|
Sydney .NET User Group and NerdDinner proudly sponsored by: |
|
|
| |
|
|
| |
|
December User Group - Canberra |
|
Windows Internet of Things development starts to sizzle – Learn the Universal
Windows Platform |
|
Windows 10 is here and will be powering a billion devices shortly. The attendees
will learn how to develop IoT applications that target Windows 10 IoT core, by
developing on the Universal Windows Platform (UWP) and how to integrate the
solution with Windows Azure. |
|
In this presentation, Chris Briggs, who heads up IoT at SSW, will teach the
attendees how to take advantage of the Universal Windows Platform. The familiar
.NET platform now empowers developers do more with less work by building one
solution across half a dozen hardware platforms. Read more. |
| |
|
|
Presented by Chris Briggs |
|
Chris
Briggs is a Senior Software Developer at SSW,
passionate about IoT, Scrum, Security, Windows Universal
Apps and Xamarin. All the Devs at SSW have been asking
Chris what he thinks the Internet of Things will mean
for their day to day lives. It ranges from the
impossible to the improbable, from automating their
coffee breaks, to telling them exactly when the next bus
will arrive! |
|
|
| |
|
Dec
14
Mon
|
Microsoft Canberra
Level 4, 6 National Circuit
Canberra
|
|
|
|
|
|
|
| |
| |
|
|
|


- A simple card game created with Unity WebGL that can be played in a browser. - This project was for me to learn more about using design patterns in Unity. - Check out the project on my Github page.


Neat
We want more
by internetjerk321
We want more posts!!
Here is more
by niceguy2
https://goodstuff.com/
Even more
by randy
https://catpics.net/
Even more
by randy
https://catpics.net/
Even more
by randy
https://catpics.net/
Even more
by randy
https://catpics.net/
Text!


public class SearcherLifetimeManager extends Object implements Closeable
SearcherLifetimeManager mgr = new SearcherLifetimeManager();Per search-request, if it's a "new" search request, then obtain the latest searcher you have (for example, by using
SearcherManager
or
NRTManager
), and
then record this searcher:
// Record the current searcher, and save the returend // token into user's search results (eg as a hidden // HTML form field): long token = mgr.record(searcher);When a follow-up search arrives, for example the user clicks next page, drills down/up, etc., take the token that you saved from the previous search and:
// If possible, obtain the same searcher as the last // search: IndexSearcher searcher = mgr.acquire(token); if (searcher != null) { // Searcher is still here try { // do searching... } finally { mgr.release(searcher); // Do not use searcher after this! searcher = null; } } else { // Searcher was pruned -- notify user session timed // out, or, pull fresh searcher again }Finally, in a separate thread, ideally the same thread that's periodically reopening your searchers, you should periodically prune old searchers:
mgr.prune(new PruneByAge(600.0));
NOTE
: keeping many searchers around means
you'll use more resources (open files, RAM) than a single
searcher. However, as long as you are using
IndexReader.openIfChanged(org.apache.lucene.index.IndexReader)
, the searchers will usually
share almost all segments and the added resource usage is
contained. When a large merge has completed, and
you reopen, because that is a large change, the new
searcher will use higher additional RAM than other
searchers; but large merges don't complete very often and
it's unlikely you'll hit two of them in your expiration
window. Still you should budget plenty of heap in the
JVM to have a good safety margin.
| Modifier and Type | Class and Description |
|---|---|
static class
|
SearcherLifetimeManager.PruneByAge
Simple pruner that drops any searcher older by
more than the specified seconds, than the newest
searcher.
|
static interface
|
SearcherLifetimeManager.Pruner
|
| Constructor and Description |
|---|
SearcherLifetimeManager
()
|
| Modifier and Type | Method and Description |
|---|---|
IndexSearcher
|
acquire
(long version)
Retrieve a previously recorded
IndexSearcher
, if it
has not yet been closed
|
void
|
close
()
Close this to future searching; any searches still in
process in other threads won't be affected, and they
should still call
release(org.apache.lucene.search.IndexSearcher)
after they are
done.
|
void
|
prune
(
SearcherLifetimeManager.Pruner
pruner)
Calls provided
SearcherLifetimeManager.Pruner
to prune entries.
|
long
|
record
(
IndexSearcher
searcher)
Records that you are now using this IndexSearcher.
|
void
|
release
(
IndexSearcher
s)
Release a searcher previously obtained from
acquire(long)
.
|
public long record( IndexSearcher searcher) throws IOException
IndexSearcher
, for example from one of the
get
methods in
NRTManager
or
SearcherManager
. It's fine if you already passed the
same searcher to this method before.
This returns the long token that you can later pass
to
acquire(long)
to retrieve the same IndexSearcher.
You should record this long token in the search results
sent to your user, such that if the user performs a
follow-on action (clicks next page, drills down, etc.)
the token is returned.
IOException
public IndexSearcher acquire(long version)
IndexSearcher
, if it
has not yet been closed
NOTE : this may return null when the requested searcher has already timed out.
If this returns a non-null result, you must match
later call
release(org.apache.lucene.search.IndexSearcher)
on this searcher, best
from a finally clause.
public void release( IndexSearcher s) throws IOException
acquire(long)
.
NOTE : it's fine to call this after close.
IOException
public void prune( SearcherLifetimeManager.Pruner pruner) throws IOException
SearcherLifetimeManager.Pruner
to prune entries. The
entries are passed to the Pruner in sorted (newest to
oldest IndexSearcher) order.
NOTE : you must peridiocally call this, ideally from the same background thread that opens new searchers.
IOException
public void close() throws IOException
release(org.apache.lucene.search.IndexSearcher)
after they are
done.
NOTE: you must ensure no other threads are
calling
record(org.apache.lucene.search.IndexSearcher)
while you call close();
otherwise it's possible not all searcher references
will be freed.
close
in interface
Closeable
IOException


Name: * Required Organization Name: * Select Organization Required Choose Provider: * Choose Provider Required Operating System: * Select OS Required Image ID: * Admin User Name: * Admin Password:


Body discovered near school in Ballymun, Co Dublin
Gardai say they are at the 'scene of an incident'
by Brynmor PattisonDeputy Online Editor, John Patrick KieransA body was discovered at a laneway near a school in Dublin this morning.
Gardai say they are at the "scene of an incident" at Balbutcher Lane in Ballymun.
The Irish Mirror understands that a body was discovered there this morning.
The discovery was made just yards from a local school.
A garda spokesman said: "Gardai are currently at the scene of an incident at Balbutcher Lane area of Ballymun.
"A scene is currently in place. Further updates will issue."
Just last Monday, there was a 'shooting' scare in the area.
Gardai responded to reports of a loud bang from a place known locally as 'The Hill' near St Joseph's School at around 3pm on Monday, November 18.
It was feared that a gun had gone off - however no evidence was found to suggest there was a shooting.
Locals told Dublin Live last week how the area has been known as an anti-social blackspot, describing it as a "no-go area".
One said: "There's always trouble there, residents are sick. There's open drug dealing and fighting and we're scared someone will be hurt."
We'll be bringing you the very latest updates, pictures and video on this breaking news story.
For the latest news and breaking news visit irishmirror.ie/news.
Get all the big headlines, pictures, analysis, opinion and video on the stories that matter to you.
Follow us on Twitter @IrishMirror - the official Irish Mirror Twitter account - real news in real time.
We're also on Facebook/irishmirror - your must-see news, features, videos and pictures throughout the day from the Irish Daily Mirror, Irish Sunday Mirror and irishmirror.ie.
How to follow the Irish Mirror on social media
You can like our main Facebook page here.
Our Irish Mirror Sports page - which brings you all your Irish and UK sports news - can be found here.
You can also check out our Irish Mirror GAA sports page.
The Irish Mirror Twitter account is @IrishMirror while our sports account is @MirrorSportIE.
Our Instagram account can be found here.


PDS files often have the extension .img, sometimes with an associated .lbl (label) file. When a .lbl file exists it should be used as the dataset name rather than the .img file.
In addition to support for most PDS imagery configurations, this driver also reads georeferencing and coordinate system information as well as selected other header metadata.
Implementation of this driver was supported by the United States Geological Survey.
For example, the MOLA labels currently contain a one pixel offset. Once ticket #5941 is applied (should be available post 1.11.3), which corrects the PDS offset defaults, here is how you can correctly read in a MOLA label using the --config options in the PDS reader.
$ gdalinfo --config PDS_SampleProjOffset_Shift -0.5 --config PDS_LineProjOffset_Shift -0.5 mola.lbl
For LOLA global PDS files the center should be perfectly 0.0, 0.0 meters in Cartesian space. example conversion:
$ gdal_translate --config PDS_SampleProjOffset_Shift -0.5 --config PDS_LineProjOffset_Shift -0.5 mola.lbl out.tif
example conversion and applying offset and multiplier values as defined in some PDS labels:
$ gdal_translate -ot Float32 -unscale --config PDS_SampleProjOffset_Shift -0.5 --config PDS_LineProjOffset_Shift -0.5 mola.lbl out_32bit.tif
As a test, this lunar LOLA PDS label should be perfectly centered at 0.0, 0.0 meters in Cartesian space without any configuration options. Remember you will need a GDAL version post 1.11.3.
$ gdalinfo ldem_4.lbl
To test the --config keyword above, this Mars MOLA PDS label should be perfectly centered at 0.0, 0.0 meters in Cartesian space with the following configuration options. Remember you will need a GDAL version post 1.11.3.
$ gdalinfo --config PDS_SampleProjOffset_Shift -0.5 --config PDS_LineProjOffset_Shift -0.5 megt90n000cb.lbl


--- layout: post title: Windows Azure WebRoles and Getting Your Console App on the Cloud date: type: post published: false status: draft categories: [] tags: [] meta: _edit_last: '54045106' author: login: sirars email<EMAIL_ADDRESS>display_name: Sirar Salih first_name: '' last_name: '' ---
I had the chance to play around with Windows Azure Worker


The toolchain should be easy to install on OSX platforms. Below are a few troubleshooting items found on Mountain Lion (10.8.2).
See https://github.com/ddm/icetools for a set of shell scripts to build IceStorm on OSX (using brew for dependencies).
The libftdi package (.so lib binary and the ftdi.h header) has been renamed to libftdi0, so either do:
port install libftdi0
(note that ports installs the tool to /opt instead of /usr, see next note)
brew install libftdi0
Note that Mac Ports installs to /opt instead of /usr, so change the first two lines in iceprog/Makefile to:
LDLIBS = -L/usr/local/lib -L/opt/local/lib -lftdi -lm CFLAGS = -MD -O0 -ggdb -Wall -std=c99 -I/usr/local/include -I/opt/local/include/
Basically you are indicating where to find the lib with -L/opt/local/lib and where to find the .h with -I/opt/local/include/.
This is a compiler issue, i.e., you are probably running on clang and you can circumvent this error by compiling against another compiler. Edit the Makefile of yosys and replace the two first lines for this, i.e., comment the first line (clang) and uncomment the second (gcc):
#CONFIG := clang CONFIG := gcc
You need to unload the FTDI driver (notes below are from Mountain Lion, 10.8.2). First check if it is running:
kextstat | grep FTDIUSBSerialDriver
If you see it on the kextstat, we need to unload it:
sudo kextunload -b com.FTDI.driver.FTDIUSBSerialDriver
Repeat the kextstat command and check that the driver was successfully unloaded.
Try running iceprog example.bin again. It should be working now.
Note: On newer OSes perhaps you need to also kextunload the com.apple.driver.AppleUSBFTDI driver.


do it now!
-
Save my love(Express the determinism to change myself for love)
-
Make her warm
-
think about what she need right now.
-
search the whether of baihu and remind her to add clothes.
-
list the reason why she is tired of the love right now.
And find the way to solve it.
-
Write a letter every day to her to express my love to her.
-
Make some touched videoes to rememerate our happiness passed life.
-
keep the phone always on-line


PERLLOCALE
Section: Perl Programmers Reference Guide (1)Updated: 2009-02-12
Index Return to Main Contents
NAME
perllocale - Perl locale handling (internationalization and localization)DESCRIPTION
Perl supports language-specific notions of data such as ``is this a letter'', ``what is the uppercase equivalent of this letter'', and ``which of these letters comes first''. These are important issues, especially for languages other than English---but also for English: it would be nai.ve to imagine that "A-Za-z" defines all the ``letters'' needed to write in English. Perl is also aware that some character other than '.' may be preferred as a decimal point, and that output date representations may be language-specific. The process of making an application take account of its users' preferences in such matters is called internationalization (often abbreviated as i18n); telling such an application about a particular set of preferences is known as localization (l10n).Perl can understand language-specific data via the standardized (ISO C, XPG4, POSIX 1.c) method called ``the locale system''. The locale system is controlled per application using one pragma, one function call, and several environment variables.
NOTE: This feature is new in Perl 5.004, and does not apply unless an application specifically requests it---see ``Backward compatibility''. The one exception is that write() now always uses the current locale - see ``NOTES''.
PREPARING TO USE LOCALES
If Perl applications are to understand and present your data correctly according a locale of your choice, all of the following must be true:- *
- Your operating system must support the locale system. If it does, you should find that the setlocale() function is a documented part of its C library.
- *
- Definitions for locales that you use must be installed. You, or your system administrator, must make sure that this is the case. The available locales, the location in which they are kept, and the manner in which they are installed all vary from system to system. Some systems provide only a few, hard-wired locales and do not allow more to be added. Others allow you to add ``canned'' locales provided by the system supplier. Still others allow you or the system administrator to define and add arbitrary locales. (You may have to ask your supplier to provide canned locales that are not delivered with your operating system.) Read your system documentation for further illumination.
- *
- Perl must believe that the locale system is supported. If it does, "perl -V:d_setlocale" will say that the value for "d_setlocale" is "define".
If you want a Perl application to process and present your data according to a particular locale, the application code should include the "use locale" pragma (see ``The use locale pragma'') where appropriate, and at least one of the following must be true:
- *
- The locale-determining environment variables (see ``ENVIRONMENT'') must be correctly set up at the time the application is started, either by yourself or by whoever set up your system account.
- *
- The application must set its own locale using the method described in ``The setlocale function''.
USING LOCALES
The use locale pragma
By default, Perl ignores the current locale. The "use locale" pragma tells Perl to use the current locale for some operations:- *
-
The comparison operators ("lt", "le", "cmp", "ge", and "gt") and
the POSIX string collation functions strcoll() and strxfrm() use
"LC_COLLATE". sort() is also affected if used without an
explicit comparison function, because it uses "cmp" by default.
Note: "eq" and "ne" are unaffected by locale: they always perform a char-by-char comparison of their scalar operands. What's more, if "cmp" finds that its operands are equal according to the collation sequence specified by the current locale, it goes on to perform a char-by-char comparison, and only returns 0 (equal) if the operands are char-for-char identical. If you really want to know whether two strings---which "eq" and "cmp" may consider different---are equal as far as collation in the locale is concerned, see the discussion in ``Category LC_COLLATE: Collation''.
- *
- Regular expressions and case-modification functions (uc(), lc(), ucfirst(), and lcfirst()) use "LC_CTYPE"
- *
- The formatting functions (printf(), sprintf() and write()) use "LC_NUMERIC"
- *
- The POSIX date formatting function (strftime()) uses "LC_TIME".
"LC_COLLATE", "LC_CTYPE", and so on, are discussed further in ``LOCALE CATEGORIES''.
The default behavior is restored with the "no locale" pragma, or upon reaching the end of block enclosing "use locale".
The string result of any operation that uses locale information is tainted, as it is possible for a locale to be untrustworthy. See ``SECURITY''.
The setlocale function
You can switch locales as often as you wish at run time with the POSIX::setlocale() function:
# This functionality not usable prior to Perl 5.004 require 5.004; # Import locale-handling tool set from POSIX module. # This example uses: setlocale -- the function call # LC_CTYPE -- explained below use POSIX qw(locale_h); # query and save the old locale $old_locale = setlocale(LC_CTYPE); setlocale(LC_CTYPE, "fr_CA.ISO8859-1"); # LC_CTYPE now in locale "French, Canada, codeset ISO 8859-1" setlocale(LC_CTYPE, ""); # LC_CTYPE now reset to default defined by LC_ALL/LC_CTYPE/LANG # environment variables. See below for documentation. # restore the old locale setlocale(LC_CTYPE, $old_locale);
The first argument of setlocale() gives the category, the second the locale. The category tells in what aspect of data processing you want to apply locale-specific rules. Category names are discussed in ``LOCALE CATEGORIES'' and ``ENVIRONMENT''. The locale is the name of a collection of customization information corresponding to a particular combination of language, country or territory, and codeset. Read on for hints on the naming of locales: not all systems name locales as in the example.
If no second argument is provided and the category is something else than LC_ALL, the function returns a string naming the current locale for the category. You can use this value as the second argument in a subsequent call to setlocale().
If no second argument is provided and the category is LC_ALL, the result is implementation-dependent. It may be a string of concatenated locales names (separator also implementation-dependent) or a single locale name. Please consult your setlocale(3) man page for details.
If a second argument is given and it corresponds to a valid locale, the locale for the category is set to that value, and the function returns the now-current locale value. You can then use this in yet another call to setlocale(). (In some implementations, the return value may sometimes differ from the value you gave as the second argument---think of it as an alias for the value you gave.)
As the example shows, if the second argument is an empty string, the category's locale is returned to the default specified by the corresponding environment variables. Generally, this results in a return to the default that was in force when Perl started up: changes to the environment made by the application after startup may or may not be noticed, depending on your system's C library.
If the second argument does not correspond to a valid locale, the locale for the category is not changed, and the function returns undef.
For further information about the categories, consult setlocale(3).
Finding locales
For locales available in your system, consult also setlocale(3) to see whether it leads to the list of available locales (search for the SEE ALSO section). If that fails, try the following command lines:
locale -a nlsinfo ls /usr/lib/nls/loc ls /usr/lib/locale ls /usr/lib/nls ls /usr/share/locale
and see whether they list something resembling these
en_US.ISO8859-1 de_DE.ISO8859-1 ru_RU.ISO8859-5 en_US.iso88591 de_DE.iso88591 ru_RU.iso88595 en_US de_DE ru_RU en de ru english german russian english.iso88591 german.iso88591 russian.iso88595 english.roman8 russian.koi8r
Sadly, even though the calling interface for setlocale() has been standardized, names of locales and the directories where the configuration resides have not been. The basic form of the name is language_territory.codeset, but the latter parts after language are not always present. The language and country are usually from the standards ISO 3166 and ISO 639, the two-letter abbreviations for the countries and the languages of the world, respectively. The codeset part often mentions some ISO 8859 character set, the Latin codesets. For example, "ISO 8859-1" is the so-called ``Western European codeset'' that can be used to encode most Western European languages adequately. Again, there are several ways to write even the name of that one standard. Lamentably.
Two special locales are worth particular mention: ``C'' and ``POSIX''. Currently these are effectively the same locale: the difference is mainly that the first one is defined by the C standard, the second by the POSIX standard. They define the default locale in which every program starts in the absence of locale information in its environment. (The default default locale, if you will.) Its language is (American) English and its character codeset ASCII.
NOTE: Not all systems have the ``POSIX'' locale (not all systems are POSIX-conformant), so use ``C'' when you need explicitly to specify this default locale.
LOCALE PROBLEMS
You may encounter the following warning message at Perl startup:
perl: warning: Setting locale failed. perl: warning: Please check that your locale settings: LC_ALL = "En_US", LANG = (unset) are supported and installed on your system. perl: warning: Falling back to the standard locale ("C").
This means that your locale settings had LC_ALL set to ``En_US'' and LANG exists but has no value. Perl tried to believe you but could not. Instead, Perl gave up and fell back to the ``C'' locale, the default locale that is supposed to work no matter what. This usually means your locale settings were wrong, they mention locales your system has never heard of, or the locale installation in your system has problems (for example, some system files are broken or missing). There are quick and temporary fixes to these problems, as well as more thorough and lasting fixes.
Temporarily fixing locale problems
The two quickest fixes are either to render Perl silent about any locale inconsistencies or to run Perl under the default locale ``C''.Perl's moaning about locale problems can be silenced by setting the environment variable PERL_BADLANG to a zero value, for example ``0''. This method really just sweeps the problem under the carpet: you tell Perl to shut up even when Perl sees that something is wrong. Do not be surprised if later something locale-dependent misbehaves.
Perl can be run under the ``C'' locale by setting the environment variable LC_ALL to ``C''. This method is perhaps a bit more civilized than the PERL_BADLANG approach, but setting LC_ALL (or other locale variables) may affect other programs as well, not just Perl. In particular, external programs run from within Perl will see these changes. If you make the new settings permanent (read on), all programs you run see the changes. See ``ENVIRONMENT'' for the full list of relevant environment variables and ``USING LOCALES'' for their effects in Perl. Effects in other programs are easily deducible. For example, the variable LC_COLLATE may well affect your sort program (or whatever the program that arranges ``records'' alphabetically in your system is called).
You can test out changing these variables temporarily, and if the new settings seem to help, put those settings into your shell startup files. Consult your local documentation for the exact details. For in Bourne-like shells (sh, ksh, bash, zsh):
LC_ALL=en_US.ISO8859-1 export LC_ALL
This assumes that we saw the locale ``en_US.ISO8859-1'' using the commands discussed above. We decided to try that instead of the above faulty locale ``En_US''--and in Cshish shells (csh, tcsh)
setenv LC_ALL en_US.ISO8859-1
or if you have the ``env'' application you can do in any shell
env LC_ALL=en_US.ISO8859-1 perl ...
If you do not know what shell you have, consult your local helpdesk or the equivalent.
Permanently fixing locale problems
The slower but superior fixes are when you may be able to yourself fix the misconfiguration of your own environment variables. The mis(sing)configuration of the whole system's locales usually requires the help of your friendly system administrator.First, see earlier in this document about ``Finding locales''. That tells how to find which locales are really supported---and more importantly, installed---on your system. In our example error message, environment variables affecting the locale are listed in the order of decreasing importance (and unset variables do not matter). Therefore, having LC_ALL set to ``En_US'' must have been the bad choice, as shown by the error message. First try fixing locale settings listed first.
Second, if using the listed commands you see something exactly (prefix matches do not count and case usually counts) like ``En_US'' without the quotes, then you should be okay because you are using a locale name that should be installed and available in your system. In this case, see ``Permanently fixing your system's locale configuration''.
Permanently fixing your system's locale configuration
This is when you see something like:
perl: warning: Please check that your locale settings: LC_ALL = "En_US", LANG = (unset) are supported and installed on your system.
but then cannot see that ``En_US'' listed by the above-mentioned commands. You may see things like ``en_US.ISO8859-1'', but that isn't the same. In this case, try running under a locale that you can list and which somehow matches what you tried. The rules for matching locale names are a bit vague because standardization is weak in this area. See again the ``Finding locales'' about general rules.
Fixing system locale configuration
Contact a system administrator (preferably your own) and report the exact error message you get, and ask them to read this same documentation you are now reading. They should be able to check whether there is something wrong with the locale configuration of the system. The ``Finding locales'' section is unfortunately a bit vague about the exact commands and places because these things are not that standardized.The localeconv function
The POSIX::localeconv() function allows you to get particulars of the locale-dependent numeric formatting information specified by the current "LC_NUMERIC" and "LC_MONETARY" locales. (If you just want the name of the current locale for a particular category, use POSIX::setlocale() with a single parameter---see ``The setlocale function''.)
use POSIX qw(locale_h); # Get a reference to a hash of locale-dependent info $locale_values = localeconv(); # Output sorted list of the values for (sort keys %$locale_values) { printf "%-20s = %s\n", $_, $locale_values->{$_} }
localeconv() takes no arguments, and returns a reference to a hash. The keys of this hash are variable names for formatting, such as "decimal_point" and "thousands_sep". The values are the corresponding, er, values. See ``localeconv'' in POSIX for a longer example listing the categories an implementation might be expected to provide; some provide more and others fewer. You don't need an explicit "use locale", because localeconv() always observes the current locale.
Here's a simple-minded example program that rewrites its command-line parameters as integers correctly formatted in the current locale:
# See comments in previous example require 5.004; use POSIX qw(locale_h); # Get some of locale's numeric formatting parameters my ($thousands_sep, $grouping) = @{localeconv()}{'thousands_sep', 'grouping'}; # Apply defaults if values are missing $thousands_sep = ',' unless $thousands_sep; # grouping and mon_grouping are packed lists # of small integers (characters) telling the # grouping (thousand_seps and mon_thousand_seps # being the group dividers) of numbers and # monetary quantities. The integers' meanings: # 255 means no more grouping, 0 means repeat # the previous grouping, 1-254 means use that # as the current grouping. Grouping goes from # right to left (low to high digits). In the # below we cheat slightly by never using anything # else than the first grouping (whatever that is). if ($grouping) { @grouping = unpack("C*", $grouping); } else { @grouping = (3); } # Format command line params for current locale for (@ARGV) { $_ = int; # Chop non-integer part 1 while s/(\d)(\d{$grouping[0]}($|$thousands_sep))/$1$thousands_sep$2/; print "$_"; } print "\n";
I18N::Langinfo
Another interface for querying locale-dependent information is the I18N::Langinfo::langinfo() function, available at least in UNIX-like systems and VMS.The following example will import the langinfo() function itself and three constants to be used as arguments to langinfo(): a constant for the abbreviated first day of the week (the numbering starts from Sunday = 1) and two more constants for the affirmative and negative answers for a yes/no question in the current locale.
use I18N::Langinfo qw(langinfo ABDAY_1 YESSTR NOSTR); my ($abday_1, $yesstr, $nostr) = map { langinfo } qw(ABDAY_1 YESSTR NOSTR); print "$abday_1? [$yesstr/$nostr] ";
In other words, in the ``C'' (or English) locale the above will probably print something like:
Sun? [yes/no]
See I18N::Langinfo for more information.
LOCALE CATEGORIES
The following subsections describe basic locale categories. Beyond these, some combination categories allow manipulation of more than one basic category at a time. See ``ENVIRONMENT'' for a discussion of these.Category LC_COLLATE: Collation
In the scope of "use locale", Perl looks to the "LC_COLLATE" environment variable to determine the application's notions on collation (ordering) of characters. For example, 'b' follows 'a' in Latin alphabets, but where do 'a' and 'a°' belong? And while 'color' follows 'chocolate' in English, what about in Spanish?The following collations all make sense and you may meet any of them if you ``use locale''.
A B C D E a b c d e A a B b C c D d E e a A b B c C d D e E a b c d e A B C D E
Here is a code snippet to tell what ``word'' characters are in the current locale, in that locale's order:
use locale; print +(sort grep /\w/, map { chr } 0..255), "\n";
Compare this with the characters that you see and their order if you state explicitly that the locale should be ignored:
no locale; print +(sort grep /\w/, map { chr } 0..255), "\n";
This machine-native collation (which is what you get unless "use locale" has appeared earlier in the same block) must be used for sorting raw binary data, whereas the locale-dependent collation of the first example is useful for natural text.
As noted in ``USING LOCALES'', "cmp" compares according to the current collation locale when "use locale" is in effect, but falls back to a char-by-char comparison for strings that the locale says are equal. You can use POSIX::strcoll() if you don't want this fall-back:
use POSIX qw(strcoll); $equal_in_locale = !strcoll("space and case ignored", "SpaceAndCaseIgnored");
$equal_in_locale will be true if the collation locale specifies a dictionary-like ordering that ignores space characters completely and which folds case.
If you have a single string that you want to check for ``equality in locale'' against several others, you might think you could gain a little efficiency by using POSIX::strxfrm() in conjunction with "eq":
use POSIX qw(strxfrm); $xfrm_string = strxfrm("Mixed-case string"); print "locale collation ignores spaces\n" if $xfrm_string eq strxfrm("Mixed-casestring"); print "locale collation ignores hyphens\n" if $xfrm_string eq strxfrm("Mixedcase string"); print "locale collation ignores case\n" if $xfrm_string eq strxfrm("mixed-case string");
strxfrm() takes a string and maps it into a transformed string for use in char-by-char comparisons against other transformed strings during collation. ``Under the hood'', locale-affected Perl comparison operators call strxfrm() for both operands, then do a char-by-char comparison of the transformed strings. By calling strxfrm() explicitly and using a non locale-affected comparison, the example attempts to save a couple of transformations. But in fact, it doesn't save anything: Perl magic (see ``Magic Variables'' in perlguts) creates the transformed version of a string the first time it's needed in a comparison, then keeps this version around in case it's needed again. An example rewritten the easy way with "cmp" runs just about as fast. It also copes with null characters embedded in strings; if you call strxfrm() directly, it treats the first null it finds as a terminator. don't expect the transformed strings it produces to be portable across systems---or even from one revision of your operating system to the next. In short, don't call strxfrm() directly: let Perl do it for you.
Note: "use locale" isn't shown in some of these examples because it isn't needed: strcoll() and strxfrm() exist only to generate locale-dependent results, and so always obey the current "LC_COLLATE" locale.
Category LC_CTYPE: Character Types
In the scope of "use locale", Perl obeys the "LC_CTYPE" locale setting. This controls the application's notion of which characters are alphabetic. This affects Perl's "\w" regular expression metanotation, which stands for alphanumeric characters---that is, alphabetic, numeric, and including other special characters such as the underscore or hyphen. (Consult perlre for more information about regular expressions.) Thanks to "LC_CTYPE", depending on your locale setting, characters like 'ae', 'd-', 'beta', and 'o' may be understood as "\w" characters.The "LC_CTYPE" locale also provides the map used in transliterating characters between lower and uppercase. This affects the case-mapping functions---lc(), lcfirst, uc(), and ucfirst(); case-mapping interpolation with "\l", "\L", "\u", or "\U" in double-quoted strings and "s///" substitutions; and case-independent regular expression pattern matching using the "i" modifier.
Finally, "LC_CTYPE" affects the POSIX character-class test functions---isalpha(), islower(), and so on. For example, if you move from the ``C'' locale to a 7-bit Scandinavian one, you may find---possibly to your surprise---that ``|'' moves from the ispunct() class to isalpha().
Note: A broken or malicious "LC_CTYPE" locale definition may result in clearly ineligible characters being considered to be alphanumeric by your application. For strict matching of (mundane) letters and digits---for example, in command strings---locale-aware applications should use "\w" inside a "no locale" block. See ``SECURITY''.
Category LC_NUMERIC: Numeric Formatting
After a proper POSIX::setlocale() call, Perl obeys the "LC_NUMERIC" locale information, which controls an application's idea of how numbers should be formatted for human readability by the printf(), sprintf(), and write() functions. String-to-numeric conversion by the POSIX::strtod() function is also affected. In most implementations the only effect is to change the character used for the decimal point---perhaps from '.' to ','. These functions aren't aware of such niceties as thousands separation and so on. (See ``The localeconv function'' if you care about these things.)Output produced by print() is also affected by the current locale: it corresponds to what you'd get from printf() in the ``C'' locale. The same is true for Perl's internal conversions between numeric and string formats:
use POSIX qw(strtod setlocale LC_NUMERIC); setlocale LC_NUMERIC, ""; $n = 5/2; # Assign numeric 2.5 to $n $a = " $n"; # Locale-dependent conversion to string print "half five is $n\n"; # Locale-dependent output printf "half five is %g\n", $n; # Locale-dependent output print "DECIMAL POINT IS COMMA\n" if $n == (strtod("2,5"))[0]; # Locale-dependent conversion
See also I18N::Langinfo and "RADIXCHAR".
Category LC_MONETARY: Formatting of monetary amounts
The C standard defines the "LC_MONETARY" category, but no function that is affected by its contents. (Those with experience of standards committees will recognize that the working group decided to punt on the issue.) Consequently, Perl takes no notice of it. If you really want to use "LC_MONETARY", you can query its contents---see ``The localeconv function''--and use the information that it returns in your application's own formatting of currency amounts. However, you may well find that the information, voluminous and complex though it may be, still does not quite meet your requirements: currency formatting is a hard nut to crack.See also I18N::Langinfo and "CRNCYSTR".
LC_TIME
Output produced by POSIX::strftime(), which builds a formatted human-readable date/time string, is affected by the current "LC_TIME" locale. Thus, in a French locale, the output produced by the %B format element (full month name) for the first month of the year would be ``janvier''. Here's how to get a list of long month names in the current locale:
use POSIX qw(strftime); for (0..11) { $long_month_name[$_] = strftime("%B", 0, 0, 0, 1, $_, 96); }
Note: "use locale" isn't needed in this example: as a function that exists only to generate locale-dependent results, strftime() always obeys the current "LC_TIME" locale.
See also I18N::Langinfo and "ABDAY_1".."ABDAY_7", "DAY_1".."DAY_7", "ABMON_1".."ABMON_12", and "ABMON_1".."ABMON_12".
Other categories
The remaining locale category, "LC_MESSAGES" (possibly supplemented by others in particular implementations) is not currently used by Perl---except possibly to affect the behavior of library functions called by extensions outside the standard Perl distribution and by the operating system and its utilities. Note especially that the string value of $! and the error messages given by external utilities may be changed by "LC_MESSAGES". If you want to have portable error codes, use "%!". See Errno.SECURITY
Although the main discussion of Perl security issues can be found in perlsec, a discussion of Perl's locale handling would be incomplete if it did not draw your attention to locale-dependent security issues. Locales---particularly on systems that allow unprivileged users to build their own locales---are untrustworthy. A malicious (or just plain broken) locale can make a locale-aware application give unexpected results. Here are a few possibilities:- *
- Regular expression checks for safe file names or mail addresses using "\w" may be spoofed by an "LC_CTYPE" locale that claims that characters such as ``>'' and ``|'' are alphanumeric.
- *
- String interpolation with case-mapping, as in, say, "$dest = "C:\U$name.$ext"", may produce dangerous results if a bogus LC_CTYPE case-mapping table is in effect.
- *
- A sneaky "LC_COLLATE" locale could result in the names of students with ``D'' grades appearing ahead of those with ``A''s.
- *
- An application that takes the trouble to use information in "LC_MONETARY" may format debits as if they were credits and vice versa if that locale has been subverted. Or it might make payments in US dollars instead of Hong Kong dollars.
- *
- The date and day names in dates formatted by strftime() could be manipulated to advantage by a malicious user able to subvert the "LC_DATE" locale. (``Look---it says I wasn't in the building on Sunday.'')
Such dangers are not peculiar to the locale system: any aspect of an application's environment which may be modified maliciously presents similar challenges. Similarly, they are not specific to Perl: any programming language that allows you to write programs that take account of their environment exposes you to these issues.
Perl cannot protect you from all possibilities shown in the examples---there is no substitute for your own vigilance---but, when "use locale" is in effect, Perl uses the tainting mechanism (see perlsec) to mark string results that become locale-dependent, and which may be untrustworthy in consequence. Here is a summary of the tainting behavior of operators and functions that may be affected by the locale:
- *
-
Comparison operators ("lt", "le", "ge", "gt" and "cmp"):
Scalar true/false (or less/equal/greater) result is never tainted.
- *
-
Case-mapping interpolation (with "\l", "\L", "\u" or "\U")
Result string containing interpolated material is tainted if "use locale" is in effect.
- *
-
Matching operator ("m//"):
Scalar true/false result never tainted.
Subpatterns, either delivered as a list-context result or as $1 etc. are tainted if "use locale" is in effect, and the subpattern regular expression contains "\w" (to match an alphanumeric character), "\W" (non-alphanumeric character), "\s" (whitespace character), or "\S" (non whitespace character). The matched-pattern variable, $&, $` (pre-match), $' (post-match), and $+ (last match) are also tainted if "use locale" is in effect and the regular expression contains "\w", "\W", "\s", or "\S".
- *
-
Substitution operator ("s///"):
Has the same behavior as the match operator. Also, the left operand of "=~" becomes tainted when "use locale" in effect if modified as a result of a substitution based on a regular expression match involving "\w", "\W", "\s", or "\S"; or of case-mapping with "\l", "\L","\u" or "\U".
- *
-
Output formatting functions (printf() and write()):
Results are never tainted because otherwise even output from print, for example "print(1/7)", should be tainted if "use locale" is in effect.
- *
-
Case-mapping functions (lc(), lcfirst(), uc(), ucfirst()):
Results are tainted if "use locale" is in effect.
- *
-
POSIX locale-dependent functions (localeconv(), strcoll(),
strftime(), strxfrm()):
Results are never tainted.
- *
-
POSIX character class tests (isalnum(), isalpha(), isdigit(),
isgraph(), islower(), isprint(), ispunct(), isspace(), isupper(),
isxdigit()):
True/false results are never tainted.
Three examples illustrate locale-dependent tainting. The first program, which ignores its locale, won't run: a value taken directly from the command line may not be used to name an output file when taint checks are enabled.
#/usr/local/bin/perl -T # Run with taint checking # Command line sanity check omitted... $tainted_output_file = shift; open(F, ">$tainted_output_file") or warn "Open of $untainted_output_file failed: $!\n";
The program can be made to run by ``laundering'' the tainted value through a regular expression: the second example---which still ignores locale information---runs, creating the file named on its command line if it can.
#/usr/local/bin/perl -T $tainted_output_file = shift; $tainted_output_file =~ m%[\w/]+%; $untainted_output_file = $&; open(F, ">$untainted_output_file") or warn "Open of $untainted_output_file failed: $!\n";
Compare this with a similar but locale-aware program:
#/usr/local/bin/perl -T $tainted_output_file = shift; use locale; $tainted_output_file =~ m%[\w/]+%; $localized_output_file = $&; open(F, ">$localized_output_file") or warn "Open of $localized_output_file failed: $!\n";
This third program fails to run because $& is tainted: it is the result of a match involving "\w" while "use locale" is in effect.
ENVIRONMENT
- PERL_BADLANG
-
A string that can suppress Perl's warning about failed locale settings
at startup. Failure can occur if the locale support in the operating
system is lacking (broken) in some way---or if you mistyped the name of
a locale when you set up your environment. If this environment
variable is absent, or has a value that does not evaluate to integer
zero---that is, ``0'' or ""-- Perl will complain about locale setting
failures.
NOTE: PERL_BADLANG only gives you a way to hide the warning message. The message tells about some problem in your system's locale support, and you should investigate what the problem is.
The following environment variables are not specific to Perl: They are part of the standardized (ISO C, XPG4, POSIX 1.c) setlocale() method for controlling an application's opinion on data.
- LC_ALL
- "LC_ALL" is the ``override-all'' locale environment variable. If set, it overrides all the rest of the locale environment variables.
- LANGUAGE
-
NOTE: "LANGUAGE" is a GNU extension, it affects you only if you
are using the GNU libc. This is the case if you are using e.g. Linux.
If you are using ``commercial'' UNIXes you are most probably not
using GNU libc and you can ignore "LANGUAGE".
However, in the case you are using "LANGUAGE": it affects the language of informational, warning, and error messages output by commands (in other words, it's like "LC_MESSAGES") but it has higher priority than LC_ALL. Moreover, it's not a single value but instead a ``path'' (``:''-separated list) of languages (not locales). See the GNU "gettext" library documentation for more information.
- LC_CTYPE
- In the absence of "LC_ALL", "LC_CTYPE" chooses the character type locale. In the absence of both "LC_ALL" and "LC_CTYPE", "LANG" chooses the character type locale.
- LC_COLLATE
- In the absence of "LC_ALL", "LC_COLLATE" chooses the collation (sorting) locale. In the absence of both "LC_ALL" and "LC_COLLATE", "LANG" chooses the collation locale.
- LC_MONETARY
- In the absence of "LC_ALL", "LC_MONETARY" chooses the monetary formatting locale. In the absence of both "LC_ALL" and "LC_MONETARY", "LANG" chooses the monetary formatting locale.
- LC_NUMERIC
- In the absence of "LC_ALL", "LC_NUMERIC" chooses the numeric format locale. In the absence of both "LC_ALL" and "LC_NUMERIC", "LANG" chooses the numeric format.
- LC_TIME
- In the absence of "LC_ALL", "LC_TIME" chooses the date and time formatting locale. In the absence of both "LC_ALL" and "LC_TIME", "LANG" chooses the date and time formatting locale.
- LANG
- "LANG" is the ``catch-all'' locale environment variable. If it is set, it is used as the last resort after the overall "LC_ALL" and the category-specific "LC_...".
Examples
The LC_NUMERIC controls the numeric output:
use locale; use POSIX qw(locale_h); # Imports setlocale() and the LC_ constants. setlocale(LC_NUMERIC, "fr_FR") or die "Pardon"; printf "%g\n", 1.23; # If the "fr_FR" succeeded, probably shows 1,23.
and also how strings are parsed by POSIX::strtod() as numbers:
use locale; use POSIX qw(locale_h strtod); setlocale(LC_NUMERIC, "de_DE") or die "Entschuldigung"; my $x = strtod("2,34") + 5; print $x, "\n"; # Probably shows 7,34.
NOTES
Backward compatibility
Versions of Perl prior to 5.004 mostly ignored locale information, generally behaving as if something similar to the "C" locale were always in force, even if the program environment suggested otherwise (see ``The setlocale function''). By default, Perl still behaves this way for backward compatibility. If you want a Perl application to pay attention to locale information, you must use the "use locale" pragma (see ``The use locale pragma'') to instruct it to do so.Versions of Perl from 5.002 to 5.003 did use the "LC_CTYPE" information if available; that is, "\w" did understand what were the letters according to the locale environment variables. The problem was that the user had no control over the feature: if the C library supported locales, Perl used them.
I18N:Collate obsolete
In versions of Perl prior to 5.004, per-locale collation was possible using the "I18N::Collate" library module. This module is now mildly obsolete and should be avoided in new applications. The "LC_COLLATE" functionality is now integrated into the Perl core language: One can use locale-specific scalar data completely normally with "use locale", so there is no longer any need to juggle with the scalar references of "I18N::Collate".Sort speed and memory use impacts
Comparing and sorting by locale is usually slower than the default sorting; slow-downs of two to four times have been observed. It will also consume more memory: once a Perl scalar variable has participated in any string comparison or sorting operation obeying the locale collation rules, it will take 3-15 times more memory than before. (The exact multiplier depends on the string's contents, the operating system and the locale.) These downsides are dictated more by the operating system's implementation of the locale system than by Perl.write() and LC_NUMERIC
Formats are the only part of Perl that unconditionally use information from a program's locale; if a program's environment specifies an LC_NUMERIC locale, it is always used to specify the decimal point character in formatted output. Formatted output cannot be controlled by "use locale" because the pragma is tied to the block structure of the program, and, for historical reasons, formats exist outside that block structure.Freely available locale definitions
There is a large collection of locale definitions at ftp://dkuug.dk/i18n/WG15-collection . You should be aware that it is unsupported, and is not claimed to be fit for any purpose. If your system allows installation of arbitrary locales, you may find the definitions useful as they are, or as a basis for the development of your own locales.I18n and l10n
``Internationalization'' is often abbreviated as i18n because its first and last letters are separated by eighteen others. (You may guess why the internalin ... internaliti ... i18n tends to get abbreviated.) In the same way, ``localization'' is often abbreviated to l10n.An imperfect standard
Internationalization, as defined in the C and POSIX standards, can be criticized as incomplete, ungainly, and having too large a granularity. (Locales apply to a whole process, when it would arguably be more useful to have them apply to a single thread, window group, or whatever.) They also have a tendency, like standards groups, to divide the world into nations, when we all know that the world can equally well be divided into bankers, bikers, gamers, and so on. But, for now, it's the only standard we've got. This may be construed as a bug.Unicode and UTF-8
The support of Unicode is new starting from Perl version 5.6, and more fully implemented in the version 5.8. See perluniintro and perlunicode for more details.Usually locale settings and Unicode do not affect each other, but there are exceptions, see ``Locales'' in perlunicode for examples.
BUGS
Broken systems
In certain systems, the operating system's locale support is broken and cannot be fixed or used by Perl. Such deficiencies can and will result in mysterious hangs and/or Perl core dumps when the "use locale" is in effect. When confronted with such a system, please report in excruciating detail to<EMAIL_ADDRESS>and complain to your vendor: bug fixes may exist for these problems in your operating system. Sometimes such bug fixes are called an operating system upgrade.SEE ALSO
I18N::Langinfo, perluniintro, perlunicode, open, ``isalnum'' in POSIX, ``isalpha'' in POSIX, ``isdigit'' in POSIX, ``isgraph'' in POSIX, ``islower'' in POSIX, ``isprint'' in POSIX, ``ispunct'' in POSIX, ``isspace'' in POSIX, ``isupper'' in POSIX, ``isxdigit'' in POSIX, ``localeconv'' in POSIX, ``setlocale'' in POSIX, ``strcoll'' in POSIX, ``strftime'' in POSIX, ``strtod'' in POSIX, ``strxfrm'' in POSIX.HISTORY
Jarkko Hietaniemi's original perli18n.pod heavily hacked by Dominic Dunlop, assisted by the perl5-porters. Prose worked over a bit by Tom Christiansen.Last update: Thu Jun 11 08:44:13 MDT 1998
Index
- NAME
- DESCRIPTION
- PREPARING TO USE LOCALES
- USING LOCALES
- LOCALE CATEGORIES
- SECURITY
- ENVIRONMENT
- NOTES
- Unicode and UTF-8
- BUGS
- SEE ALSO
- HISTORY
This document was created by man2html, using the manual pages.
Time: 05:29:08 GMT, December 24, 2015


(Note: we're not using the N pool for this project, at the moment...)
Using a brute force approach to find parameter sensitivties and best fit values.
Analysis of layer values vs. MIMICS residuals to determine if it's worth using the new data layers for modeling.
Investigating trends in Nick Patton's soil pit data based on sampling depth.
Quick overview of the gaps found in the RCrk flux tower data (4 sites).
Adjusting MIMICS parameters to make SOC estimates more sensitive to soil temperature differences, such as those between north-south aspects of Johnston Draw
Looking for clues for why MIMICS is underpredicting high SOC stocks. Are the surface layers in those stocks more C rich? Is high POM throwing off the MIMICS estimate?
See title.
Plot residuals against various environemntal properties to find missed correlations.
Set MIMICS parameters to reduce CUE to reduce size of microbial pools, then reduce Tau to reduce transfer of microbial C to SOM pools.
Explore how MIMICS SOC estimates change when shifting input data ANPP values.
Review and mapping of profile SIC stock data provided in the Reynolds Creek soil datasets from Nick Patton and Chris Stanbery.
Comparison of soil C pools from Hasini filed data with SOM pools in MIMICS.
Analysis to determine hwo fMET values influence microbial pools, SOM pools and SOM stocks in MIMICS SOC.
Analysis to determine if slope and/or curvature correlate with residual error in the MIMICS SOC predictions.
Overview of RC datasets available from Hasini Delvinne thesis work, provided by Marie-Anne de Graaff.
Add fW variable in MIMICS sandbox code to constrain microbial processing based on water stress.
Estimate of soil water inputs across Reynolds Creek based on elevation and aspect.
Overview of Johnston Draw soil moisture probe data, with emphasis of comparison of between north and south slopes.
Overview of Reynolds Creek soil moisture probe data and analysis of relationship with mean annual precipitation values.


Sign Up
Sign up for your personal Miku Sushi ID
Full name
Username
Email address
Password
Retype password
Gender
Male
Female
Sign up


Decision matrix for entire coastal region incorporating 19 coastal districts by plotting sensitivity indices against adaptive capacity indices ( A) and visualization of drivers and buffers of both Sensitivity and adaptive capacity components of a representative district on the circumplex charts ( B, C), respectively, for intervention planning.


Grit gives you object oriented read/write access to Git repositories via Ruby. The main goals are stability and performance. To this end, some of the interactions with Git repositories are done by shelling out to the system’s `git` command, and other interactions are done with pure Ruby reimplementations of core Git functionality. This choice, however, is transparent to end users, and you need not know which method is being used.
This software was developed to power GitHub, and should be considered production ready. An extensive test suite is provided to verify its correctness.
Grit is maintained by Tom Preston-Werner, Scott Chacon, Chris Wanstrath, and PJ Hyett.
This documentation is accurate as of Grit 2.3.
## Requirements
- git (git-scm.com) tested with <IP_ADDRESS>
## Install
Easiest install is via RubyGems:
$ gem install grit
## Source
Grit’s Git repo is available on GitHub, which can be browsed at:
http://github.com/mojombo/grit
and cloned with:
git clone git://github.com/mojombo/grit.git
### Development
You will need these gems to get tests to pass:
- mocha
### Contributing
If you’d like to hack on Grit, follow these instructions. To get all of the dependencies, install the gem first.
- Fork the project to your own account
- Clone down your fork
- Create a thoughtfully named topic branch to contain your change
- Hack away
- Add tests and make sure everything still passes by running `rake`
- If you are adding new functionality, document it in README.md
- Do not change the version number, I will do that on my end
- If necessary, rebase your commits into logical chunks, without errors
- Push the branch up to GitHub
- Send a pull request for your branch
## Usage
Grit gives you object model access to your Git repositories. Once you have created a `Repo` object, you can traverse it to find parent commits, trees, blobs, etc.
### Initialize a Repo object
The first step is to create a `Grit::Repo` object to represent your repo. In this documentation I include the `Grit` module to reduce typing.
require 'grit' repo = Grit::Repo.new("/Users/tom/dev/grit")
In the above example, the directory `/Users/tom/dev/grit` is my working directory and contains the `.git` directory. You can also initialize Grit with a bare repo.
repo = Repo.new("/var/git/grit.git")
### Getting a list of commits
From the `Repo` object, you can get a list of commits as an array of `Commit` objects.
repo.commits # => [#<Grit::Commit "e80bbd2ce67651aa18e57fb0b43618ad4baf7750">, #<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">, #<Grit::Commit "038af8c329ef7c1bae4568b98bd5c58510465493">, #<Grit::Commit "40d3057d09a7a4d61059bca9dca5ae698de58cbe">, #<Grit::Commit "4ea50f4754937bf19461af58ce3b3d24c77311d9">]
Called without arguments, `Repo#commits` returns a list of up to ten commits reachable by the *master* branch (starting at the latest commit). You can ask for commits beginning at a different branch, commit, tag, etc.
repo.commits('mybranch') repo.commits('40d3057d09a7a4d61059bca9dca5ae698de58cbe') repo.commits('v0.1')
You can specify the maximum number of commits to return.
repo.commits('master', 100)
If you need paging, you can specify a number of commits to skip.
repo.commits('master', 10, 20)
The above will return commits 21-30 from the commit list.
### The Commit object
`Commit` objects contain information about that commit.
head = repo.commits.first head.id # => "e80bbd2ce67651aa18e57fb0b43618ad4baf7750" head.parents # => [#<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">] head.tree # => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f"> head.author # => #<Grit::Actor "Tom Preston-Werner<EMAIL_ADDRESS>head.authored_date # => Wed Oct 24 22:02:31 -0700 2007 head.committer # => #<Grit::Actor "Tom Preston-Werner<EMAIL_ADDRESS>head.committed_date # => Wed Oct 24 22:02:31 -0700 2007 head.message # => "add Actor inspect"
You can traverse a commit’s ancestry by chaining calls to `parents`.
repo.commits.first.parents[0].parents[0].parents[0]
The above corresponds to **master^^^** or **master~3** in Git parlance.
### The Tree object
A tree records pointers to the contents of a directory. Let’s say you want the root tree of the latest commit on the *master* branch.
tree = repo.commits.first.tree # => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f"> tree.id # => "3536eb9abac69c3e4db583ad38f3d30f8db4771f"
Once you have a tree, you can get the contents.
contents = tree.contents # => [#<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">, #<Grit::Blob "81d2c27608b352814cbe979a6acd678d30219678">, #<Grit::Tree "c3d07b0083f01a6e1ac969a0f32b8d06f20c62e5">, #<Grit::Tree "4d00fe177a8407dbbc64a24dbfc564762c0922d8">]
This tree contains two `Blob` objects and two `Tree` objects. The trees are subdirectories and the blobs are files. Trees below the root have additional attributes.
contents.last.name # => "lib" contents.last.mode # => "040000"
There is a convenience method that allows you to get a named sub-object from a tree.
tree / "lib" # => #<Grit::Tree "e74893a3d8a25cbb1367cf241cc741bfd503c4b2">
You can also get a tree directly from the repo if you know its name.
repo.tree # => #<Grit::Tree "master"> repo.tree("91169e1f5fa4de2eaea3f176461f5dc784796769") # => #<Grit::Tree "91169e1f5fa4de2eaea3f176461f5dc784796769">
### The Blob object
A blob represents a file. Trees often contain blobs.
blob = tree.contents.first # => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
A blob has certain attributes.
blob.id # => "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666" blob.name # => "README.txt" blob.mode # => "100644" blob.size # => 7726
You can get the data of a blob as a string.
blob.data # => "Grit is a library to ..."
You can also get a blob directly from the repo if you know its name.
repo.blob("4ebc8aea50e0a67e000ba29a30809d0a7b9b2666") # => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
### Other
There are many more API methods available that are not documented here. Please reference the code for more functionality.
Copyright
Copyright © 2010 Tom Preston-Werner. See LICENSE for details.


'Dishonest' BJP govt mum on key questions about WhatsApp breach: Congress
According to sources, the WhatsApp has been asked to submit its response by November 4
by Press Trust of IndiaThe Congress on Saturday hit out at the Centre over the snooping controversy, saying a "dishonest" government is refusing to answer key questions like who purchased and deployed the illegal spyware used for the alleged surveillance.
On Thursday, Facebook-owned company WhatsApp had said Indian journalists and human rights activists were among those globally spied upon by unnamed entities using Israeli spyware Pegasus, leading to a furore over breach of citizens' privacy.
Congress' chief spokesperson Randeep Surjewala attacked the government saying that in May, WhatsApp had "quickly resolved a security issue and notified relevant Indian and international government authorities".
ALSO READ: WhatsApp says 'strong action' taken in spyware breach incident
"A dishonest BJP Govt refuses to answer relevant questions on #WhatsAppSpygate - 1. Who in GOI purchased & deployed the illegal spyware? 2. Who-PM or NSA-authorised the purchase? 3. If Facebook had informed GOI in May 2019, why was govt mum? 4.
What action against the guilty," he said in a tweet.
Following the disclosure by WhatsApp, the Indian government has asked the messaging platform to explain the matter and list out the measures that have been taken by it to safeguard the privacy of millions of Indians.
According to sources, the company has been asked to submit its response by November 4.