1/*
2	Copyright 1999-2001, Be Incorporated.   All Rights Reserved.
3	This file may be used under the terms of the Be Sample Code License.
4*/
5
6/*
7 * handles mime type information for dosfs
8 * gets/sets mime information in vnode
9 */
10
11
12#define MIME_STRING_TYPE 'MIMS'
13
14#include "system_dependencies.h"
15
16#ifndef FS_SHELL
17#include <file_systems/mime_ext_table.h>
18#endif
19
20#include "dosfs.h"
21#include "attr.h"
22
23
24int32 kBeOSTypeCookie = 0x1234;
25
26#define DPRINTF(a,b) if (debug_attr > (a)) dprintf b
27
28status_t set_mime_type(vnode *node, const char *filename)
29{
30#ifdef FS_SHELL
31	return B_ERROR;
32#else
33	return set_mime(&node->mime, filename);
34#endif
35}
36
37
38status_t
39dosfs_open_attrdir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
40{
41	DPRINTF(0, ("dosfs_open_attrdir called\n"));
42
43	if ((*_cookie = malloc(sizeof(uint32))) == NULL) {
44		return ENOMEM;
45	}
46	*(int32 *)(*_cookie) = 0;
47
48	return 0;
49}
50
51
52status_t
53dosfs_close_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
54{
55	DPRINTF(0, ("dosfs_close_attrdir called\n"));
56
57	*(int32 *)_cookie = 1;
58
59	return 0;
60}
61
62
63status_t
64dosfs_free_attrdir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
65{
66	DPRINTF(0, ("dosfs_free_attrcookie called\n"));
67
68	if (_cookie == NULL) {
69		dprintf("error: dosfs_free_attrcookie called with null cookie\n");
70		return EINVAL;
71	}
72
73	*(int32 *)_cookie = 0x87654321;
74	free(_cookie);
75
76	return 0;
77}
78
79
80status_t
81dosfs_rewind_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
82{
83	DPRINTF(0, ("dosfs_rewind_attrdir called\n"));
84
85	if (_cookie == NULL) {
86		dprintf("error: dosfs_rewind_attrcookie called with null cookie\n");
87		return EINVAL;
88	}
89
90	*(uint32 *)_cookie = 0;
91	return 0;
92}
93
94
95status_t
96dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
97	struct dirent *entry, size_t bufsize, uint32 *num)
98{
99	nspace *vol = (nspace *)_vol->private_volume;
100	vnode *node = (vnode *)_node->private_node;
101	int32 *cookie = (int32 *)_cookie;
102
103	DPRINTF(0, ("dosfs_read_attrdir called\n"));
104
105	*num = 0;
106
107	RecursiveLocker lock(vol->vlock);
108
109	if ((*cookie == 0) && (node->mime)) {
110		*num = 1;
111
112		entry->d_ino = node->vnid;
113		entry->d_dev = vol->id;
114		strcpy(entry->d_name, "BEOS:TYPE");
115		entry->d_reclen = offsetof(struct dirent, d_name) + strlen(entry->d_name) + 1;
116	}
117
118	*cookie = 1;
119
120	return 0;
121}
122
123
124status_t
125dosfs_open_attr(fs_volume *_vol, fs_vnode *_node, const char *name,
126	int openMode, void **_cookie)
127{
128	nspace *vol = (nspace *)_vol->private_volume;
129	vnode *node = (vnode *)_node->private_node;
130
131	if (strcmp(name, "BEOS:TYPE"))
132		return ENOENT;
133
134	RecursiveLocker lock(vol->vlock);
135
136	if (node->mime == NULL) {
137		return ENOENT;
138	}
139
140	*_cookie = &kBeOSTypeCookie;
141	return B_OK;
142}
143
144
145status_t
146dosfs_close_attr(fs_volume *_vol, fs_vnode *_node, void *cookie)
147{
148	return B_OK;
149}
150
151
152status_t
153dosfs_free_attr_cookie(fs_volume *_vol, fs_vnode *_node, void *cookie)
154{
155	return B_OK;
156}
157
158
159status_t
160dosfs_read_attr_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,
161	struct stat *stat)
162{
163	nspace *vol = (nspace *)_vol->private_volume;
164	vnode *node = (vnode *)_node->private_node;
165
166	DPRINTF(0, ("dosfs_read_attr_stat\n"));
167
168	if (_cookie != &kBeOSTypeCookie)
169		return ENOENT;
170
171	RecursiveLocker lock(vol->vlock);
172
173	if (node->mime == NULL) {
174		return ENOENT;
175	}
176
177	stat->st_type = MIME_STRING_TYPE;
178	stat->st_size = strlen(node->mime) + 1;
179
180	return 0;
181}
182
183
184status_t
185dosfs_read_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
186	void *buffer, size_t *_length)
187{
188	nspace *vol = (nspace *)_vol->private_volume;
189	vnode *node = (vnode *)_node->private_node;
190	ssize_t length;
191
192	DPRINTF(0, ("dosfs_read_attr\n"));
193
194	if (_cookie != &kBeOSTypeCookie)
195		return ENOENT;
196
197	RecursiveLocker lock(vol->vlock);
198
199	if (node->mime == NULL)
200		return ENOENT;
201
202	if ((pos < 0) || (pos > (off_t)strlen(node->mime)))
203		return EINVAL;
204
205	length = user_strlcpy((char*)buffer, node->mime + pos, *_length);
206	if (length < B_OK)
207		return B_BAD_ADDRESS;
208
209	if ((size_t)length < *_length)
210		*_length = length + 1;
211
212	return 0;
213}
214
215
216// suck up application attempts to set mime types; this hides an unsightly
217// error message printed out by zip
218status_t
219dosfs_write_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie,
220	off_t pos, const void *buffer, size_t *_length)
221{
222	DPRINTF(0, ("dosfs_write_attr\n"));
223
224	*_length = 0;
225
226	if (_cookie != &kBeOSTypeCookie)
227		return ENOSYS;
228
229	return B_OK;
230}
231