UNIXworkcode

/* * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE * Version 2, December 2004 * * Copyright (C) 2016 Olaf Wintermann <olaf.wintermann@gmail.com> * * Everyone is permitted to copy and distribute verbatim or modified * copies of this license document, and changing it is allowed as long * as the name is changed. * * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION * * 0. You just DO WHAT THE FUCK YOU WANT TO. */ /* * tool for copying extended attributes on FreeBSD */ #include <sys/types.h> #include <sys/extattr.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> int main(int argc, char **argv) { if(argc < 3) { fprintf(stderr, "usage: %s <srcfile> <destfile>\n", argv[0]); return -1; } int src = open(argv[1], O_RDONLY); if(src == -1) { fprintf(stderr, "Cannot open %s: ", argv[1]); perror(NULL); return -1; } int dst = open(argv[2], O_WRONLY); if(dst == -1) { fprintf(stderr, "Cannot open %s: ", argv[2]); perror(NULL); return -1; } // get length of attributes list ssize_t lslen = extattr_list_fd(src, EXTATTR_NAMESPACE_USER, NULL, 0); if(lslen < 0) { perror("extattr_list_fd"); return -1; } if(lslen == 0) { return 0; } // get attributes list char *list = malloc(lslen + 1); lslen = extattr_list_fd(src, EXTATTR_NAMESPACE_USER, list, lslen); if(lslen < 0) { perror("extattr_list_fd"); return -1; } for(int i=0;i<lslen;i++) { char namelen = list[i]; char *name = list + i + 1; char nextlen = list[i + namelen + 1]; // save length of next name list[i + namelen + 1] = '\0'; // terminate string temporary // get xattr from src and add it to dst printf("%s\n", name); ssize_t len = extattr_get_fd(src, EXTATTR_NAMESPACE_USER, name, NULL, 0); if(len > 0) { char *value = malloc(len); len = extattr_get_fd(src, EXTATTR_NAMESPACE_USER, name, value, len); if(len > 0) { if(extattr_set_fd(dst, EXTATTR_NAMESPACE_USER, name, value, len) == -1) { perror("extattr_set_fd"); } } else { perror("extattr_get_fd"); } free(value); } else { perror("extattr_get_fd"); } list[i + namelen + 1] = nextlen; // restore length i += namelen; } return 0; }