2 * CAP VFS module for Samba 3.x Version 0.3
4 * Copyright (C) Tim Potter, 1999-2000
5 * Copyright (C) Alexander Bokovoy, 2002-2003
6 * Copyright (C) Stefan (metze) Metzmacher, 2003
7 * Copyright (C) TAKAHASHI Motonobu (monyo), 2003
8 * Copyright (C) Jeremy Allison, 2007
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 #include "smbd/smbd.h"
29 static char *capencode(TALLOC_CTX *ctx, const char *from);
30 static char *capdecode(TALLOC_CTX *ctx, const char *from);
32 static uint64_t cap_disk_free(vfs_handle_struct *handle,
33 const struct smb_filename *smb_fname,
38 char *capname = capencode(talloc_tos(), smb_fname->base_name);
39 struct smb_filename *cap_smb_fname = NULL;
45 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
50 if (cap_smb_fname == NULL) {
55 return SMB_VFS_NEXT_DISK_FREE(handle, cap_smb_fname,
59 static int cap_get_quota(vfs_handle_struct *handle,
60 const struct smb_filename *smb_fname,
61 enum SMB_QUOTA_TYPE qtype,
65 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
66 struct smb_filename *cap_smb_fname = NULL;
72 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
77 if (cap_smb_fname == NULL) {
82 return SMB_VFS_NEXT_GET_QUOTA(handle, cap_smb_fname, qtype, id, dq);
85 static DIR *cap_opendir(vfs_handle_struct *handle,
86 const struct smb_filename *smb_fname,
90 char *capname = capencode(talloc_tos(), smb_fname->base_name);
91 struct smb_filename *cap_smb_fname = NULL;
97 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
102 if (cap_smb_fname == NULL) {
103 TALLOC_FREE(capname);
107 return SMB_VFS_NEXT_OPENDIR(handle, cap_smb_fname, mask, attr);
110 static struct dirent *cap_readdir(vfs_handle_struct *handle,
112 SMB_STRUCT_STAT *sbuf)
114 struct dirent *result;
115 struct dirent *newdirent;
118 DEBUG(3,("cap: cap_readdir\n"));
120 result = SMB_VFS_NEXT_READDIR(handle, dirp, NULL);
125 newname = capdecode(talloc_tos(), result->d_name);
129 DEBUG(3,("cap: cap_readdir: %s\n", newname));
130 newnamelen = strlen(newname)+1;
131 newdirent = talloc_size(
132 talloc_tos(), sizeof(struct dirent) + newnamelen);
136 talloc_set_name_const(newdirent, "struct dirent");
137 memcpy(newdirent, result, sizeof(struct dirent));
138 memcpy(&newdirent->d_name, newname, newnamelen);
142 static int cap_mkdirat(vfs_handle_struct *handle,
143 struct files_struct *dirfsp,
144 const struct smb_filename *smb_fname,
147 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
148 struct smb_filename *cap_smb_fname = NULL;
155 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
160 if (cap_smb_fname == NULL) {
161 TALLOC_FREE(cappath);
166 return SMB_VFS_NEXT_MKDIRAT(handle,
172 static int cap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname,
173 files_struct *fsp, int flags, mode_t mode)
176 char *tmp_base_name = NULL;
179 cappath = capencode(talloc_tos(), smb_fname->base_name);
186 tmp_base_name = smb_fname->base_name;
187 smb_fname->base_name = cappath;
189 DEBUG(3,("cap: cap_open for %s\n", smb_fname_str_dbg(smb_fname)));
190 ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
192 smb_fname->base_name = tmp_base_name;
193 TALLOC_FREE(cappath);
198 static int cap_renameat(vfs_handle_struct *handle,
199 files_struct *srcfsp,
200 const struct smb_filename *smb_fname_src,
201 files_struct *dstfsp,
202 const struct smb_filename *smb_fname_dst)
206 struct smb_filename *smb_fname_src_tmp = NULL;
207 struct smb_filename *smb_fname_dst_tmp = NULL;
210 capold = capencode(talloc_tos(), smb_fname_src->base_name);
211 capnew = capencode(talloc_tos(), smb_fname_dst->base_name);
212 if (!capold || !capnew) {
217 /* Setup temporary smb_filename structs. */
218 smb_fname_src_tmp = cp_smb_filename(talloc_tos(), smb_fname_src);
219 if (smb_fname_src_tmp == NULL) {
223 smb_fname_dst_tmp = cp_smb_filename(talloc_tos(), smb_fname_dst);
224 if (smb_fname_dst_tmp == NULL) {
229 smb_fname_src_tmp->base_name = capold;
230 smb_fname_dst_tmp->base_name = capnew;
232 ret = SMB_VFS_NEXT_RENAMEAT(handle,
241 TALLOC_FREE(smb_fname_src_tmp);
242 TALLOC_FREE(smb_fname_dst_tmp);
247 static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
250 char *tmp_base_name = NULL;
253 cappath = capencode(talloc_tos(), smb_fname->base_name);
260 tmp_base_name = smb_fname->base_name;
261 smb_fname->base_name = cappath;
263 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
265 smb_fname->base_name = tmp_base_name;
266 TALLOC_FREE(cappath);
271 static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
274 char *tmp_base_name = NULL;
277 cappath = capencode(talloc_tos(), smb_fname->base_name);
284 tmp_base_name = smb_fname->base_name;
285 smb_fname->base_name = cappath;
287 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
289 smb_fname->base_name = tmp_base_name;
290 TALLOC_FREE(cappath);
295 static int cap_unlinkat(vfs_handle_struct *handle,
296 struct files_struct *dirfsp,
297 const struct smb_filename *smb_fname,
300 struct smb_filename *smb_fname_tmp = NULL;
301 char *cappath = NULL;
304 cappath = capencode(talloc_tos(), smb_fname->base_name);
310 /* Setup temporary smb_filename structs. */
311 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
312 if (smb_fname_tmp == NULL) {
317 smb_fname_tmp->base_name = cappath;
319 ret = SMB_VFS_NEXT_UNLINKAT(handle,
324 TALLOC_FREE(smb_fname_tmp);
328 static int cap_chmod(vfs_handle_struct *handle,
329 const struct smb_filename *smb_fname,
332 struct smb_filename *cap_smb_fname = NULL;
333 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
342 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
347 if (cap_smb_fname == NULL) {
348 TALLOC_FREE(cappath);
353 ret = SMB_VFS_NEXT_CHMOD(handle, cap_smb_fname, mode);
355 TALLOC_FREE(cappath);
356 TALLOC_FREE(cap_smb_fname);
361 static int cap_lchown(vfs_handle_struct *handle,
362 const struct smb_filename *smb_fname,
366 struct smb_filename *cap_smb_fname = NULL;
367 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
376 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
381 if (cap_smb_fname == NULL) {
382 TALLOC_FREE(cappath);
387 ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
389 TALLOC_FREE(cappath);
390 TALLOC_FREE(cap_smb_fname);
395 static int cap_chdir(vfs_handle_struct *handle,
396 const struct smb_filename *smb_fname)
398 struct smb_filename *cap_smb_fname = NULL;
399 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
407 DEBUG(3,("cap: cap_chdir for %s\n", smb_fname->base_name));
409 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
414 if (cap_smb_fname == NULL) {
415 TALLOC_FREE(cappath);
419 ret = SMB_VFS_NEXT_CHDIR(handle, cap_smb_fname);
423 TALLOC_FREE(cappath);
424 TALLOC_FREE(cap_smb_fname);
425 if (saved_errno != 0) {
431 static int cap_ntimes(vfs_handle_struct *handle,
432 const struct smb_filename *smb_fname,
433 struct smb_file_time *ft)
435 struct smb_filename *smb_fname_tmp = NULL;
436 char *cappath = NULL;
439 cappath = capencode(talloc_tos(), smb_fname->base_name);
446 /* Setup temporary smb_filename structs. */
447 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
448 if (smb_fname_tmp == NULL) {
453 smb_fname_tmp->base_name = cappath;
455 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
457 TALLOC_FREE(smb_fname_tmp);
461 static int cap_symlinkat(vfs_handle_struct *handle,
462 const char *link_contents,
463 struct files_struct *dirfsp,
464 const struct smb_filename *new_smb_fname)
466 char *capold = capencode(talloc_tos(), link_contents);
467 char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
468 struct smb_filename *new_cap_smb_fname = NULL;
472 if (!capold || !capnew) {
476 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
480 new_smb_fname->flags);
481 if (new_cap_smb_fname == NULL) {
487 ret = SMB_VFS_NEXT_SYMLINKAT(handle,
496 TALLOC_FREE(new_cap_smb_fname);
497 if (saved_errno != 0) {
503 static int cap_readlinkat(vfs_handle_struct *handle,
504 files_struct *dirfsp,
505 const struct smb_filename *smb_fname,
509 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
510 struct smb_filename *cap_smb_fname = NULL;
518 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
523 if (cap_smb_fname == NULL) {
524 TALLOC_FREE(cappath);
528 ret = SMB_VFS_NEXT_READLINKAT(handle,
536 TALLOC_FREE(cappath);
537 TALLOC_FREE(cap_smb_fname);
538 if (saved_errno != 0) {
544 static int cap_linkat(vfs_handle_struct *handle,
545 files_struct *srcfsp,
546 const struct smb_filename *old_smb_fname,
547 files_struct *dstfsp,
548 const struct smb_filename *new_smb_fname,
551 char *capold = capencode(talloc_tos(), old_smb_fname->base_name);
552 char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
553 struct smb_filename *old_cap_smb_fname = NULL;
554 struct smb_filename *new_cap_smb_fname = NULL;
558 if (!capold || !capnew) {
562 old_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
566 old_smb_fname->flags);
567 if (old_cap_smb_fname == NULL) {
573 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
577 new_smb_fname->flags);
578 if (new_cap_smb_fname == NULL) {
581 TALLOC_FREE(old_cap_smb_fname);
585 ret = SMB_VFS_NEXT_LINKAT(handle,
596 TALLOC_FREE(old_cap_smb_fname);
597 TALLOC_FREE(new_cap_smb_fname);
598 if (saved_errno != 0) {
604 static int cap_mknodat(vfs_handle_struct *handle,
605 files_struct *dirfsp,
606 const struct smb_filename *smb_fname,
610 struct smb_filename *cap_smb_fname = NULL;
611 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
619 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
624 if (cap_smb_fname == NULL) {
625 TALLOC_FREE(cappath);
629 ret = SMB_VFS_NEXT_MKNODAT(handle,
637 TALLOC_FREE(cappath);
638 TALLOC_FREE(cap_smb_fname);
639 if (saved_errno != 0) {
645 static struct smb_filename *cap_realpath(vfs_handle_struct *handle,
647 const struct smb_filename *smb_fname)
649 /* monyo need capencode'ed and capdecode'ed? */
650 struct smb_filename *cap_smb_fname = NULL;
651 struct smb_filename *return_fname = NULL;
652 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
659 cap_smb_fname = synthetic_smb_fname(ctx,
664 if (cap_smb_fname == NULL) {
665 TALLOC_FREE(cappath);
669 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, cap_smb_fname);
670 if (return_fname == NULL) {
673 TALLOC_FREE(cappath);
674 TALLOC_FREE(cap_smb_fname);
675 if (saved_errno != 0) {
681 static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle,
682 const struct smb_filename *smb_fname,
686 struct smb_filename *cap_smb_fname = NULL;
687 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
693 return (SMB_ACL_T)NULL;
695 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
700 if (cap_smb_fname == NULL) {
701 TALLOC_FREE(cappath);
703 return (SMB_ACL_T)NULL;
705 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cap_smb_fname,
710 TALLOC_FREE(cappath);
711 TALLOC_FREE(cap_smb_fname);
712 if (saved_errno != 0) {
718 static int cap_sys_acl_set_file(vfs_handle_struct *handle,
719 const struct smb_filename *smb_fname,
720 SMB_ACL_TYPE_T acltype,
723 struct smb_filename *cap_smb_fname = NULL;
724 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
732 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
737 if (cap_smb_fname == NULL) {
738 TALLOC_FREE(cappath);
742 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cap_smb_fname,
747 TALLOC_FREE(cappath);
748 TALLOC_FREE(cap_smb_fname);
749 if (saved_errno != 0) {
755 static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
756 const struct smb_filename *smb_fname)
758 struct smb_filename *cap_smb_fname = NULL;
759 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
767 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
772 if (cap_smb_fname == NULL) {
773 TALLOC_FREE(cappath);
777 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cap_smb_fname);
781 TALLOC_FREE(cappath);
782 TALLOC_FREE(cap_smb_fname);
789 static ssize_t cap_getxattr(vfs_handle_struct *handle,
790 const struct smb_filename *smb_fname,
795 struct smb_filename *cap_smb_fname = NULL;
796 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
797 char *capname = capencode(talloc_tos(), name);
801 if (!cappath || !capname) {
805 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
810 if (cap_smb_fname == NULL) {
811 TALLOC_FREE(cappath);
812 TALLOC_FREE(capname);
816 ret = SMB_VFS_NEXT_GETXATTR(handle, cap_smb_fname,
817 capname, value, size);
821 TALLOC_FREE(cappath);
822 TALLOC_FREE(capname);
823 TALLOC_FREE(cap_smb_fname);
830 static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
832 char *cappath = capencode(talloc_tos(), path);
838 return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
841 static ssize_t cap_listxattr(vfs_handle_struct *handle,
842 const struct smb_filename *smb_fname,
846 struct smb_filename *cap_smb_fname = NULL;
847 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
855 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
860 if (cap_smb_fname == NULL) {
861 TALLOC_FREE(cappath);
865 ret = SMB_VFS_NEXT_LISTXATTR(handle, cap_smb_fname, list, size);
869 TALLOC_FREE(cappath);
870 TALLOC_FREE(cap_smb_fname);
877 static int cap_removexattr(vfs_handle_struct *handle,
878 const struct smb_filename *smb_fname,
881 struct smb_filename *cap_smb_fname = NULL;
882 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
883 char *capname = capencode(talloc_tos(), name);
887 if (!cappath || !capname) {
891 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
896 if (cap_smb_fname == NULL) {
897 TALLOC_FREE(cappath);
898 TALLOC_FREE(capname);
902 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, cap_smb_fname, capname);
906 TALLOC_FREE(cappath);
907 TALLOC_FREE(capname);
908 TALLOC_FREE(cap_smb_fname);
915 static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
917 char *cappath = capencode(talloc_tos(), path);
923 return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
926 static int cap_setxattr(vfs_handle_struct *handle,
927 const struct smb_filename *smb_fname,
933 struct smb_filename *cap_smb_fname = NULL;
934 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
935 char *capname = capencode(talloc_tos(), name);
939 if (!cappath || !capname) {
943 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
948 if (cap_smb_fname == NULL) {
949 TALLOC_FREE(cappath);
950 TALLOC_FREE(capname);
954 ret = SMB_VFS_NEXT_SETXATTR(handle, cap_smb_fname,
955 capname, value, size, flags);
959 TALLOC_FREE(cappath);
960 TALLOC_FREE(capname);
961 TALLOC_FREE(cap_smb_fname);
968 static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
970 char *cappath = capencode(talloc_tos(), path);
976 return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
979 static NTSTATUS cap_create_dfs_pathat(vfs_handle_struct *handle,
980 files_struct *dirfsp,
981 const struct smb_filename *smb_fname,
982 const struct referral *reflist,
983 size_t referral_count)
985 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
986 struct smb_filename *cap_smb_fname = NULL;
989 if (cappath == NULL) {
990 return NT_STATUS_NO_MEMORY;
992 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
997 if (cap_smb_fname == NULL) {
998 TALLOC_FREE(cappath);
999 return NT_STATUS_NO_MEMORY;
1001 status = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
1006 TALLOC_FREE(cappath);
1007 TALLOC_FREE(cap_smb_fname);
1011 static struct vfs_fn_pointers vfs_cap_fns = {
1012 .disk_free_fn = cap_disk_free,
1013 .get_quota_fn = cap_get_quota,
1014 .opendir_fn = cap_opendir,
1015 .readdir_fn = cap_readdir,
1016 .mkdirat_fn = cap_mkdirat,
1017 .open_fn = cap_open,
1018 .renameat_fn = cap_renameat,
1019 .stat_fn = cap_stat,
1020 .lstat_fn = cap_lstat,
1021 .unlinkat_fn = cap_unlinkat,
1022 .chmod_fn = cap_chmod,
1023 .lchown_fn = cap_lchown,
1024 .chdir_fn = cap_chdir,
1025 .ntimes_fn = cap_ntimes,
1026 .symlinkat_fn = cap_symlinkat,
1027 .readlinkat_fn = cap_readlinkat,
1028 .linkat_fn = cap_linkat,
1029 .mknodat_fn = cap_mknodat,
1030 .realpath_fn = cap_realpath,
1031 .sys_acl_get_file_fn = cap_sys_acl_get_file,
1032 .sys_acl_set_file_fn = cap_sys_acl_set_file,
1033 .sys_acl_delete_def_file_fn = cap_sys_acl_delete_def_file,
1034 .getxattr_fn = cap_getxattr,
1035 .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
1036 .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
1037 .fgetxattr_fn = cap_fgetxattr,
1038 .listxattr_fn = cap_listxattr,
1039 .removexattr_fn = cap_removexattr,
1040 .fremovexattr_fn = cap_fremovexattr,
1041 .setxattr_fn = cap_setxattr,
1042 .fsetxattr_fn = cap_fsetxattr,
1043 .create_dfs_pathat_fn = cap_create_dfs_pathat
1047 NTSTATUS vfs_cap_init(TALLOC_CTX *ctx)
1049 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
1053 /* For CAP functions */
1055 #define hex2bin(c) hex2bin_table[(unsigned char)(c)]
1056 #define bin2hex(c) bin2hex_table[(unsigned char)(c)]
1057 #define is_hex(s) ((s)[0] == hex_tag)
1059 static unsigned char hex2bin_table[256] = {
1060 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
1061 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
1062 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
1063 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
1064 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
1065 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1066 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
1067 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
1068 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1069 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
1070 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
1071 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
1072 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
1073 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
1074 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
1075 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
1076 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
1077 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 */
1079 static unsigned char bin2hex_table[256] = "0123456789abcdef";
1081 /*******************************************************************
1082 original code -> ":xx" - CAP format
1083 ********************************************************************/
1085 static char *capencode(TALLOC_CTX *ctx, const char *from)
1092 for (p1 = from; *p1; p1++) {
1093 if ((unsigned char)*p1 >= 0x80) {
1101 to = talloc_array(ctx, char, len);
1106 for (out = to; *from;) {
1107 /* buffer husoku error */
1108 if ((unsigned char)*from >= 0x80) {
1110 *out++ = bin2hex (((*from)>>4)&0x0f);
1111 *out++ = bin2hex ((*from)&0x0f);
1121 /*******************************************************************
1122 CAP -> original code
1123 ********************************************************************/
1124 /* ":xx" -> a byte */
1126 static char *capdecode(TALLOC_CTX *ctx, const char *from)
1133 for (p1 = from; *p1; len++) {
1142 to = talloc_array(ctx, char, len);
1147 for (out = to; *from;) {
1149 *out++ = (hex2bin(from[1])<<4) | (hex2bin(from[2]));