utils.c (6111B)
1 #include <dirent.h> 2 #include <fcntl.h> 3 #include <stdint.h> 4 #include <stdio.h> 5 #include <stdlib.h> 6 #include <string.h> 7 #include <sys/stat.h> 8 #if defined(_MSC_VER) || defined(__MINGW32__) 9 #include <io.h> 10 #include <sys/utime.h> 11 #else 12 #include <unistd.h> 13 #include <utime.h> 14 #endif 15 16 #include "utils.h" 17 18 // global verbosity setting 19 int g_verbosity = 0; 20 21 int read_s16_be(unsigned char *buf) 22 { 23 unsigned tmp = read_u16_be(buf); 24 int ret; 25 if (tmp > 0x7FFF) { 26 ret = -((int)0x10000 - (int)tmp); 27 } else { 28 ret = (int)tmp; 29 } 30 return ret; 31 } 32 33 float read_f32_be(unsigned char *buf) 34 { 35 union {uint32_t i; float f;} ret; 36 ret.i = read_u32_be(buf); 37 return ret.f; 38 } 39 40 int is_power2(unsigned int val) 41 { 42 while (((val & 1) == 0) && (val > 1)) { 43 val >>= 1; 44 } 45 return (val == 1); 46 } 47 48 int fprint_write_output(FILE *fp, write_encoding encoding, const uint8_t *raw, int length) 49 { 50 typedef struct { 51 int bytes_per_val; 52 const char *suffix; 53 } encoding_format; 54 const encoding_format enc_fmt[] = { 55 [ENCODING_RAW] = {0, ""}, 56 [ENCODING_U8] = {sizeof(uint8_t), ""}, 57 [ENCODING_U16] = {sizeof(uint16_t), ""}, 58 [ENCODING_U32] = {sizeof(uint32_t), ""}, 59 [ENCODING_U64] = {sizeof(uint64_t), "ULL"}, 60 }; 61 int flength = 0; 62 const encoding_format *fmt = &enc_fmt[encoding]; 63 switch (encoding) { 64 case ENCODING_RAW: 65 flength = fwrite(raw, 1, length, fp); 66 break; 67 case ENCODING_U8: 68 case ENCODING_U16: 69 case ENCODING_U32: 70 case ENCODING_U64: 71 for (int w = 0; w < length; w += fmt->bytes_per_val) { 72 flength += fprintf(fp, "0x"); 73 for (int b = 0; b < fmt->bytes_per_val; b++) { 74 int off = w + b; 75 flength += fprintf(fp, "%02x", off < length ? raw[off] : 0x00); 76 } 77 flength += fprintf(fp, "%s%c", fmt->suffix, (w < length - fmt->bytes_per_val) ? ',' : '\n'); 78 } 79 break; 80 } 81 return flength; 82 } 83 84 void swap_bytes(unsigned char *data, long length) 85 { 86 long i; 87 unsigned char tmp; 88 for (i = 0; i < length; i += 2) { 89 tmp = data[i]; 90 data[i] = data[i+1]; 91 data[i+1] = tmp; 92 } 93 } 94 95 void reverse_endian(unsigned char *data, long length) 96 { 97 long i; 98 unsigned char tmp; 99 for (i = 0; i < length; i += 4) { 100 tmp = data[i]; 101 data[i] = data[i+3]; 102 data[i+3] = tmp; 103 tmp = data[i+1]; 104 data[i+1] = data[i+2]; 105 data[i+2] = tmp; 106 } 107 } 108 109 long filesize(const char *filename) 110 { 111 struct stat st; 112 113 if (stat(filename, &st) == 0) { 114 return st.st_size; 115 } 116 117 return -1; 118 } 119 120 void touch_file(const char *filename) 121 { 122 int fd; 123 //fd = open(filename, O_WRONLY|O_CREAT|O_NOCTTY|O_NONBLOCK, 0666); 124 fd = open(filename, O_WRONLY|O_CREAT, 0666); 125 if (fd >= 0) { 126 utime(filename, NULL); 127 close(fd); 128 } 129 } 130 131 long read_file(const char *file_name, unsigned char **data) 132 { 133 FILE *in; 134 unsigned char *in_buf = NULL; 135 long file_size; 136 long bytes_read; 137 in = fopen(file_name, "rb"); 138 if (in == NULL) { 139 return -1; 140 } 141 142 // allocate buffer to read from offset to end of file 143 fseek(in, 0, SEEK_END); 144 file_size = ftell(in); 145 146 // sanity check 147 if (file_size > 256*MB) { 148 return -2; 149 } 150 151 in_buf = malloc(file_size); 152 fseek(in, 0, SEEK_SET); 153 154 // read bytes 155 bytes_read = fread(in_buf, 1, file_size, in); 156 if (bytes_read != file_size) { 157 return -3; 158 } 159 160 fclose(in); 161 *data = in_buf; 162 return bytes_read; 163 } 164 165 long write_file(const char *file_name, unsigned char *data, long length) 166 { 167 FILE *out; 168 long bytes_written; 169 // open output file 170 out = fopen(file_name, "wb"); 171 if (out == NULL) { 172 perror(file_name); 173 return -1; 174 } 175 bytes_written = fwrite(data, 1, length, out); 176 fclose(out); 177 return bytes_written; 178 } 179 180 void generate_filename(const char *in_name, char *out_name, char *extension) 181 { 182 char tmp_name[FILENAME_MAX]; 183 int len; 184 int i; 185 strcpy(tmp_name, in_name); 186 len = strlen(tmp_name); 187 for (i = len - 1; i > 0; i--) { 188 if (tmp_name[i] == '.') { 189 break; 190 } 191 } 192 if (i <= 0) { 193 i = len; 194 } 195 tmp_name[i] = '\0'; 196 sprintf(out_name, "%s.%s", tmp_name, extension); 197 } 198 199 char *basename(const char *name) 200 { 201 const char *base = name; 202 while (*name) { 203 if (*name++ == '/') { 204 base = name; 205 } 206 } 207 return (char *)base; 208 } 209 210 void make_dir(const char *dir_name) 211 { 212 struct stat st = {0}; 213 if (stat(dir_name, &st) == -1) { 214 mkdir(dir_name, 0755); 215 } 216 } 217 218 long copy_file(const char *src_name, const char *dst_name) 219 { 220 unsigned char *buf; 221 long bytes_written; 222 long bytes_read; 223 224 bytes_read = read_file(src_name, &buf); 225 226 if (bytes_read > 0) { 227 bytes_written = write_file(dst_name, buf, bytes_read); 228 if (bytes_written != bytes_read) { 229 bytes_read = -1; 230 } 231 free(buf); 232 } 233 234 return bytes_read; 235 } 236 237 void dir_list_ext(const char *dir, const char *extension, dir_list *list) 238 { 239 char *pool; 240 char *pool_ptr; 241 struct dirent *entry; 242 DIR *dfd; 243 int idx; 244 245 dfd = opendir(dir); 246 if (dfd == NULL) { 247 ERROR("Can't open '%s'\n", dir); 248 exit(1); 249 } 250 251 pool = malloc(FILENAME_MAX * MAX_DIR_FILES); 252 pool_ptr = pool; 253 254 idx = 0; 255 while ((entry = readdir(dfd)) != NULL && idx < MAX_DIR_FILES) { 256 if (!extension || str_ends_with(entry->d_name, extension)) { 257 sprintf(pool_ptr, "%s/%s", dir, entry->d_name); 258 list->files[idx] = pool_ptr; 259 pool_ptr += strlen(pool_ptr) + 1; 260 idx++; 261 } 262 } 263 list->count = idx; 264 265 closedir(dfd); 266 } 267 268 void dir_list_free(dir_list *list) 269 { 270 // assume first entry in array is allocated 271 if (list->files[0]) { 272 free(list->files[0]); 273 list->files[0] = NULL; 274 } 275 } 276 277 int str_ends_with(const char *str, const char *suffix) 278 { 279 if (!str || !suffix) { 280 return 0; 281 } 282 size_t len_str = strlen(str); 283 size_t len_suffix = strlen(suffix); 284 if (len_suffix > len_str) { 285 return 0; 286 } 287 return (0 == strncmp(str + len_str - len_suffix, suffix, len_suffix)); 288 }