aboutsummaryrefslogtreecommitdiff
path: root/src/mime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mime.c')
-rw-r--r--src/mime.c97
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