file.c (2683B)
1 #include "file.h" 2 3 #include <stdio.h> 4 #include <stdlib.h> 5 #include <string.h> 6 #include <sys/stat.h> 7 #include <unistd.h> 8 9 char * 10 get_mime_type_from_extension(char *extension) { 11 char *default_type = "application/octet-stream"; 12 size_t i, 13 number_of_types = sizeof(mime_types) 14 / sizeof(mime_types[0]); 15 16 for (i = 0; i < number_of_types; i++) { 17 if (strcmp(mime_types[i].extension, extension) == 0) { 18 return mime_types[i].type; 19 } 20 } 21 22 return default_type; 23 } 24 25 int 26 is_file_readable(char *path) { 27 struct stat file_stat; 28 29 if (stat(path, &file_stat) != 0) { 30 return 0; 31 } 32 33 if (!S_ISREG(file_stat.st_mode)) { 34 return 0; 35 } 36 37 if (access(path, R_OK) != 0) { 38 return 0; 39 }; 40 41 return 1; 42 } 43 44 char * 45 get_normalised_path(char *path) { 46 char *normalised; 47 int i, 48 j; 49 50 if (path == NULL) { 51 return path; 52 } 53 54 normalised = malloc(strlen(path) + 1); 55 56 if (normalised == NULL) { 57 return normalised; 58 } 59 60 j = 0; 61 for (i = 0; path[i] != '\0'; i++) { 62 if (path[i] != '/' || 63 /* In the following conditions, we have path[i] == '/'. */ 64 i == 0 || /* Keep leading slash */ 65 path[i - 1] != '/' || /* No continous slashes */ 66 path[i + 1] != '\0') { /* No trailing slash */ 67 normalised[j] = path[i]; 68 j++; 69 } 70 } 71 72 normalised[j] = '\0'; 73 74 return normalised; 75 } 76 77 char * 78 get_file_name(char *path) { 79 char *last_slash = strrchr(path, '/'), 80 *character_after_last_slash = last_slash + sizeof(char); 81 82 if (last_slash == NULL) { 83 /* If no slash occurs, the file name is the actual path */ 84 return path; 85 } 86 87 if (*character_after_last_slash == '\0') { 88 /* If path ends in '/', the file name will be considered 89 empty */ 90 return ""; 91 } 92 93 return character_after_last_slash; 94 } 95 96 char * 97 get_file_extension(char *path) { 98 char *file_name = get_file_name(path), 99 *last_dot = strrchr(file_name, '.'); 100 101 if (last_dot == NULL) { 102 return ""; 103 } 104 105 return last_dot + sizeof(char); 106 } 107 108 struct file_content 109 get_file_content(char *path) { 110 struct file_content result = { NULL, 0 }; 111 FILE *file = fopen(path, "rb"); 112 long file_size; 113 size_t bytes_read; 114 115 if (file == NULL) { 116 return result; 117 } 118 119 /* Move the file pointer to the end of the file */ 120 fseek(file, 0, SEEK_END); 121 /* Get the size */ 122 file_size = ftell(file); 123 /* Come back at the start of the file */ 124 fseek(file, 0, SEEK_SET); 125 126 result.content = malloc(file_size + 1); 127 128 if (!result.content) { 129 fclose(file); 130 return result; 131 } 132 133 bytes_read = fread(result.content, 1, file_size, file); 134 135 /* 'result' gets written here. Before this, it remained { NULL, 0 }. */ 136 result.content[bytes_read] = '\0'; 137 result.length = bytes_read; 138 139 fclose(file); 140 141 return result; 142 }