#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef _WIN32
#include <Windows.h>
#endif
#include "libxattr.h"
int attrtool_list(
int argc,
char **argv,
int values);
int attrtool_get(
int argc,
char **argv,
int raw);
int attrtool_set(
int argc,
char **argv);
int attrtool_rm(
int argc,
char **argv);
void print_usage(
char *cmd) {
fprintf(stderr,
"usage %s:\n", cmd);
fprintf(stderr,
" list <file>\n");
fprintf(stderr,
" listvalues <file>\n");
fprintf(stderr,
" get <file> <name>\n");
fprintf(stderr,
" set <file> <name> <value>\n");
fprintf(stderr,
" remove <file> <name>\n");
}
int xattr_tool_main(
int argc,
char **argv);
#ifdef _WIN32
static char* wchar2utf8(
const wchar_t *wstr,
size_t wlen) {
size_t maxlen = wlen *
4;
char *ret = malloc(maxlen +
1);
int ret_len = WideCharToMultiByte(
CP_UTF8,
0,
wstr,
wlen,
ret,
maxlen,
NULL,
NULL);
ret[ret_len] =
0;
return ret;
}
int wmain(
int argc,
wchar_t **argv) {
char **argv_utf8 = calloc(argc,
sizeof(
char*));
for(
int i=
0;i<argc;i++) {
argv_utf8[i] = wchar2utf8(argv[i], wcslen(argv[i]));
}
int ret = xattr_tool_main(argc, argv_utf8);
for(
int i=
0;i<argc;i++) {
free(argv_utf8[i]);
}
free(argv_utf8);
return ret;
}
#else
int main(
int argc,
char **argv) {
return xattr_tool_main(argc, argv);
}
#endif
int xattr_tool_main(
int argc,
char **argv) {
if(argc <
3) {
print_usage(argv[
0]);
return 1;
}
if(!strcmp(argv[
1],
"list") || !strcmp(argv[
1],
"ls")) {
return attrtool_list(argc, argv,
0);
}
else if(!strcmp(argv[
1],
"listvalues") || !strcmp(argv[
1],
"lsv")) {
return attrtool_list(argc, argv,
1);
}
else if(!strcmp(argv[
1],
"get")) {
return attrtool_get(argc, argv,
0);
}
else if(!strcmp(argv[
1],
"set")) {
return attrtool_set(argc, argv);
}
else if(!strcmp(argv[
1],
"rm") || !strcmp(argv[
1],
"remove")) {
return attrtool_rm(argc, argv);
}
else {
fprintf(stderr,
"Unknown command\n");
print_usage(argv[
0]);
}
return 1;
}
int attrtool_list(
int argc,
char **argv,
int values) {
ssize_t nelm =
0;
char **list = xattr_list(argv[
2], &nelm);
if(nelm <
0) {
perror(
"xattr_list");
return 3;
}
for(
int i=
0;i<nelm;i++) {
char *attr = list[i];
if(values) {
ssize_t valuelen =
0;
char *value = xattr_get(argv[
2], attr, &valuelen);
if(valuelen <
0) {
printf(
"%s: #ERROR: %s\n", attr, strerror(errno));
}
else {
printf(
"%s: %.*s\n", attr, (
int)valuelen, value);
}
if(value) {
free(value);
}
}
else {
printf(
"%s\n", attr);
}
free(list[i]);
}
if(list) {
free(list);
}
return 0;
}
int attrtool_get(
int argc,
char **argv,
int raw) {
if(argc <
4) {
fprintf(stderr,
"Too few arguments\n");
print_usage(argv[
1]);
return 1;
}
char *file = argv[
2];
char *attr = argv[
3];
int ret =
0;
ssize_t valuelen =
0;
char *value = xattr_get(file, attr, &valuelen);
if(value) {
if(raw) {
fwrite(value,
1, valuelen, stdout);
}
else {
printf(
"%.*s\n", (
int)valuelen, value);
}
free(value);
}
else {
perror(
"xattr_get");
ret =
3;
}
return ret;
}
int attrtool_set(
int argc,
char **argv) {
if(argc <
4) {
fprintf(stderr,
"Too few arguments\n");
print_usage(argv[
1]);
return 1;
}
size_t len = strlen(argv[
4]);
char *file = argv[
2];
char *attr = argv[
3];
char *value = argv[
4];
int ret =
0;
if(xattr_set(file, attr, value, len)) {
perror(
"xattr_set");
ret =
3;
}
return ret;
}
int attrtool_rm(
int argc,
char **argv) {
if(argc <
4) {
fprintf(stderr,
"Too few arguments\n");
print_usage(argv[
1]);
return 1;
}
char *file = argv[
2];
char *attr = argv[
3];
int ret =
0;
if(xattr_remove(file, attr)) {
perror(
"xattr_remove");
ret =
1;
}
return ret;
}