4 * Implement a fixed mapping of forbidden NT characters in filenames that are
5 * used a lot by the CAD package Catia.
7 * Yes, this a BAD BAD UGLY INCOMPLETE hack, but it helps quite some people
8 * out there. Catia V4 on AIX uses characters like "<*$ a *lot*, all forbidden
11 * Copyright (C) Volker Lendecke, 2005
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31 static void catia_string_replace(char *s
, unsigned char oldc
, unsigned
34 static smb_ucs2_t tmpbuf
[sizeof(pstring
)];
35 smb_ucs2_t
*ptr
= tmpbuf
;
36 smb_ucs2_t old
= oldc
;
38 push_ucs2(NULL
, tmpbuf
, s
, sizeof(tmpbuf
), STR_TERMINATE
);
41 if (*ptr
==old
) *ptr
=newc
;
43 pull_ucs2(NULL
, s
, tmpbuf
, -1, sizeof(tmpbuf
), STR_TERMINATE
);
46 static void from_unix(char *s
)
48 catia_string_replace(s
, '\x22', '\xa8');
49 catia_string_replace(s
, '\x2a', '\xa4');
50 catia_string_replace(s
, '\x2f', '\xf8');
51 catia_string_replace(s
, '\x3a', '\xf7');
52 catia_string_replace(s
, '\x3c', '\xab');
53 catia_string_replace(s
, '\x3e', '\xbb');
54 catia_string_replace(s
, '\x3f', '\xbf');
55 catia_string_replace(s
, '\x5c', '\xff');
56 catia_string_replace(s
, '\x7c', '\xa6');
57 catia_string_replace(s
, ' ', '\xb1');
60 static void to_unix(char *s
)
62 catia_string_replace(s
, '\xa8', '\x22');
63 catia_string_replace(s
, '\xa4', '\x2a');
64 catia_string_replace(s
, '\xf8', '\x2f');
65 catia_string_replace(s
, '\xf7', '\x3a');
66 catia_string_replace(s
, '\xab', '\x3c');
67 catia_string_replace(s
, '\xbb', '\x3e');
68 catia_string_replace(s
, '\xbf', '\x3f');
69 catia_string_replace(s
, '\xff', '\x5c');
70 catia_string_replace(s
, '\xa6', '\x7c');
71 catia_string_replace(s
, '\xb1', ' ');
74 static SMB_STRUCT_DIR
*catia_opendir(vfs_handle_struct
*handle
,
75 const char *fname
, const char *mask
, uint32 attr
)
81 return SMB_VFS_NEXT_OPENDIR(handle
, name
, mask
, attr
);
84 static SMB_STRUCT_DIRENT
*catia_readdir(vfs_handle_struct
*handle
,
87 SMB_STRUCT_DIRENT
*result
= SMB_VFS_NEXT_READDIR(handle
, dirp
);
92 from_unix(result
->d_name
);
96 static int catia_open(vfs_handle_struct
*handle
,
97 const char *fname
, files_struct
*fsp
, int flags
, mode_t mode
)
101 pstrcpy(name
, fname
);
104 return SMB_VFS_NEXT_OPEN(handle
, name
, fsp
, flags
, mode
);
107 static int catia_rename(vfs_handle_struct
*handle
,
108 const char *oldname
, const char *newname
)
110 pstring oname
, nname
;
112 pstrcpy(oname
, oldname
);
114 pstrcpy(nname
, newname
);
117 DEBUG(10, ("converted old name: %s\n", oname
));
118 DEBUG(10, ("converted new name: %s\n", nname
));
120 return SMB_VFS_NEXT_RENAME(handle
, oname
, nname
);
123 static int catia_stat(vfs_handle_struct
*handle
,
124 const char *fname
, SMB_STRUCT_STAT
*sbuf
)
127 pstrcpy(name
, fname
);
130 return SMB_VFS_NEXT_STAT(handle
, name
, sbuf
);
133 static int catia_lstat(vfs_handle_struct
*handle
,
134 const char *path
, SMB_STRUCT_STAT
*sbuf
)
140 return SMB_VFS_NEXT_LSTAT(handle
, name
, sbuf
);
143 static int catia_unlink(vfs_handle_struct
*handle
, const char *path
)
149 return SMB_VFS_NEXT_UNLINK(handle
, name
);
152 static int catia_chmod(vfs_handle_struct
*handle
,
153 const char *path
, mode_t mode
)
159 return SMB_VFS_NEXT_CHMOD(handle
, name
, mode
);
162 static int catia_chown(vfs_handle_struct
*handle
,
163 const char *path
, uid_t uid
, gid_t gid
)
169 return SMB_VFS_NEXT_CHOWN(handle
, name
, uid
, gid
);
172 static int catia_chdir(vfs_handle_struct
*handle
,
179 return SMB_VFS_NEXT_CHDIR(handle
, name
);
182 static char *catia_getwd(vfs_handle_struct
*handle
, char *buf
)
184 return SMB_VFS_NEXT_GETWD(handle
, buf
);
187 static int catia_ntimes(vfs_handle_struct
*handle
,
188 const char *path
, const struct timespec ts
[2])
190 return SMB_VFS_NEXT_NTIMES(handle
, path
, ts
);
193 static BOOL
catia_symlink(vfs_handle_struct
*handle
,
194 const char *oldpath
, const char *newpath
)
196 return SMB_VFS_NEXT_SYMLINK(handle
, oldpath
, newpath
);
199 static BOOL
catia_readlink(vfs_handle_struct
*handle
,
200 const char *path
, char *buf
, size_t bufsiz
)
202 return SMB_VFS_NEXT_READLINK(handle
, path
, buf
, bufsiz
);
205 static int catia_link(vfs_handle_struct
*handle
,
206 const char *oldpath
, const char *newpath
)
208 return SMB_VFS_NEXT_LINK(handle
, oldpath
, newpath
);
211 static int catia_mknod(vfs_handle_struct
*handle
,
212 const char *path
, mode_t mode
, SMB_DEV_T dev
)
214 return SMB_VFS_NEXT_MKNOD(handle
, path
, mode
, dev
);
217 static char *catia_realpath(vfs_handle_struct
*handle
,
218 const char *path
, char *resolved_path
)
220 return SMB_VFS_NEXT_REALPATH(handle
, path
, resolved_path
);
223 static size_t catia_get_nt_acl(vfs_handle_struct
*handle
, files_struct
*fsp
,
224 const char *name
, uint32 security_info
,
225 struct security_descriptor_info
**ppdesc
)
227 return SMB_VFS_NEXT_GET_NT_ACL(handle
, fsp
, name
, security_info
,
231 static BOOL
catia_set_nt_acl(vfs_handle_struct
*handle
, files_struct
*fsp
,
232 const char *name
, uint32 security_info_sent
,
233 struct security_descriptor_info
*psd
)
235 return SMB_VFS_NEXT_SET_NT_ACL(handle
, fsp
, name
, security_info_sent
,
239 static int catia_chmod_acl(vfs_handle_struct
*handle
,
240 const char *name
, mode_t mode
)
242 /* If the underlying VFS doesn't have ACL support... */
243 if (!handle
->vfs_next
.ops
.chmod_acl
) {
247 return SMB_VFS_NEXT_CHMOD_ACL(handle
, name
, mode
);
250 /* VFS operations structure */
252 static vfs_op_tuple catia_op_tuples
[] = {
254 /* Directory operations */
256 {SMB_VFS_OP(catia_opendir
), SMB_VFS_OP_OPENDIR
,
257 SMB_VFS_LAYER_TRANSPARENT
},
258 {SMB_VFS_OP(catia_readdir
), SMB_VFS_OP_READDIR
,
259 SMB_VFS_LAYER_TRANSPARENT
},
261 /* File operations */
263 {SMB_VFS_OP(catia_open
), SMB_VFS_OP_OPEN
,
264 SMB_VFS_LAYER_TRANSPARENT
},
265 {SMB_VFS_OP(catia_rename
), SMB_VFS_OP_RENAME
,
266 SMB_VFS_LAYER_TRANSPARENT
},
267 {SMB_VFS_OP(catia_stat
), SMB_VFS_OP_STAT
,
268 SMB_VFS_LAYER_TRANSPARENT
},
269 {SMB_VFS_OP(catia_lstat
), SMB_VFS_OP_LSTAT
,
270 SMB_VFS_LAYER_TRANSPARENT
},
271 {SMB_VFS_OP(catia_unlink
), SMB_VFS_OP_UNLINK
,
272 SMB_VFS_LAYER_TRANSPARENT
},
273 {SMB_VFS_OP(catia_chmod
), SMB_VFS_OP_CHMOD
,
274 SMB_VFS_LAYER_TRANSPARENT
},
275 {SMB_VFS_OP(catia_chown
), SMB_VFS_OP_CHOWN
,
276 SMB_VFS_LAYER_TRANSPARENT
},
277 {SMB_VFS_OP(catia_chdir
), SMB_VFS_OP_CHDIR
,
278 SMB_VFS_LAYER_TRANSPARENT
},
279 {SMB_VFS_OP(catia_getwd
), SMB_VFS_OP_GETWD
,
280 SMB_VFS_LAYER_TRANSPARENT
},
281 {SMB_VFS_OP(catia_ntimes
), SMB_VFS_OP_NTIMES
,
282 SMB_VFS_LAYER_TRANSPARENT
},
283 {SMB_VFS_OP(catia_symlink
), SMB_VFS_OP_SYMLINK
,
284 SMB_VFS_LAYER_TRANSPARENT
},
285 {SMB_VFS_OP(catia_readlink
), SMB_VFS_OP_READLINK
,
286 SMB_VFS_LAYER_TRANSPARENT
},
287 {SMB_VFS_OP(catia_link
), SMB_VFS_OP_LINK
,
288 SMB_VFS_LAYER_TRANSPARENT
},
289 {SMB_VFS_OP(catia_mknod
), SMB_VFS_OP_MKNOD
,
290 SMB_VFS_LAYER_TRANSPARENT
},
291 {SMB_VFS_OP(catia_realpath
), SMB_VFS_OP_REALPATH
,
292 SMB_VFS_LAYER_TRANSPARENT
},
294 /* NT File ACL operations */
296 {SMB_VFS_OP(catia_get_nt_acl
), SMB_VFS_OP_GET_NT_ACL
,
297 SMB_VFS_LAYER_TRANSPARENT
},
298 {SMB_VFS_OP(catia_set_nt_acl
), SMB_VFS_OP_SET_NT_ACL
,
299 SMB_VFS_LAYER_TRANSPARENT
},
301 /* POSIX ACL operations */
303 {SMB_VFS_OP(catia_chmod_acl
), SMB_VFS_OP_CHMOD_ACL
,
304 SMB_VFS_LAYER_TRANSPARENT
},
307 {NULL
, SMB_VFS_OP_NOOP
,
311 NTSTATUS
vfs_catia_init(void);
312 NTSTATUS
vfs_catia_init(void)
314 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION
, "catia",