UNIXworkcode

1 /* 2 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 3 * Version 2, December 2004 4 * 5 * Copyright (C) 2016 Olaf Wintermann <olaf.wintermann@gmail.com> 6 * 7 * Everyone is permitted to copy and distribute verbatim or modified 8 * copies of this license document, and changing it is allowed as long 9 * as the name is changed. 10 * 11 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 12 * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 13 * 14 * 0. You just DO WHAT THE FUCK YOU WANT TO. 15 */ 16 17 /* 18 * tool for copying extended attributes on FreeBSD 19 */ 20 21 #include <sys/types.h> 22 #include <sys/extattr.h> 23 24 #include <stdio.h> 25 #include <stdlib.h> 26 #include <unistd.h> 27 #include <fcntl.h> 28 29 int main(int argc, char **argv) { 30 if(argc < 3) { 31 fprintf(stderr, "usage: %s <srcfile> <destfile>\n", argv[0]); 32 return -1; 33 } 34 35 int src = open(argv[1], O_RDONLY); 36 if(src == -1) { 37 fprintf(stderr, "Cannot open %s: ", argv[1]); 38 perror(NULL); 39 return -1; 40 } 41 42 int dst = open(argv[2], O_WRONLY); 43 if(dst == -1) { 44 fprintf(stderr, "Cannot open %s: ", argv[2]); 45 perror(NULL); 46 return -1; 47 } 48 49 // get length of attributes list 50 ssize_t lslen = extattr_list_fd(src, EXTATTR_NAMESPACE_USER, NULL, 0); 51 if(lslen < 0) { 52 perror("extattr_list_fd"); 53 return -1; 54 } 55 if(lslen == 0) { 56 return 0; 57 } 58 59 // get attributes list 60 char *list = malloc(lslen + 1); 61 lslen = extattr_list_fd(src, EXTATTR_NAMESPACE_USER, list, lslen); 62 if(lslen < 0) { 63 perror("extattr_list_fd"); 64 return -1; 65 } 66 67 for(int i=0;i<lslen;i++) { 68 char namelen = list[i]; 69 char *name = list + i + 1; 70 71 char nextlen = list[i + namelen + 1]; // save length of next name 72 list[i + namelen + 1] = '\0'; // terminate string temporary 73 74 // get xattr from src and add it to dst 75 printf("%s\n", name); 76 ssize_t len = extattr_get_fd(src, EXTATTR_NAMESPACE_USER, name, NULL, 0); 77 if(len > 0) { 78 char *value = malloc(len); 79 len = extattr_get_fd(src, EXTATTR_NAMESPACE_USER, name, value, len); 80 if(len > 0) { 81 if(extattr_set_fd(dst, EXTATTR_NAMESPACE_USER, name, value, len) == -1) { 82 perror("extattr_set_fd"); 83 } 84 } else { 85 perror("extattr_get_fd"); 86 } 87 free(value); 88 } else { 89 perror("extattr_get_fd"); 90 } 91 92 list[i + namelen + 1] = nextlen; // restore length 93 i += namelen; 94 } 95 96 return 0; 97 } 98