/usr/lib/python2.7/dist-packages/linkcheck/ftpparse.py is in linkchecker 9.3-4.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 | # -*- coding: iso-8859-1 -*-
# Copyright (C) 2009-2014 Bastian Kleineidam
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
"""
Python implementation of a part of Dan Bernstein's ftpparse library.
See also http://cr.yp.to/ftpparse.html
"""
months = ("jan", "feb", "mar", "apr", "may", "jun", "jul", "aug", "sep",
"oct", "nov", "dec")
def ismonth (txt):
"""Check if given text is a month name."""
return txt.lower() in months
def ftpparse (line):
"""Parse a FTP list line into a dictionary with attributes:
name - name of file (string)
trycwd - False if cwd is definitely pointless, True otherwise
tryretr - False if retr is definitely pointless, True otherwise
If the line has no file information, None is returned
"""
if len(line) < 2:
# an empty name in EPLF, with no info, could be 2 chars
return None
info = dict(name=None, trycwd=False, tryretr=False)
# EPLF format
# http://pobox.com/~djb/proto/eplf.html
# "+i8388621.29609,m824255902,/,\tdev"
# "+i8388621.44468,m839956783,r,s10376,\tRFCEPLF"
if line[0] == '+':
if '\t' in line:
flags, name = line.split('\t', 1)
info['name'] = name
flags = flags.split(',')
info['trycwd'] = '/' in flags
info['tryretr'] = 'r' in flags
return info
# UNIX-style listing, without inum and without blocks
# "-rw-r--r-- 1 root other 531 Jan 29 03:26 README"
# "dr-xr-xr-x 2 root other 512 Apr 8 1994 etc"
# "dr-xr-xr-x 2 root 512 Apr 8 1994 etc"
# "lrwxrwxrwx 1 root other 7 Jan 25 00:17 bin -> usr/bin"
# Also produced by Microsoft's FTP servers for Windows:
# "---------- 1 owner group 1803128 Jul 10 10:18 ls-lR.Z"
# "d--------- 1 owner group 0 May 9 19:45 Softlib"
# Also WFTPD for MSDOS:
# "-rwxrwxrwx 1 noone nogroup 322 Aug 19 1996 message.ftp"
# Also NetWare:
# "d [R----F--] supervisor 512 Jan 16 18:53 login"
# "- [R----F--] rhesus 214059 Oct 20 15:27 cx.exe"
# Also NetPresenz for the Mac:
# "-------r-- 326 1391972 1392298 Nov 22 1995 MegaPhone.sit"
# "drwxrwxr-x folder 2 May 10 1996 network"
if line[0] in 'bcdlps-':
if line[0] == 'd':
info['trycwd'] = True
if line[0] == '-':
info['tryretr'] = True
if line[0] == 'l':
info['trycwd'] = info['tryretr'] = True
parts = line.split()
if len(parts) < 7:
return None
del parts[0] # skip permissions
if parts[0] != 'folder':
del parts[0] # skip nlink
del parts[0] # skip uid
del parts[0] # skip gid or size
if not ismonth(parts[0]):
del parts[0] # skip size
if not ismonth(parts[0]):
return None
del parts[0] # skip month
del parts[0] # skip day
if not parts:
return None
del parts[0] # skip year or time
name = " ".join(parts)
# resolve links
if line[0] == 'l' and ' -> ' in name:
name = name.split(' -> ', 1)[1]
# eliminate extra NetWare spaces
if line[1] in ' [' and name.startswith(' '):
name = name[3:]
info["name"] = name
return info
# MultiNet (some spaces removed from examples)
# "00README.TXT;1 2 30-DEC-1996 17:44 [SYSTEM] (RWED,RWED,RE,RE)"
# "CORE.DIR;1 1 8-SEP-1996 16:09 [SYSTEM] (RWE,RWE,RE,RE)"
# and non-MutliNet VMS:
# "CII-MANUAL.TEX;1 213/216 29-JAN-1996 03:33:12 [ANONYMOU,ANONYMOUS] (RWED,RWED,,)"
i = line.find(';')
if i != -1:
name = line[:i]
if name.endswith(".DIR"):
name = name[:-4]
info["trycwd"] = True
else:
info["tryretr"] = True
info["name"] = name
return info
# MSDOS format
# 04-27-00 09:09PM <DIR> licensed
# 07-18-00 10:16AM <DIR> pub
# 04-14-00 03:47PM 589 readme.htm
if line[0].isdigit():
parts = line.split()
if len(parts) != 4:
return None
info['name'] = parts[3]
if parts[2][0] == '<':
info['trycwd'] = True
else:
info['tryretr'] = True
return info
# Some useless lines, safely ignored:
# "Total of 11 Files, 10966 Blocks." (VMS)
# "total 14786" (UNIX)
# "DISK$ANONFTP:[ANONYMOUS]" (VMS)
# "Directory DISK$PCSA:[ANONYM]" (VMS)
return None
|