diff options
Diffstat (limited to 'src/mime.c')
-rw-r--r-- | src/mime.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/src/mime.c b/src/mime.c new file mode 100644 index 0000000..d90cc3f --- /dev/null +++ b/src/mime.c @@ -0,0 +1,97 @@ +#include "spm.h" + +Process *file_command(const char *_filename) { + char *filename = strdup(_filename); + Process *proc_info = NULL; + char sh_cmd[PATH_MAX]; + sh_cmd[0] = '\0'; +#ifdef __APPLE__ + const char *fmt_cmd = "file -I \"%s\""; +#else // GNU + const char *fmt_cmd = "file -E -i \"%s\""; +#endif + + strchrdel(filename, "&;|"); + sprintf(sh_cmd, fmt_cmd, filename); + shell(&proc_info, SHELL_OUTPUT, sh_cmd); + +#ifdef __APPLE__ + // Force BSD command to return non-zero when a file can't be found + const char *failmsg = ": cannot open"; + if (strstr(proc_info->output, failmsg) != NULL) { + proc_info->returncode = 1; + } +#endif + free(filename); + return proc_info; +} + +Mime *file_mimetype(const char *filename) { + char **output = NULL; + char **parts = NULL; + Mime *type = NULL; + Process *proc = file_command(filename); + + if (proc->returncode != 0) { + return NULL; + } + output = split(proc->output, ":"); + if (!output || output[1] == NULL) { + return NULL; + } + parts = split(output[1], ";"); + if (!parts || !parts[0] || !parts[1]) { + return NULL; + } + + char *what = strdup(parts[0]); + what = lstrip(what); + + char *charset = strdup(strchr(parts[1], '=') + 1); + charset = lstrip(charset); + charset[strlen(charset) - 1] = '\0'; + + char *origin = strdup(realpath(filename, NULL)); + + type = (Mime *)calloc(1, sizeof(Mime)); + type->origin = origin; + type->type = strdup(what); + type->charset = strdup(charset); + + split_free(output); + split_free(parts); + return type; +} + +void mime_free(Mime *m) { + if (m != NULL) { + free(m->origin); + free(m->type); + free(m->charset); + free(m); + } +} + +int file_is_text(const char *filename) { + int result = 0; + char *path = normpath(filename); + Mime *type = file_mimetype(path); + if (startswith(type->type, "text/") == 0) { + result = 1; + } + free(path); + mime_free(type); + return result; +} + +int file_is_binary(const char *filename) { + int result = 0; + char *path = normpath(filename); + Mime *type = file_mimetype(path); + if (startswith(type->type, "application/") == 0 && strcmp(type->charset, "binary") == 0) { + result = 1; + } + free(path); + mime_free(type); + return result; +}
\ No newline at end of file |