L'attributo del file esterno del formato zip


25

Questa è una domanda leggermente esotica, ma non sembrano esserci molte informazioni in rete su questo. Ho appena aggiunto una risposta a una domanda sull'attributo del file esterno del formato zip . Come puoi vedere dalla mia risposta, concludo che solo il secondo byte (di 4 byte) viene effettivamente utilizzato per Unix. Apparentemente questo contiene informazioni sufficienti quando si decomprime per dedurre se l'oggetto è un file o una directory e ha anche spazio per altre informazioni su autorizzazioni e attributi. La mia domanda è: come si associa alle consuete autorizzazioni Unix? Esistono le consuete autorizzazioni Unix (ad es. Sotto) che si lsadattano esattamente a un byte e, in tal caso, qualcuno può descrivere il layout o fornire un riferimento, per favore?

$ 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

Vorrei renderlo più concreto ponendo una domanda specifica. Per la patch Trac citata nella mia risposta sopra, puoi creare un file zip con lo snippet di Python di seguito.

Il 040755 << 16Lvalore corrisponde alla creazione di una directory vuota con le autorizzazioni drwxr-xr-x. (L'ho provato). Riconosco 0755corrisponde al rwxr-xr-xmodello, ma per quanto riguarda il 04, e in che modo l'intero valore corrisponde a un byte? Riconosco anche che << 16Lcorrisponde a uno spostamento bit a sinistra di 16 posizioni, che lo farebbe finire come il secondo dal byte superiore.

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: Nel rileggere questo, penso che la mia conclusione che le autorizzazioni Unix corrispondono solo a un byte possa essere errata, ma lascerò che quanto sopra sia valido per il momento, poiché non sono sicuro di quale sia la risposta corretta.

EDIT2: in effetti non ero corretto riguardo ai valori Unix corrispondenti solo a 1 byte. Come spiegato da @ Random832, utilizza entrambi i primi due byte. Per la risposta di @ Random832, possiamo costruire il 040755valore desiderato dalle tabelle che fornisce di seguito. Vale a dire:

__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 

L'aggiunta qui è nella base 8 .


Non so nulla delle autorizzazioni zip, ma so che le autorizzazioni unix tradizionali usano 12 bit, che sono più di un byte. Forse zip non dà fastidio con setxid e sticky, ma questo lascia comunque 9 (rwx × ugo).
Gilles 'SO- smetti di essere malvagio' il

Risposte:


30

0040000è il valore tradizionale di S_IFDIR, il flag del tipo di file che rappresenta una directory. Il tipo utilizza i primi 4 bit del valore a 16 bit st_mode , 0100000è il valore per i file regolari.

I 16 bit alti degli attributi del file esterno sembrano essere utilizzati per autorizzazioni specifiche del sistema operativo. I valori Unix sono gli stessi delle implementazioni unix tradizionali. Altri sistemi operativi utilizzano altri valori. Informazioni sui formati utilizzati in una varietà di differenti sistemi operativi può essere trovato nel codice sorgente di Info-ZIP ( scaricare o ad esempio in debian apt-get source [zip or unzip]) - file in questione sono zipinfo.cin unzipei file della piattaforma-specifici zip.

Questi sono convenzionalmente definiti in ottale (base 8); questo è rappresentato in C e Python prefissando il numero con a 0.

Questi valori possono essere trovati in <sys/stat.h>- link alla versione 4.4BSD . Questi non sono nello standard POSIX (che definisce invece le macro di test); ma provengono da AT&T Unix e BSD. (in GNU libc / Linux, i valori stessi sono definiti come __S_IFDIRetc in bits/stat.h, sebbene l' intestazione del kernel potrebbe essere più facile da leggere - i valori sono praticamente tutti uguali ovunque).

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

E, naturalmente, gli altri 12 bit sono per le autorizzazioni e i bit setuid / setgid / sticky, come per 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 */

Come nota storica, il motivo 0100000è che i file regolari invece di 0 è che nelle primissime versioni di unix, 0 era per file "piccoli" (questi non utilizzavano blocchi indiretti nel filesystem) e il bit alto del flag mode era impostato per file "grandi" che utilizzerebbero blocchi indiretti. Gli altri due tipi che usano questo bit sono stati aggiunti in successivi sistemi operativi derivati ​​da unix, dopo che il filesystem era cambiato.

Quindi, per concludere, il layout generale del campo degli attributi estesi per Unix è

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

@ Random832: Wow, è incredibilmente completo e completo. Puoi anche spiegare come 040755 << 16Lviene costruito il valore ? In particolare, quale rappresentazione / base sta usando (penso possibilmente ottale ) e, soprattutto, come fa il linguaggio (l'interprete Python in questo caso) a sapere qual è la rappresentazione? Hmm, forse il tipo è dichiarato nel codice C. Inoltre, da quale file stai ottenendo i valori di "tipo di file"? L'aggiunta di alcuni collegamenti / riferimenti sarebbe utile.
Faheem Mitha,

@ Random832: Vedo che zipinfo.cè nella fonte per decomprimere su Debian . In alternativa si può usare il più conveniente apt-get source unzip. Puoi aggiungerlo alla tua risposta o utilizzare una fonte non a valle. Di solito cito Debian perché credo che saranno in giro per il lungo raggio. :-)
Faheem Mitha

@ Random832: Ok, penso di vedere come funziona. Devi solo sommare tutti i valori per le cose che sono impostati in base 8 come da tabella e ottieni il numero 040755. Vale la pena menzionare imo per le persone che non conoscono o hanno dimenticato. Naturalmente, ciò lascia ancora la questione di come sappia che è la base 8, ma forse il tipo è dichiarato come base 8.
Faheem Mitha

È base 8 perché inizia con uno 0.
Chiarirò

@Random: Grazie per il chiarimento. Non ero a conoscenza della principale convenzione 0. Il stat.hfile su Linux (suppongo che sia il file corretto /usr/include/sys/stat.h) non contiene la definizione di queste costanti in modo così chiaro come il file a cui si è collegati. Sono nascosti altrove? Vedo che hai usato il termine test macros, ma non sono sicuro di cosa significhi.
Faheem Mitha,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.