zip形式の外部ファイル属性


25

これは少しエキゾチックな質問ですが、これに関する情報はネット上にあまりないようです。zip形式の外部ファイル属性に関する質問への回答を追加しまし。私の答えからわかるように、Unixでは実際には2バイト(4バイト)しか使用されていないと結論付けています。どうやらこれは、オブジェクトがファイルであるかディレクトリであるかを推測するために解凍するときに十分な情報を含み、他の許可と属性情報のためのスペースも持っています。私の質問は、これが通常のUnixパーミッションにどのようにマッピングされるのかということです。ls正確に1バイトに収まる通常のUnixアクセス許可(たとえば、以下)を実行します。そうであれば、誰かがレイアウトを説明したり、参照を提供したりできますか?

$ ls -la
total 36
drwxr-xr-x   3 faheem faheem  4096 Jun 10 01:11 .
drwxrwxrwt 136 root   root   28672 Jun 10 01:07 ..
-rw-r--r--   1 faheem faheem     0 Jun 10 01:07 a
drwxr-xr-x   2 faheem faheem  4096 Jun 10 01:07 b
lrwxrwxrwx   1 faheem faheem     1 Jun 10 01:11 c -> b

具体的な質問をして、これをより具体的にしましょう。上記の私の回答で引用したTracパッチに従って、以下のPythonのスニペットでzipファイルを作成できます。

040755 << 16L値は、権限を持つ空のディレクトリの作成に対応しますdrwxr-xr-x。(テストしました)。私0755rwxr-xr-xパターンに対応していることを認識していますが、については04どうですか、また値全体はどのようにバイトに対応していますか?また<< 16L、16桁のビット単位の左シフトに対応することも認識しています。これにより、最上位バイトから2番目にシフトします。

def makezip1():
    import zipfile
    z = zipfile.ZipFile("foo.zip", mode = 'w')
    zfi = zipfile.ZipInfo("foo/empty/")
    zfi.external_attr = 040755 << 16L # permissions drwxr-xr-x
    z.writestr(zfi, "")
    print z.namelist()
    z.close()

編集:これを読み直すと、Unixのアクセス許可は1バイトにしか対応していないという私の結論は間違っているかもしれませんが、正しい答えがわからないので、上記を現在のままにしておきます。

EDIT2:1バイトのみに対応するUnix値については、実際に間違っていました。@ Random832が説明したように、上位2バイトの両方を使用します。@ Random832の答えによれば040755、彼が下に示す表から目的の値を作成できます。すなわち:

__S_IFDIR + S_IRUSR + S_IWUSR + S_IXUSR + S_IRGRP + S_IXGRP + S_IROTH + S_IXOTH
0040000   + 0400    + 0200    + 0100    + 0040    + 0010    + 0004    + 0001
= 40755 

ここの追加はベース8にあります。


zipパーミッションについては何も知りませんが、従来のUNIXパーミッションでは12ビット(1バイト以上)を使用することを知っています。zipはsetxidとstickyに悩まされないかもしれませんが、それでも9(rwx×ugo)のままです。
ジル 'SO-悪であるのをやめる'

回答:


30

0040000は、S_IFDIRディレクトリを表すファイルタイプフラグであるの従来の値です。タイプは、16ビット st_mode値の上位4ビットを使用し、0100000通常のファイルの値です。

外部ファイル属性の上位16ビットは、OS固有の許可に使用されているようです。Unixの値は、従来のUNIX実装と同じです。他のOSは他の値を使用します。さまざまなOSで使用される形式に関する情報は、Info-ZIPソースコード(ダウンロードまたはdebianなどapt-get source [zip or unzip])にあります。関連ファイルはzipinfo.cunzipあり、プラットフォーム固有のファイルはにありzipます。

これらは通常、8進数(基数8)で定義されます。これは、番号の前にaを付けることでCおよびpythonで表され0ます。

これらの値は、すべての中に見つけることができます<sys/stat.h>- 4.4BSDのバージョンへのリンク。これらはPOSIX標準ではありません(代わりにテストマクロを定義します)。ただし、AT&T UnixおよびBSDに由来します。(GNU libc / Linuxでは、値自体は__S_IFDIRなどで定義されbits/stat.hますが、カーネルヘッダーは読みやすいかもしれません-値はどこでもほぼ同じです。)

#define S_IFIFO  0010000  /* named pipe (fifo) */
#define S_IFCHR  0020000  /* character special */
#define S_IFDIR  0040000  /* directory */
#define S_IFBLK  0060000  /* block special */
#define S_IFREG  0100000  /* regular */
#define S_IFLNK  0120000  /* symbolic link */
#define S_IFSOCK 0140000  /* socket */

そしてもちろん、他の12ビットはパーミッションとsetuid / setgid / stickyビット用であり、chmodと同じです:

#define S_ISUID 0004000 /* set user id on execution */
#define S_ISGID 0002000 /* set group id on execution */
#define S_ISTXT 0001000 /* sticky bit */
#define S_IRWXU 0000700 /* RWX mask for owner */
#define S_IRUSR 0000400 /* R for owner */
#define S_IWUSR 0000200 /* W for owner */
#define S_IXUSR 0000100 /* X for owner */
#define S_IRWXG 0000070 /* RWX mask for group */
#define S_IRGRP 0000040 /* R for group */
#define S_IWGRP 0000020 /* W for group */
#define S_IXGRP 0000010 /* X for group */
#define S_IRWXO 0000007 /* RWX mask for other */
#define S_IROTH 0000004 /* R for other */
#define S_IWOTH 0000002 /* W for other */
#define S_IXOTH 0000001 /* X for other */
#define S_ISVTX 0001000 /* save swapped text even after use */

歴史的なメモとして、理由0100000は、0の代わりに通常のファイルの場合です。unixの非常に初期のバージョンでは、0は「小さな」ファイル(これらはファイルシステムで間接ブロックを使用しませんでした)であり、モードフラグの上位ビットは間接ブロックを使用する「大きな」ファイルに設定します。このビットを使用する他の2つのタイプは、ファイルシステムが変更された後に、後のUNIX派生OSで追加されました。

したがって、最後に、Unixの拡張属性フィールドの全体的なレイアウトは次のとおりです。

TTTTsstrwxrwxrwx0000000000ADVSHR
^^^^____________________________ file type as explained above
    ^^^_________________________ setuid, setgid, sticky
       ^^^^^^^^^________________ permissions
                ^^^^^^^^________ This is the "lower-middle byte" your post mentions
                        ^^^^^^^^ DOS attribute bits

@ Random832:うわー、それは見事に完了しました。また、値040755 << 16Lがどのように構築されるかを説明できますか?具体的には、どの表現/ベースを使用していますか(おそらくOctalと思います)、そして最も重要なことは、言語(この場合はPythonインタープリター)はどのように表現が知っているのですか?うーん、多分型はCコードで宣言されています。また、どのファイルから「ファイルタイプ」の値を取得していますか?いくつかのリンク/参照を追加すると役立ちます。
ファヒムミタ

@ Random832:Debianのunzipzipinfo.cソースにあるようです。または、より便利なを使用できますapt-get source unzip。回答に追加するか、アンストリームソースを使用できます。私は通常、Debianを引用します。なぜなら、彼らは長い間存在し続けると信じているからです。:-)
Faheem Mitha

@ Random832:わかりました、私はこれがどのように機能するか見ると思います。テーブルごとにベース8に設定されているもののすべての値を加算すると、数値が得られます040755。それは、知らない人や忘れてしまった人のためにimoに言及する価値があります。もちろん、それはまだそれがそれを知っているかの質問がベース8、多分タイプがベース8のように宣言されている葉
Faheem Mitha

0で始まるため、8を基数としています。編集でそれを明確にします
Random832

@ランダム:説明をありがとう。先行する0の慣習を知りませんでした。stat.hLinux上のファイル(正しいファイルであると仮定しています/usr/include/sys/stat.h)には、リンク先のファイルのような明確な方法でこれらの定数の定義が含まれていません。彼らはどこかに隠されていますか?あなたは用語を使用してtest macrosいるようですが、それが何を意味するのか分かりません。
ファヒームミサ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.