4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2005, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
24 * xtypes.c - Extended filesystem attribute support for MIME types
33 #include <sys/types.h>
44 static Option o_xattr_ignore
;
46 #define XTYPE_ATTR "user.mime_type"
48 #define RETURN_IF_IGNORED(val) if(o_xattr_ignore.int_value) return (val)
50 #if defined(HAVE_GETXATTR)
51 /* Linux implementation */
55 static int (*dyn_setxattr
)(const char *path
, const char *name
,
56 const void *value
, size_t size
, int flags
) = NULL
;
57 static ssize_t (*dyn_getxattr
)(const char *path
, const char *name
,
58 void *value
, size_t size
) = NULL
;
59 static ssize_t (*dyn_listxattr
)(const char *path
, char *list
,
66 libc
= dlopen("libc.so.6", RTLD_LAZY
| RTLD_NOLOAD
);
68 return; /* Give up on xattr support */
70 dyn_setxattr
= (void *) dlsym(libc
, "setxattr");
71 dyn_getxattr
= (void *) dlsym(libc
, "getxattr");
72 dyn_listxattr
= (void *) dlsym(libc
, "listxattr");
74 option_add_int(&o_xattr_ignore
, "xattr_ignore", FALSE
);
77 int xtype_supported(const char *path
)
82 RETURN_IF_IGNORED(FALSE
);
89 nent
=dyn_getxattr(path
, XTYPE_ATTR
, buf
, sizeof(buf
));
91 if(nent
<0 && errno
==ENOTSUP
)
98 int xtype_have_attr(const char *path
)
103 RETURN_IF_IGNORED(FALSE
);
109 nent
=dyn_listxattr(path
, buf
, sizeof(buf
));
111 if(nent
<0 && errno
==ERANGE
)
117 MIME_type
*xtype_get(const char *path
)
121 MIME_type
*type
= NULL
;
123 RETURN_IF_IGNORED(type_from_path(path
));
126 return type_from_path(path
); /* Old libc */
128 size
= dyn_getxattr(path
, XTYPE_ATTR
, "", 0);
133 buf
= g_new(gchar
, size
+ 1);
134 new_size
= dyn_getxattr(path
, XTYPE_ATTR
, buf
, size
);
136 if (size
== new_size
)
139 type
= mime_type_lookup(buf
);
147 /* Fall back to non-extended */
148 return type_from_path(path
);
152 int xtype_set(const char *path
, const MIME_type
*type
)
157 if(o_xattr_ignore
.int_value
)
166 return 1; /* Set type failed */
169 ttext
= g_strdup_printf("%s/%s", type
->media_type
, type
->subtype
);
170 res
= dyn_setxattr(path
, XTYPE_ATTR
, ttext
, strlen(ttext
), 0);
176 #elif defined(HAVE_ATTROPEN)
178 /* Solaris 9 implementation */
180 void xtype_init(void)
182 option_add_int(&o_xattr_ignore
, "xattr_ignore", FALSE
);
185 int xtype_supported(const char *path
)
187 RETURN_IF_IGNORED(FALSE
);
188 #ifdef _PC_XATTR_ENABLED
192 return pathconf(path
, _PC_XATTR_ENABLED
);
198 int xtype_have_attr(const char *path
)
200 RETURN_IF_IGNORED(FALSE
);
201 #ifdef _PC_XATTR_EXISTS
202 return pathconf(path
, _PC_XATTR_EXISTS
)>0;
208 MIME_type
*xtype_get(const char *path
)
213 MIME_type
*type
=NULL
;
215 RETURN_IF_IGNORED(type_from_path(path
));
217 #ifdef _PC_XATTR_EXISTS
218 if(!pathconf(path
, _PC_XATTR_EXISTS
))
219 return type_from_path(path
);
222 fd
=attropen(path
, XTYPE_ATTR
, O_RDONLY
);
225 nb
=read(fd
, buf
, sizeof(buf
));
228 nl
=strchr(buf
, '\n');
231 type
=mime_type_lookup(buf
);
239 /* Fall back to non-extended */
240 return type_from_path(path
);
243 int xtype_set(const char *path
, const MIME_type
*type
)
249 if(o_xattr_ignore
.int_value
)
255 fd
=attropen(path
, XTYPE_ATTR
, O_WRONLY
|O_CREAT
, 0644);
257 ttext
=g_strdup_printf("%s/%s",
258 type
->media_type
, type
->subtype
);
259 nb
=write(fd
, ttext
, strlen(ttext
));
260 if(nb
==strlen(ttext
))
261 ftruncate(fd
, (off_t
) nb
);
270 return 1; /* Set type failed */
274 /* No extended attributes available */
276 void xtype_init(void)
280 int xtype_supported(const char *path
)
285 int xtype_have_attr(const char *path
)
290 MIME_type
*xtype_get(const char *path
)
292 /* Fall back to non-extended */
293 return type_from_path(path
);
296 int xtype_set(const char *path
, const MIME_type
*type
)
299 return 1; /* Set type failed */