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 <SupportDefs.h>
15#include <KernelExport.h>
16
17#include <dirent.h>
18#include <file_systems/mime_ext_table.h>
19#include <fs_attr.h>
20#include <string.h>
21#include <malloc.h>
22
23#include "dosfs.h"
24#include "attr.h"
25
26int32 kBeOSTypeCookie = 0x1234;
27
28#define DPRINTF(a,b) if (debug_attr > (a)) dprintf b
29
30status_t set_mime_type(vnode *node, const char *filename)
31{
32	return set_mime(&node->mime, filename);
33}
34
35
36status_t
37dosfs_open_attrdir(fs_volume *_vol, fs_vnode *_node, void **_cookie)
38{
39	nspace *vol = (nspace *)_vol->private_volume;
40
41	TOUCH(_node);
42
43	DPRINTF(0, ("dosfs_open_attrdir called\n"));
44
45	LOCK_VOL(vol);
46
47	if ((*_cookie = malloc(sizeof(uint32))) == NULL) {
48		UNLOCK_VOL(vol);
49		return ENOMEM;
50	}
51	*(int32 *)(*_cookie) = 0;
52
53	UNLOCK_VOL(vol);
54
55	return 0;
56}
57
58
59status_t
60dosfs_close_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
61{
62	nspace *vol = (nspace *)_vol->private_volume;
63
64	TOUCH(_node);
65
66	DPRINTF(0, ("dosfs_close_attrdir called\n"));
67
68	LOCK_VOL(vol);
69
70	*(int32 *)_cookie = 1;
71
72	UNLOCK_VOL(vol);
73
74	return 0;
75}
76
77
78status_t
79dosfs_free_attrdir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie)
80{
81	TOUCH(_vol); TOUCH(_node);
82
83	DPRINTF(0, ("dosfs_free_attrcookie called\n"));
84
85	if (_cookie == NULL) {
86		dprintf("error: dosfs_free_attrcookie called with null cookie\n");
87		return EINVAL;
88	}
89
90	*(int32 *)_cookie = 0x87654321;
91	free(_cookie);
92
93	return 0;
94}
95
96
97status_t
98dosfs_rewind_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie)
99{
100	TOUCH(_vol); TOUCH(_node);
101
102	DPRINTF(0, ("dosfs_rewind_attrdir called\n"));
103
104	if (_cookie == NULL) {
105		dprintf("error: dosfs_rewind_attrcookie called with null cookie\n");
106		return EINVAL;
107	}
108
109	*(uint32 *)_cookie = 0;
110	return 0;
111}
112
113
114status_t
115dosfs_read_attrdir(fs_volume *_vol, fs_vnode *_node, void *_cookie,
116	struct dirent *entry, size_t bufsize, uint32 *num)
117{
118	nspace *vol = (nspace *)_vol->private_volume;
119	vnode *node = (vnode *)_node->private_node;
120	int32 *cookie = (int32 *)_cookie;
121
122	TOUCH(bufsize);
123
124	DPRINTF(0, ("dosfs_read_attrdir called\n"));
125
126	*num = 0;
127
128	LOCK_VOL(vol);
129
130	if ((*cookie == 0) && (node->mime)) {
131		*num = 1;
132
133		entry->d_ino = node->vnid;
134		entry->d_dev = vol->id;
135		entry->d_reclen = 10;
136		strcpy(entry->d_name, "BEOS:TYPE");
137	}
138
139	*cookie = 1;
140
141	UNLOCK_VOL(vol);
142
143	return 0;
144}
145
146
147status_t
148dosfs_open_attr(fs_volume *_vol, fs_vnode *_node, const char *name,
149	int openMode, void **_cookie)
150{
151	nspace *vol = (nspace *)_vol->private_volume;
152	vnode *node = (vnode *)_node->private_node;
153
154	if (strcmp(name, "BEOS:TYPE"))
155		return ENOENT;
156
157	LOCK_VOL(vol);
158
159	if (node->mime == NULL) {
160		UNLOCK_VOL(vol);
161		return ENOENT;
162	}
163
164	UNLOCK_VOL(vol);
165
166	*_cookie = &kBeOSTypeCookie;
167	return B_OK;
168}
169
170
171status_t
172dosfs_close_attr(fs_volume *_vol, fs_vnode *_node, void *cookie)
173{
174	return B_OK;
175}
176
177
178status_t
179dosfs_free_attr_cookie(fs_volume *_vol, fs_vnode *_node, void *cookie)
180{
181	return B_OK;
182}
183
184
185status_t
186dosfs_read_attr_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie,
187	struct stat *stat)
188{
189	nspace *vol = (nspace *)_vol->private_volume;
190	vnode *node = (vnode *)_node->private_node;
191
192	DPRINTF(0, ("dosfs_read_attr_stat\n"));
193
194	if (_cookie != &kBeOSTypeCookie)
195		return ENOENT;
196
197	LOCK_VOL(vol);
198
199	if (node->mime == NULL) {
200		UNLOCK_VOL(vol);
201		return ENOENT;
202	}
203
204	stat->st_type = MIME_STRING_TYPE;
205	stat->st_size = strlen(node->mime) + 1;
206
207	UNLOCK_VOL(vol);
208	return 0;
209}
210
211
212status_t
213dosfs_read_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos,
214	void *buffer, size_t *_length)
215{
216	nspace *vol = (nspace *)_vol->private_volume;
217	vnode *node = (vnode *)_node->private_node;
218	ssize_t length;
219
220	DPRINTF(0, ("dosfs_read_attr\n"));
221
222	if (_cookie != &kBeOSTypeCookie)
223		return ENOENT;
224
225	LOCK_VOL(vol);
226
227	if (node->mime == NULL) {
228		UNLOCK_VOL(vol);
229		return ENOENT;
230	}
231
232	if ((pos < 0) || (pos > strlen(node->mime))) {
233		UNLOCK_VOL(vol);
234		return EINVAL;
235	}
236
237	length = user_strlcpy(buffer, node->mime + pos, *_length);
238	if (length < B_OK) {
239		UNLOCK_VOL(vol);
240		return B_BAD_ADDRESS;
241	}
242	if (length < *_length)
243		*_length = length + 1;
244
245	UNLOCK_VOL(vol);
246	return 0;
247}
248
249
250// suck up application attempts to set mime types; this hides an unsightly
251// error message printed out by zip
252status_t
253dosfs_write_attr(fs_volume *_vol, fs_vnode *_node, void *_cookie,
254	off_t pos, const void *buffer, size_t *_length)
255{
256	DPRINTF(0, ("dosfs_write_attr\n"));
257
258	*_length = 0;
259
260	if (_cookie != &kBeOSTypeCookie)
261		return ENOSYS;
262
263	return B_OK;
264}
265