Skip to content

Instantly share code, notes, and snippets.

@rsky
Created January 23, 2011 15:44
Show Gist options
  • Save rsky/792155 to your computer and use it in GitHub Desktop.
Save rsky/792155 to your computer and use it in GitHub Desktop.
HFS+の拡張属性を取り除くコマンドラインツール
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/errno.h>
#include <sys/xattr.h>
#include <sys/param.h>
#include <libgen.h>
/*
cc -Wall -Wextra -Os -std=c99 -o xattr-clean xattr-clean.c
cc -Wall -Wextra -Os -std=c99 -m32 -o xattr-clean xattr-clean.c
cc -Wall -Wextra -Os -std=c99 -m64 -o xattr-clean xattr-clean.c
cc -Wall -Wextra -Os -std=c99 -arch i386 -arch ppc -o xattr-clean xattr-clean.c
cc -Wall -Wextra -Os -std=c99 -arch ppc -arch ppc64 -arch i386 -arch x86_64 -o xattr-clean xattr-clean.c
*/
static const int options = XATTR_NOFOLLOW;
static char pathbuf[MAXPATHLEN];
static void raise_error(int errnum)
{
switch (errnum) {
case ENOTSUP:
fprintf(stderr, "Filesystem does not support extended attributes.\n");
break;
case ENOATTR:
fprintf(stderr, "The extended attribute does not exist.\n");
break;
case ERANGE:
fprintf(stderr, "Buffer size is too small.\n");
break;
case EINVAL:
fprintf(stderr, "Options does not make sense.\n");
break;
default:
fprintf(stderr, "Cannot get extended attributes: %s.\n", strerror(errnum));
}
}
static void clean_xattr(const char *path)
{
printf("%s\n", path);
if (strlen(path) >= MAXPATHLEN) {
raise_error(ENAMETOOLONG);
exit(ENAMETOOLONG);
}
ssize_t check = listxattr(path, NULL, 0, options);
if (check == -1) {
int errnum = errno;
raise_error(errnum);
exit(errnum);
} else if (check == 0) {
return;
}
size_t size = (size_t)check;
char *buffer = (char *)malloc(size);
if (!buffer) {
fprintf(stderr, "Cannot allocate %zu bytes!\n", size);
exit(ENOMEM);
}
listxattr(path, buffer, size, options);
strcpy(pathbuf, path);
const char *name = basename(pathbuf);
const char *attr = buffer;
const char *eos = attr + size;
while (attr < eos) {
if (removexattr(path, attr, options) == -1) {
int errnum = errno;
free(buffer);
raise_error(errnum);
exit(errnum);
}
printf("%s: %s\n", name, attr);
attr = attr + strlen(attr) + 1;
}
free(buffer);
}
int main(int argc, const char *argv[])
{
if (argc < 2) {
fprintf(stderr, "argument required!\n");
return 1;
}
int i = 1;
while (i < argc) {
clean_xattr(argv[i]);
i++;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment