Line data Source code
1 : // GIOGetMimeType: Copyright (C) 2012 Khaled Hosny
2 : // GIOguessMimeType: Copyright (C) 2014 Jose Da Silva
3 : //
4 : // This program is free software; you can redistribute it and/or modify
5 : // it under the terms of the GNU General Public License as published by
6 : // the Free Software Foundation; either version 3 of the License, or
7 : // (at your option) any later version.
8 : //
9 : // This program is distributed in the hope that it will be useful,
10 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : // GNU General Public License for more details.
13 : //
14 : // You should have received a copy of the GNU General Public License
15 : // along with this program; if not, see <http://www.gnu.org/licenses/>.
16 :
17 : #include "gio.h"
18 : #include "gfile.h"
19 : #include "ustring.h"
20 : #include <gio/gio.h>
21 : #include <glib.h>
22 :
23 : const char *MimeListFromExt[] = {
24 : /* This list is indexed from list ExtToMimeList */
25 : /* 0 .bmp */ "image/bmp",
26 : /* 1 .xbm */ "image/x-xbitmap",
27 : /* 2 .xpm */ "image/x-xpixmap",
28 : /* 3 .tif */ "image/tiff",
29 : /* 4 .jpg */ "image/jpeg",
30 : /* 5 .png */ "image/png",
31 : /* 6 .gif */ "image/gif",
32 : /* 7 .sun */ "image/x-sun-raster",
33 : /* 8 ,sgi */ "image/x-sgi",
34 : /* 9 .txt */ "text/plain",
35 : /*10 .htm */ "text/html",
36 : /*11 .xml */ "text/xml",
37 : /*12 .css */ "text/css",
38 : /*13 .c */ "text/c",
39 : /*14 .java */ "text/java",
40 : /*15 .ps */ "text/fontps",
41 : /*16 .pfa */ "text/ps",
42 : /*17 .obj */ "application/x-object",
43 : /*18 core */ "application/x-core",
44 : /*19 .tar */ "application/x-tar",
45 : /*20 .zip */ "application/x-compressed",
46 : /* vnd.font-fontforge-sfd Officially registered with IANA on 14 May 2008 */
47 : /*21 .sfd */ "application/vnd.font-fontforge-sfd",
48 : /*22 .pdf */ "application/pdf",
49 : /*23 .ttf */ "application/x-font-ttf",
50 : /*24 .otf */ "application/x-font-otf",
51 : /*25 ,cid */ "application/x-font-cid",
52 : /*26 .pcf */ "application/x-font-pcf",
53 : /*27 .snf */ "application/x-font-snf",
54 : /*28 .bdf */ "application/x-font-bdf",
55 : /*29 .woff */ "application/x-font-woff",
56 : /*30 .dfont */ "application/x-mac-dfont",
57 : /*31 .ffil */ "application/x-mac-suit"
58 : };
59 :
60 : typedef struct {
61 : char *ext3; /* filename dot ext3 */
62 : int mime; /* index to mime type */
63 : } ext3mime;
64 :
65 : const ext3mime ExtToMimeList[] = {
66 : {".bmp", 0},
67 : {".xbm", 1},
68 : {".xpm", 2},
69 : {".tiff", 3},{".tif", 3},
70 : {".jpeg", 4},{".jpg", 4},
71 : {".png", 5},
72 : {".gif", 6},
73 : {".ras", 7},{".im1", 7},{".im8", 7},{".im24", 7},
74 : {".im32", 7},{".rs", 7},{".sun", 7},
75 : {".rgb", 8},{".rgba", 8},{".sgi", 8},{".bw", 8},
76 : {".txt", 9},{".text", 9},{".sh", 9},{".bat", 9},
77 : {".html", 10},{".htm", 10},
78 : {".xml", 11},
79 : {".css", 12},
80 : {".c", 13},{".h", 13},
81 : {"java", 14},
82 : {".pfa", 15},{".pfb", 15},{".pt3", 15},{".cff", 15},
83 : {".ps", 16},{".eps", 16},
84 : {".o", 17},{".obj", 17},
85 : {".tar", 19},
86 : {".gz", 20},{".tgz", 20},{".z", 20},{".zip", 20},
87 : {".bz2", 20},{".tbz", 20},{".rpm", 20},
88 : {".sfd", 21},
89 : {".pdf", 22},
90 : {".ttf", 23},
91 : {".otf", 24},{".otb", 24},{".gai", 24},
92 : {".cid", 25},
93 : {".pcf", 26},
94 : {".snf", 27},
95 : {".bdf", 28},
96 : {".woff", 29},
97 : {".dfont", 30},
98 : {".ffil", 31},
99 : {0, 0}
100 : };
101 :
102 0 : char *GIOguessMimeType(const char *path) {
103 : /* Try guess mime type based on filename dot3 extension */
104 : /* This list is incomplete, but saves having to sniff a */
105 : /* file to figure-out the file-type (if dot3 extension) */
106 : /* plus, some operating systems have weak mime guessing */
107 : /* routines, but have strong dot3 extension usage. */
108 : int i;
109 : char *pt;
110 :
111 0 : if ( (pt=strrchr(path,'.'))!=NULL )
112 0 : for (i = 0; ExtToMimeList[i].ext3; i++)
113 0 : if ( strcasecmp(pt,ExtToMimeList[i].ext3)==0 )
114 0 : return( copy(MimeListFromExt[ExtToMimeList[i].mime]) );
115 0 : return( 0 );
116 : }
117 :
118 0 : char* GIOGetMimeType(const char *path) {
119 : /* Get file mime type by sniffing a portion of the file */
120 : /* If that does not work, then depend on guessing type. */
121 : #define sniff_length 4096
122 0 : char *content_type=NULL,*mime=0;
123 :
124 : /*
125 : Doing this on Windows is horrendously slow. glib on Windows also only uses
126 : the sniff buffer iff MIME detection via file extension fails, and even
127 : then, only for determining if it /looks like/ a text file.
128 : */
129 : #ifndef __MINGW32__
130 : FILE *fp;
131 :
132 0 : if ( (fp=fopen(path,"rb"))!=NULL ) {
133 : guchar sniff_buffer[sniff_length];
134 : gboolean uncertain;
135 0 : size_t res=fread(sniff_buffer,1,sniff_length,fp);
136 0 : int err=ferror(fp);
137 0 : fclose (fp);
138 0 : if ( !err ) {
139 : // first force guessing file type from the content only by passing
140 : // NULL for file name, if the result is not certain try again with
141 : // file name
142 0 : content_type=g_content_type_guess(NULL,sniff_buffer,res,&uncertain);
143 0 : if (uncertain) {
144 0 : if (content_type!=NULL)
145 0 : g_free(content_type);
146 0 : content_type=g_content_type_guess(path,sniff_buffer,res,NULL);
147 : }
148 : }
149 : }
150 : #endif
151 :
152 0 : if ( content_type==NULL )
153 : /* if sniffing failed - then try and guess the file type */
154 0 : content_type=g_content_type_guess(path,NULL,0,NULL);
155 :
156 0 : if ( content_type!=NULL ) {
157 0 : char *temp=g_content_type_get_mime_type(content_type);
158 0 : g_free(content_type);
159 :
160 0 : if ( temp!=NULL ) {
161 0 : mime=copy(temp); /* ...convert to generic malloc/free */
162 0 : g_free(temp);
163 : }
164 : }
165 :
166 0 : return( mime );
167 : }
168 :
169 :
|