/usr/lib/python3/dist-packages/click/arfile.py is in python3-click 0.4.21.1.
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 | # Copyright (C) 2013 Canonical Ltd.
# Author: Colin Watson <cjwatson@ubuntu.com>
# 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; version 3 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""Basic support for writing ar archive files.
We do things this way so that Click packages can be created with minimal
dependencies (e.g. on non-Ubuntu systems). No read support is needed, since
Click packages are always installed on systems that have dpkg.
Some method names and general approach come from the tarfile module in
Python's standard library; details of the format come from dpkg.
"""
from __future__ import print_function
__metaclass__ = type
__all__ = [
'ArFile',
]
import os
import shutil
import time
class ArFile:
def __init__(self, name=None, mode="w", fileobj=None):
if mode != "w":
raise ValueError("only mode 'w' is supported")
self.mode = mode
self.real_mode = "wb"
if fileobj:
if name is None and hasattr(fileobj, "name"):
name = fileobj.name
if hasattr(fileobj, "mode"):
if fileobj.mode != "wb":
raise ValueError("fileobj must be opened with mode='wb'")
self._mode = fileobj.mode
self.opened_fileobj = False
else:
fileobj = open(name, self.real_mode)
self.opened_fileobj = True
self.name = name
self.fileobj = fileobj
self.closed = False
def close(self):
if self.opened_fileobj:
self.fileobj.close()
self.closed = True
def _check(self):
if self.closed:
raise IOError("ArFile %s is closed" % self.name)
def __enter__(self):
self._check()
return self
def __exit__(self, *args):
self.close()
def add_magic(self):
self.fileobj.write(b"!<arch>\n")
def add_header(self, name, size):
if len(name) > 15:
raise ValueError("ar member name '%s' length too long" % name)
if size > 9999999999:
raise ValueError("ar member size %d too large" % size)
header = ("%-16s%-12u0 0 100644 %-10d`\n" % (
name, int(time.time()), size)).encode()
assert len(header) == 60 # sizeof(struct ar_hdr)
self.fileobj.write(header)
def add_data(self, name, data):
size = len(data)
self.add_header(name, size)
self.fileobj.write(data)
if size & 1:
self.fileobj.write(b"\n") # padding
def add_file(self, name, path):
with open(path, "rb") as fobj:
size = os.fstat(fobj.fileno()).st_size
self.add_header(name, size)
shutil.copyfileobj(fobj, self.fileobj)
if size & 1:
self.fileobj.write(b"\n") # padding
|