Atribut file eksternal format zip

25

Ini adalah pertanyaan yang agak eksotis, tetapi sepertinya tidak ada banyak informasi di internet tentang ini. Saya baru saja menambahkan jawaban untuk pertanyaan tentang atribut file eksternal format zip . Seperti yang Anda lihat dari jawaban saya, saya menyimpulkan bahwa hanya byte kedua (4 byte) yang benar-benar digunakan untuk Unix. Rupanya ini berisi informasi yang cukup ketika membuka ritsleting untuk menyimpulkan apakah objek adalah file atau direktori, dan juga memiliki ruang untuk izin lainnya dan informasi atribut. Pertanyaan saya adalah, bagaimana cara memetakan ini ke izin Unix yang biasa? Apakah izin Unix yang biasa (misalnya di bawah) yang lsmemberikan kesesuaian tepat satu byte, dan jika demikian, dapatkah seseorang menggambarkan tata letak atau memberikan referensi, tolong?

$ 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

Biarkan saya membuat ini lebih konkret dengan mengajukan pertanyaan spesifik. Per tambalan Trac yang dikutip dalam jawaban saya di atas, Anda dapat membuat file zip dengan potongan Python di bawah ini.

The 040755 << 16Lnilai sesuai dengan penciptaan direktori kosong dengan izin drwxr-xr-x. (Saya mengujinya). Saya mengenali 0755koresponden dengan rwxr-xr-xpola, tetapi bagaimana dengan 04, dan bagaimana seluruh nilai sesuai dengan byte? Saya juga mengenali << 16Lberkorespondensi dengan pergeseran kiri bitwise 16 tempat, yang akan membuatnya berakhir sebagai yang kedua dari byte atas.

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()

EDIT: Pada membaca ulang ini, saya pikir kesimpulan saya bahwa izin Unix hanya sesuai dengan satu byte mungkin salah, tetapi saya akan membiarkan di atas berdiri untuk saat ini, karena saya tidak yakin apa jawaban yang benar.

EDIT2: Saya memang salah tentang nilai-nilai Unix hanya sesuai dengan 1 byte. Seperti yang dijelaskan oleh @ Random832, ia menggunakan kedua dari dua byte teratas. Per @ Random832 menjawab, kita bisa membuat nilai yang diinginkan 040755dari tabel yang dia berikan di bawah ini. Yaitu:

__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 

Tambahan di sini ada di basis 8 .

Faheem Mitha
sumber
Saya tidak tahu tentang izin zip, tapi saya tahu bahwa izin unix tradisional menggunakan 12 bit, yang lebih dari satu byte. Mungkin zip tidak repot dengan setxid dan lengket, tetapi masih menyisakan 9 (rwx × ugo).
Gilles 'SO- berhenti bersikap jahat'

Jawaban:

30

0040000adalah nilai tradisional dari S_IFDIR, jenis bendera file yang mewakili direktori. Jenis ini menggunakan 4 bit teratas dari nilai 16-bit st_mode , 0100000adalah nilai untuk file biasa.

Atribut file eksternal 16 bit tinggi tampaknya digunakan untuk izin khusus OS. Nilai-nilai Unix sama dengan pada implementasi unix tradisional. OS lain menggunakan nilai lain. Informasi tentang format yang digunakan dalam berbagai OS yang berbeda dapat ditemukan dalam kode sumber Info-ZIP ( unduh atau mis. Dalam bahasa debian apt-get source [zip or unzip]) - file yang relevan ada zipinfo.cdi dalamnya unzip, dan file khusus platform di zip.

Ini secara konvensional didefinisikan dalam oktal (basis 8); ini direpresentasikan dalam C dan python dengan mengawali angka dengan a 0.

Semua nilai ini dapat ditemukan di <sys/stat.h>- tautan ke versi 4.4BSD . Ini tidak dalam standar POSIX (yang mendefinisikan makro pengujian sebagai gantinya); tetapi berasal dari AT&T Unix dan BSD. (dalam GNU libc / Linux, nilai-nilai itu sendiri didefinisikan sebagai __S_IFDIRetc in bits/stat.h, meskipun header kernel mungkin lebih mudah dibaca - nilainya hampir sama di mana-mana.)

#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 */

Dan tentu saja, 12 bit lainnya adalah untuk perizinan dan bit setuid / setgid / sticky, sama seperti untuk 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 */

Sebagai catatan historis, alasannya 0100000adalah untuk file biasa, bukan 0 adalah bahwa dalam versi unix yang sangat awal, 0 adalah untuk file 'kecil' (ini tidak menggunakan blok tidak langsung dalam sistem file) dan bit mode flag yang tinggi adalah set untuk file 'besar' yang akan menggunakan blok tidak langsung. Dua tipe lain yang menggunakan bit ini ditambahkan dalam OS yang diturunkan kemudian, setelah filesystem berubah.

Jadi, untuk menyelesaikannya, tata letak keseluruhan bidang atribut yang diperluas untuk Unix adalah

TTTTsstrwxrwxrwx0000000000ADVSHR
^^^^____________________________ file type as explained above
    ^^^_________________________ setuid, setgid, sticky
       ^^^^^^^^^________________ permissions
                ^^^^^^^^________ This is the "lower-middle byte" your post mentions
                        ^^^^^^^^ DOS attribute bits
Random832
sumber
@ Random832: Wow, itu mengesankan selesai dan selesai. Bisakah Anda juga menjelaskan bagaimana nilainya 040755 << 16Ldibangun? Secara khusus, representasi / basis apa yang digunakannya (saya pikir mungkin Octal ), dan yang paling penting, bagaimana bahasa (juru bahasa Python dalam kasus ini) mengetahui apa representasi itu? Hmm, mungkin jenisnya dinyatakan dalam kode C. Selain itu, file apa yang Anda dapatkan dari nilai "tipe file"? Menambahkan beberapa tautan / referensi akan sangat membantu.
Faheem Mitha
@ Random832: Saya melihat bahwa zipinfo.cada di sumber untuk unzip di Debian . Atau seseorang dapat menggunakan yang lebih nyaman apt-get source unzip. Anda dapat menambahkannya ke jawaban Anda, atau menggunakan sumber yang tidak mengalir. Saya biasanya mengutip Debian karena saya yakin mereka akan ada untuk jangka panjang. :-)
Faheem Mitha
@ Random832: Oke, saya rasa saya mengerti cara kerjanya. Anda cukup menambahkan bersama semua nilai untuk hal-hal yang ditetapkan dalam basis 8 sesuai tabel Anda, dan Anda mendapatkan nomornya 040755. Itu akan layak disebut imo untuk orang-orang yang tidak tahu atau lupa. Tentu saja, itu masih menyisakan pertanyaan tentang bagaimana ia mengetahui basis 8, tetapi mungkin tipe tersebut dinyatakan sebagai basis 8.
Faheem Mitha
Ini basis 8 karena dimulai dengan 0. Saya akan mengklarifikasi bahwa dalam edit
Random832
@Random: Terima kasih atas klarifikasi. Saya tidak mengetahui konvensi 0 terkemuka. The stat.hfile di Linux (aku mengasumsikan file yang benar adalah /usr/include/sys/stat.h) tidak mengandung definisi konstanta ini sedemikian rupa jelas file yang terkait dengan. Apakah mereka disembunyikan di tempat lain? Saya melihat Anda menggunakan istilah itu test macros, tetapi saya tidak yakin apa artinya itu.
Faheem Mitha