Ottieni attributi estesi del file in C
-
Usa le funzioni
getxattr
elistxattr
per ottenere attributi estesi del file -
Usa la funzione
setxattr
per impostare attributi estesi su file
Questo articolo spiegherà diversi metodi su come ottenere attributi estesi di un file in C.
Usa le funzioni getxattr
e listxattr
per ottenere attributi estesi del file
Alcuni sistemi basati su UNIX forniscono attributi estesi per i file, che rappresentano coppie nome-valore di metadati che possono essere associati al file. Gli attributi estesi richiedono il supporto del file system sottostante, ma i tipi di file system comuni hanno questa caratteristica. Gli attributi estesi hanno il formato specifico di tipo - namespace.name
, dove namespace
è utilizzato per raggruppare quelli funzionalmente simili, mentre la parte name
identifica un singolo attributo esteso. Uno spazio dei nomi può avere i seguenti valori: user
, trusted
, system
e security
, che distinguono diversi tipi di autorizzazione come convenzione (descritti in dettaglio nella pagina). In questo caso, implementiamo un programma di esempio che accetta più nomi di file come argomenti della linea di comando e di conseguenza recupera tutti gli attributi estesi per ogni file. Si noti che il programma elabora più argomenti di file con la funzione getopt
.
La funzione getxattr
richiede quattro argomenti per recuperare un valore di attributo esteso. Il primo argomento specifica un percorso nel filesystem per indicare il file per il quale devono essere recuperati gli EA, e il secondo argomento specifica un nome di attributo. Gli ultimi due argomenti sono il puntatore alla posizione in cui il valore verrà memorizzato da getxattr
e la dimensione del buffer disponibile su questo indirizzo. Si noti che la dimensione del valore dell’attributo può essere recuperata passando il valore 0
come argomento della dimensione e il valore di ritorno della chiamata è il numero di byte per il buffer necessario. Sebbene, quando la seconda chiamata viene invocata per recuperare il valore, potrebbe essere modificata e avere una dimensione diversa; quindi, è meglio controllare i codici di errore per garantire un’esecuzione senza errori.
D’altra parte, la funzione listxattr
recupera l’lista dei nomi degli attributi estesi per il percorso del file specificato. Richiede tre argomenti, il primo dei quali è il percorso del file. I due argomenti successivi rappresentano il buffer in cui verrà memorizzato l’lista recuperato e la sua dimensione specificata in byte. Si noti che questo buffer è allocato al chiamante e il chiamante è responsabile dell’allocazione di memoria sufficiente. Inoltre, in modo simile a getxattr
, si può passare il valore 0
come terzo argomento a questa funzione, e il valore restituito sarà la dimensione del buffer necessaria per memorizzare l’lista completo.
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/xattr.h>
#include <unistd.h>
#define XATTR_SIZE 10000
#define errExit(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
static void usageError(char *progName) {
fprintf(stderr, "Usage: %s [-x] file...\n", progName);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
char list[XATTR_SIZE], value[XATTR_SIZE];
ssize_t listLen, valueLen;
int ns, j, k, opt;
bool hexDisplay;
hexDisplay = 0;
while ((opt = getopt(argc, argv, "x")) != -1) {
switch (opt) {
case 'x':
hexDisplay = 1;
break;
case '?':
usageError(argv[0]);
}
}
if (optind >= argc) usageError(argv[0]);
for (j = optind; j < argc; j++) {
listLen = listxattr(argv[j], list, XATTR_SIZE);
if (listLen == -1) errExit("listxattr");
printf("%s:\n", argv[j]);
for (ns = 0; ns < listLen; ns += strlen(&list[ns]) + 1) {
printf(" name=%s; ", &list[ns]);
valueLen = getxattr(argv[j], &list[ns], value, XATTR_SIZE);
if (valueLen == -1) {
printf("couldn't get value");
} else if (!hexDisplay) {
printf("value=%.*s", (int)valueLen, value);
} else {
printf("value=");
for (k = 0; k < valueLen; k++) printf("%02x ", (unsigned char)value[k]);
}
printf("\n");
}
printf("\n");
}
exit(EXIT_SUCCESS);
}
Usa la funzione setxattr
per impostare attributi estesi su file
In alternativa, possiamo impostare attributi arbitrari ai file usando la funzione setxattr
, che prende il percorso del file, la coppia nome-valore come argomenti separati, la dimensione del valore, un numero intero che specifica i valori predefiniti per diverse operazioni sugli insiemi. Se l’ultimo argomento è zero, che è il valore predefinito, l’attributo esteso viene creato se non esiste; in caso contrario, il valore viene sostituito. La macro XATTR_CREATE
può essere specificata per indicare solo l’opzione di creazione, che fallirà se l’attributo esiste, e XATTR_REPLACE
per eseguire la sostituzione che fallisce se l’attributo non esiste.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/xattr.h>
#define errExit(msg) \
do { \
perror(msg); \
exit(EXIT_FAILURE); \
} while (0)
static void usageError(char *progName) {
fprintf(stderr, "Usage: %s file\n", progName);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
char *value;
if (argc < 2 || strcmp(argv[1], "--help") == 0) usageError(argv[0]);
value = "x attribute value";
if (setxattr(argv[1], "user.x", value, strlen(value), 0) == -1)
errExit("setxattr");
value = "y attribute value";
if (setxattr(argv[1], "user.y", value, strlen(value), 0) == -1)
errExit("setxattr");
exit(EXIT_SUCCESS);
}
Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.
LinkedIn Facebook