UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2019 Olaf Wintermann. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * small tool for accessing extended attributes 31 */ 32 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <errno.h> 37 38 #ifdef _WIN32 39 #include <Windows.h> 40 #endif 41 42 #include "libxattr.h" 43 44 int attrtool_list(int argc, char **argv, int values); 45 int attrtool_get(int argc, char **argv, int raw); 46 int attrtool_set(int argc, char **argv); 47 int attrtool_rm(int argc, char **argv); 48 49 void print_usage(char *cmd) { 50 fprintf(stderr, "usage %s:\n", cmd); 51 fprintf(stderr, " list <file>\n"); 52 fprintf(stderr, " listvalues <file>\n"); 53 fprintf(stderr, " get <file> <name>\n"); 54 fprintf(stderr, " set <file> <name> <value>\n"); 55 fprintf(stderr, " remove <file> <name>\n"); 56 } 57 58 int xattr_tool_main(int argc, char **argv); 59 60 #ifdef _WIN32 61 static char* wchar2utf8(const wchar_t *wstr, size_t wlen) { 62 size_t maxlen = wlen * 4; 63 char *ret = malloc(maxlen + 1); 64 int ret_len = WideCharToMultiByte( 65 CP_UTF8, 66 0, 67 wstr, 68 wlen, 69 ret, 70 maxlen, 71 NULL, 72 NULL); 73 ret[ret_len] = 0; 74 return ret; 75 } 76 77 int wmain(int argc, wchar_t **argv) { 78 char **argv_utf8 = calloc(argc, sizeof(char*)); 79 for(int i=0;i<argc;i++) { 80 argv_utf8[i] = wchar2utf8(argv[i], wcslen(argv[i])); 81 } 82 83 int ret = xattr_tool_main(argc, argv_utf8); 84 85 for(int i=0;i<argc;i++) { 86 free(argv_utf8[i]); 87 } 88 free(argv_utf8); 89 90 return ret; 91 } 92 #else 93 int main(int argc, char **argv) { 94 return xattr_tool_main(argc, argv); 95 } 96 #endif 97 98 int xattr_tool_main(int argc, char **argv) { 99 if(argc < 3) { 100 print_usage(argv[0]); 101 return 1; 102 } 103 104 if(!strcmp(argv[1], "list") || !strcmp(argv[1], "ls")) { 105 return attrtool_list(argc, argv, 0); 106 } else if(!strcmp(argv[1], "listvalues") || !strcmp(argv[1], "lsv")) { 107 return attrtool_list(argc, argv, 1); 108 } else if(!strcmp(argv[1], "get")) { 109 return attrtool_get(argc, argv, 0); 110 } else if(!strcmp(argv[1], "set")) { 111 return attrtool_set(argc, argv); 112 } else if(!strcmp(argv[1], "rm") || !strcmp(argv[1], "remove")) { 113 return attrtool_rm(argc, argv); 114 } else { 115 fprintf(stderr, "Unknown command\n"); 116 print_usage(argv[0]); 117 } 118 119 return 1; 120 } 121 122 int attrtool_list(int argc, char **argv, int values) { 123 ssize_t nelm = 0; 124 char **list = xattr_list(argv[2], &nelm); 125 if(nelm < 0) { 126 perror("xattr_list"); 127 return 3; 128 } 129 130 for(int i=0;i<nelm;i++) { 131 char *attr = list[i]; 132 if(values) { 133 ssize_t valuelen = 0; 134 char *value = xattr_get(argv[2], attr, &valuelen); 135 if(valuelen < 0) { 136 printf("%s: #ERROR: %s\n", attr, strerror(errno)); 137 } else { 138 printf("%s: %.*s\n", attr, (int)valuelen, value); 139 } 140 141 if(value) { 142 free(value); 143 } 144 } else { 145 printf("%s\n", attr); 146 } 147 148 free(list[i]); 149 } 150 if(list) { 151 free(list); 152 } 153 154 return 0; 155 } 156 157 int attrtool_get(int argc, char **argv, int raw) { 158 if(argc < 4) { 159 fprintf(stderr, "Too few arguments\n"); 160 print_usage(argv[1]); 161 return 1; 162 } 163 164 char *file = argv[2]; 165 char *attr = argv[3]; 166 int ret = 0; 167 168 ssize_t valuelen = 0; 169 char *value = xattr_get(file, attr, &valuelen); 170 if(value) { 171 if(raw) { 172 fwrite(value, 1, valuelen, stdout); 173 } else { 174 printf("%.*s\n", (int)valuelen, value); 175 } 176 free(value); 177 } else { 178 perror("xattr_get"); 179 ret = 3; 180 } 181 182 return ret; 183 } 184 185 int attrtool_set(int argc, char **argv) { 186 if(argc < 4) { 187 fprintf(stderr, "Too few arguments\n"); 188 print_usage(argv[1]); 189 return 1; 190 } 191 192 size_t len = strlen(argv[4]); 193 char *file = argv[2]; 194 char *attr = argv[3]; 195 char *value = argv[4]; 196 int ret = 0; 197 198 if(xattr_set(file, attr, value, len)) { 199 perror("xattr_set"); 200 ret = 3; 201 } 202 203 return ret; 204 } 205 206 int attrtool_rm(int argc, char **argv) { 207 if(argc < 4) { 208 fprintf(stderr, "Too few arguments\n"); 209 print_usage(argv[1]); 210 return 1; 211 } 212 213 char *file = argv[2]; 214 char *attr = argv[3]; 215 int ret = 0; 216 217 if(xattr_remove(file, attr)) { 218 perror("xattr_remove"); 219 ret = 1; 220 } 221 222 return ret; 223 } 224