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(),
51 if (cap_smb_fname == NULL) {
56 return SMB_VFS_NEXT_DISK_FREE(handle, cap_smb_fname,
60 static int cap_get_quota(vfs_handle_struct *handle,
61 const struct smb_filename *smb_fname,
62 enum SMB_QUOTA_TYPE qtype,
66 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
67 struct smb_filename *cap_smb_fname = NULL;
73 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
79 if (cap_smb_fname == NULL) {
84 return SMB_VFS_NEXT_GET_QUOTA(handle, cap_smb_fname, qtype, id, dq);
87 static struct dirent *cap_readdir(vfs_handle_struct *handle,
88 struct files_struct *dirfsp,
90 SMB_STRUCT_STAT *sbuf)
92 struct dirent *result;
93 struct dirent *newdirent;
96 DEBUG(3,("cap: cap_readdir\n"));
98 result = SMB_VFS_NEXT_READDIR(handle, dirfsp, dirp, NULL);
103 newname = capdecode(talloc_tos(), result->d_name);
107 DEBUG(3,("cap: cap_readdir: %s\n", newname));
108 newnamelen = strlen(newname)+1;
109 newdirent = talloc_size(
110 talloc_tos(), sizeof(struct dirent) + newnamelen);
114 talloc_set_name_const(newdirent, "struct dirent");
115 memcpy(newdirent, result, sizeof(struct dirent));
116 memcpy(&newdirent->d_name, newname, newnamelen);
120 static int cap_mkdirat(vfs_handle_struct *handle,
121 struct files_struct *dirfsp,
122 const struct smb_filename *smb_fname,
125 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
126 struct smb_filename *cap_smb_fname = NULL;
133 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
139 if (cap_smb_fname == NULL) {
140 TALLOC_FREE(cappath);
145 return SMB_VFS_NEXT_MKDIRAT(handle,
151 static int cap_openat(vfs_handle_struct *handle,
152 const struct files_struct *dirfsp,
153 const struct smb_filename *smb_fname_in,
158 char *cappath = NULL;
159 struct smb_filename *smb_fname = NULL;
163 cappath = capencode(talloc_tos(), smb_fname_in->base_name);
164 if (cappath == NULL) {
169 smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
170 if (smb_fname == NULL) {
171 TALLOC_FREE(cappath);
175 smb_fname->base_name = cappath;
177 DBG_DEBUG("cap_open for %s\n", smb_fname_str_dbg(smb_fname));
178 ret = SMB_VFS_NEXT_OPENAT(handle,
188 TALLOC_FREE(cappath);
189 TALLOC_FREE(smb_fname);
190 if (saved_errno != 0) {
196 static int cap_renameat(vfs_handle_struct *handle,
197 files_struct *srcfsp,
198 const struct smb_filename *smb_fname_src,
199 files_struct *dstfsp,
200 const struct smb_filename *smb_fname_dst)
204 struct smb_filename *smb_fname_src_tmp = NULL;
205 struct smb_filename *smb_fname_dst_tmp = NULL;
208 capold = capencode(talloc_tos(), smb_fname_src->base_name);
209 capnew = capencode(talloc_tos(), smb_fname_dst->base_name);
210 if (!capold || !capnew) {
215 /* Setup temporary smb_filename structs. */
216 smb_fname_src_tmp = cp_smb_filename(talloc_tos(), smb_fname_src);
217 if (smb_fname_src_tmp == NULL) {
221 smb_fname_dst_tmp = cp_smb_filename(talloc_tos(), smb_fname_dst);
222 if (smb_fname_dst_tmp == NULL) {
227 smb_fname_src_tmp->base_name = capold;
228 smb_fname_dst_tmp->base_name = capnew;
230 ret = SMB_VFS_NEXT_RENAMEAT(handle,
239 TALLOC_FREE(smb_fname_src_tmp);
240 TALLOC_FREE(smb_fname_dst_tmp);
245 static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
248 char *tmp_base_name = NULL;
251 cappath = capencode(talloc_tos(), smb_fname->base_name);
258 tmp_base_name = smb_fname->base_name;
259 smb_fname->base_name = cappath;
261 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
263 smb_fname->base_name = tmp_base_name;
264 TALLOC_FREE(cappath);
269 static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
272 char *tmp_base_name = NULL;
275 cappath = capencode(talloc_tos(), smb_fname->base_name);
282 tmp_base_name = smb_fname->base_name;
283 smb_fname->base_name = cappath;
285 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
287 smb_fname->base_name = tmp_base_name;
288 TALLOC_FREE(cappath);
293 static int cap_unlinkat(vfs_handle_struct *handle,
294 struct files_struct *dirfsp,
295 const struct smb_filename *smb_fname,
298 struct smb_filename *full_fname = NULL;
299 struct smb_filename *smb_fname_tmp = NULL;
300 char *cappath = NULL;
303 full_fname = full_path_from_dirfsp_atname(talloc_tos(),
306 if (full_fname == NULL) {
310 cappath = capencode(talloc_tos(), full_fname->base_name);
312 TALLOC_FREE(full_fname);
317 /* Setup temporary smb_filename structs. */
318 smb_fname_tmp = cp_smb_filename(talloc_tos(), full_fname);
319 TALLOC_FREE(full_fname);
320 if (smb_fname_tmp == NULL) {
325 smb_fname_tmp->base_name = cappath;
327 ret = SMB_VFS_NEXT_UNLINKAT(handle,
328 dirfsp->conn->cwd_fsp,
332 TALLOC_FREE(smb_fname_tmp);
336 static int cap_chmod(vfs_handle_struct *handle,
337 const struct smb_filename *smb_fname,
340 struct smb_filename *cap_smb_fname = NULL;
341 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
350 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
356 if (cap_smb_fname == NULL) {
357 TALLOC_FREE(cappath);
362 ret = SMB_VFS_NEXT_CHMOD(handle, cap_smb_fname, mode);
364 TALLOC_FREE(cappath);
365 TALLOC_FREE(cap_smb_fname);
370 static int cap_lchown(vfs_handle_struct *handle,
371 const struct smb_filename *smb_fname,
375 struct smb_filename *cap_smb_fname = NULL;
376 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
385 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
391 if (cap_smb_fname == NULL) {
392 TALLOC_FREE(cappath);
397 ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
399 TALLOC_FREE(cappath);
400 TALLOC_FREE(cap_smb_fname);
405 static int cap_chdir(vfs_handle_struct *handle,
406 const struct smb_filename *smb_fname)
408 struct smb_filename *cap_smb_fname = NULL;
409 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
417 DEBUG(3,("cap: cap_chdir for %s\n", smb_fname->base_name));
419 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
425 if (cap_smb_fname == NULL) {
426 TALLOC_FREE(cappath);
430 ret = SMB_VFS_NEXT_CHDIR(handle, cap_smb_fname);
434 TALLOC_FREE(cappath);
435 TALLOC_FREE(cap_smb_fname);
436 if (saved_errno != 0) {
442 static int cap_ntimes(vfs_handle_struct *handle,
443 const struct smb_filename *smb_fname,
444 struct smb_file_time *ft)
446 struct smb_filename *smb_fname_tmp = NULL;
447 char *cappath = NULL;
450 cappath = capencode(talloc_tos(), smb_fname->base_name);
457 /* Setup temporary smb_filename structs. */
458 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
459 if (smb_fname_tmp == NULL) {
464 smb_fname_tmp->base_name = cappath;
466 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
468 TALLOC_FREE(smb_fname_tmp);
472 static int cap_symlinkat(vfs_handle_struct *handle,
473 const struct smb_filename *link_contents,
474 struct files_struct *dirfsp,
475 const struct smb_filename *new_smb_fname)
477 struct smb_filename *full_fname = NULL;
478 char *capold = capencode(talloc_tos(), link_contents->base_name);
480 struct smb_filename *new_link_target = NULL;
481 struct smb_filename *new_cap_smb_fname = NULL;
485 if (!capold || !capnew) {
490 full_fname = full_path_from_dirfsp_atname(talloc_tos(),
493 if (full_fname == NULL) {
497 capnew = capencode(talloc_tos(), full_fname->base_name);
499 TALLOC_FREE(full_fname);
504 new_link_target = synthetic_smb_fname(talloc_tos(),
509 new_smb_fname->flags);
510 if (new_link_target == NULL) {
511 TALLOC_FREE(full_fname);
518 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
523 new_smb_fname->flags);
524 if (new_cap_smb_fname == NULL) {
525 TALLOC_FREE(full_fname);
528 TALLOC_FREE(new_link_target);
532 ret = SMB_VFS_NEXT_SYMLINKAT(handle,
534 handle->conn->cwd_fsp,
539 TALLOC_FREE(full_fname);
542 TALLOC_FREE(new_link_target);
543 TALLOC_FREE(new_cap_smb_fname);
544 if (saved_errno != 0) {
550 static int cap_readlinkat(vfs_handle_struct *handle,
551 const struct files_struct *dirfsp,
552 const struct smb_filename *smb_fname,
556 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
557 struct smb_filename *cap_smb_fname = NULL;
565 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
571 if (cap_smb_fname == NULL) {
572 TALLOC_FREE(cappath);
576 ret = SMB_VFS_NEXT_READLINKAT(handle,
584 TALLOC_FREE(cappath);
585 TALLOC_FREE(cap_smb_fname);
586 if (saved_errno != 0) {
592 static int cap_linkat(vfs_handle_struct *handle,
593 files_struct *srcfsp,
594 const struct smb_filename *old_smb_fname,
595 files_struct *dstfsp,
596 const struct smb_filename *new_smb_fname,
599 char *capold = capencode(talloc_tos(), old_smb_fname->base_name);
600 char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
601 struct smb_filename *old_cap_smb_fname = NULL;
602 struct smb_filename *new_cap_smb_fname = NULL;
606 if (!capold || !capnew) {
610 old_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
615 old_smb_fname->flags);
616 if (old_cap_smb_fname == NULL) {
622 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
627 new_smb_fname->flags);
628 if (new_cap_smb_fname == NULL) {
631 TALLOC_FREE(old_cap_smb_fname);
635 ret = SMB_VFS_NEXT_LINKAT(handle,
646 TALLOC_FREE(old_cap_smb_fname);
647 TALLOC_FREE(new_cap_smb_fname);
648 if (saved_errno != 0) {
654 static int cap_mknodat(vfs_handle_struct *handle,
655 files_struct *dirfsp,
656 const struct smb_filename *smb_fname,
660 struct smb_filename *full_fname = NULL;
661 struct smb_filename *cap_smb_fname = NULL;
662 char *cappath = NULL;
666 full_fname = full_path_from_dirfsp_atname(talloc_tos(),
669 if (full_fname == NULL) {
673 cappath = capencode(talloc_tos(), full_fname->base_name);
675 TALLOC_FREE(full_fname);
679 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
685 if (cap_smb_fname == NULL) {
686 TALLOC_FREE(full_fname);
687 TALLOC_FREE(cappath);
691 ret = SMB_VFS_NEXT_MKNODAT(handle,
692 handle->conn->cwd_fsp,
699 TALLOC_FREE(full_fname);
700 TALLOC_FREE(cappath);
701 TALLOC_FREE(cap_smb_fname);
702 if (saved_errno != 0) {
708 static struct smb_filename *cap_realpath(vfs_handle_struct *handle,
710 const struct smb_filename *smb_fname)
712 /* monyo need capencode'ed and capdecode'ed? */
713 struct smb_filename *cap_smb_fname = NULL;
714 struct smb_filename *return_fname = NULL;
715 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
722 cap_smb_fname = synthetic_smb_fname(ctx,
728 if (cap_smb_fname == NULL) {
729 TALLOC_FREE(cappath);
733 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, cap_smb_fname);
734 if (return_fname == NULL) {
737 TALLOC_FREE(cappath);
738 TALLOC_FREE(cap_smb_fname);
739 if (saved_errno != 0) {
745 static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle,
746 const struct smb_filename *smb_fname,
750 struct smb_filename *cap_smb_fname = NULL;
751 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
757 return (SMB_ACL_T)NULL;
759 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
765 if (cap_smb_fname == NULL) {
766 TALLOC_FREE(cappath);
768 return (SMB_ACL_T)NULL;
770 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cap_smb_fname,
775 TALLOC_FREE(cappath);
776 TALLOC_FREE(cap_smb_fname);
777 if (saved_errno != 0) {
783 static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
784 const struct smb_filename *smb_fname)
786 struct smb_filename *cap_smb_fname = NULL;
787 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
795 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
801 if (cap_smb_fname == NULL) {
802 TALLOC_FREE(cappath);
806 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cap_smb_fname);
810 TALLOC_FREE(cappath);
811 TALLOC_FREE(cap_smb_fname);
818 static ssize_t cap_getxattr(vfs_handle_struct *handle,
819 const struct smb_filename *smb_fname,
824 struct smb_filename *cap_smb_fname = NULL;
825 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
826 char *capname = capencode(talloc_tos(), name);
830 if (!cappath || !capname) {
834 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
840 if (cap_smb_fname == NULL) {
841 TALLOC_FREE(cappath);
842 TALLOC_FREE(capname);
846 ret = SMB_VFS_NEXT_GETXATTR(handle, cap_smb_fname,
847 capname, value, size);
851 TALLOC_FREE(cappath);
852 TALLOC_FREE(capname);
853 TALLOC_FREE(cap_smb_fname);
860 static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
862 char *cappath = capencode(talloc_tos(), path);
868 return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
871 static ssize_t cap_listxattr(vfs_handle_struct *handle,
872 const struct smb_filename *smb_fname,
876 struct smb_filename *cap_smb_fname = NULL;
877 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
885 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
891 if (cap_smb_fname == NULL) {
892 TALLOC_FREE(cappath);
896 ret = SMB_VFS_NEXT_LISTXATTR(handle, cap_smb_fname, list, size);
900 TALLOC_FREE(cappath);
901 TALLOC_FREE(cap_smb_fname);
908 static int cap_removexattr(vfs_handle_struct *handle,
909 const struct smb_filename *smb_fname,
912 struct smb_filename *cap_smb_fname = NULL;
913 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
914 char *capname = capencode(talloc_tos(), name);
918 if (!cappath || !capname) {
922 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
928 if (cap_smb_fname == NULL) {
929 TALLOC_FREE(cappath);
930 TALLOC_FREE(capname);
934 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, cap_smb_fname, capname);
938 TALLOC_FREE(cappath);
939 TALLOC_FREE(capname);
940 TALLOC_FREE(cap_smb_fname);
947 static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
949 char *cappath = capencode(talloc_tos(), path);
955 return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
958 static int cap_setxattr(vfs_handle_struct *handle,
959 const struct smb_filename *smb_fname,
965 struct smb_filename *cap_smb_fname = NULL;
966 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
967 char *capname = capencode(talloc_tos(), name);
971 if (!cappath || !capname) {
975 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
981 if (cap_smb_fname == NULL) {
982 TALLOC_FREE(cappath);
983 TALLOC_FREE(capname);
987 ret = SMB_VFS_NEXT_SETXATTR(handle, cap_smb_fname,
988 capname, value, size, flags);
992 TALLOC_FREE(cappath);
993 TALLOC_FREE(capname);
994 TALLOC_FREE(cap_smb_fname);
1001 static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
1003 char *cappath = capencode(talloc_tos(), path);
1009 return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
1012 static NTSTATUS cap_create_dfs_pathat(vfs_handle_struct *handle,
1013 files_struct *dirfsp,
1014 const struct smb_filename *smb_fname,
1015 const struct referral *reflist,
1016 size_t referral_count)
1018 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
1019 struct smb_filename *cap_smb_fname = NULL;
1022 if (cappath == NULL) {
1023 return NT_STATUS_NO_MEMORY;
1025 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
1031 if (cap_smb_fname == NULL) {
1032 TALLOC_FREE(cappath);
1033 return NT_STATUS_NO_MEMORY;
1035 status = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
1040 TALLOC_FREE(cappath);
1041 TALLOC_FREE(cap_smb_fname);
1045 static NTSTATUS cap_read_dfs_pathat(struct vfs_handle_struct *handle,
1046 TALLOC_CTX *mem_ctx,
1047 struct files_struct *dirfsp,
1048 struct smb_filename *smb_fname,
1049 struct referral **ppreflist,
1050 size_t *preferral_count)
1052 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
1053 struct smb_filename *cap_smb_fname = NULL;
1056 if (cappath == NULL) {
1057 return NT_STATUS_NO_MEMORY;
1059 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
1065 if (cap_smb_fname == NULL) {
1066 TALLOC_FREE(cappath);
1067 return NT_STATUS_NO_MEMORY;
1070 status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
1077 if (NT_STATUS_IS_OK(status)) {
1078 /* Return any stat(2) info. */
1079 smb_fname->st = cap_smb_fname->st;
1082 TALLOC_FREE(cappath);
1083 TALLOC_FREE(cap_smb_fname);
1087 static struct vfs_fn_pointers vfs_cap_fns = {
1088 .disk_free_fn = cap_disk_free,
1089 .get_quota_fn = cap_get_quota,
1090 .readdir_fn = cap_readdir,
1091 .mkdirat_fn = cap_mkdirat,
1092 .openat_fn = cap_openat,
1093 .renameat_fn = cap_renameat,
1094 .stat_fn = cap_stat,
1095 .lstat_fn = cap_lstat,
1096 .unlinkat_fn = cap_unlinkat,
1097 .chmod_fn = cap_chmod,
1098 .lchown_fn = cap_lchown,
1099 .chdir_fn = cap_chdir,
1100 .ntimes_fn = cap_ntimes,
1101 .symlinkat_fn = cap_symlinkat,
1102 .readlinkat_fn = cap_readlinkat,
1103 .linkat_fn = cap_linkat,
1104 .mknodat_fn = cap_mknodat,
1105 .realpath_fn = cap_realpath,
1106 .sys_acl_get_file_fn = cap_sys_acl_get_file,
1107 .sys_acl_delete_def_file_fn = cap_sys_acl_delete_def_file,
1108 .getxattr_fn = cap_getxattr,
1109 .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
1110 .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
1111 .fgetxattr_fn = cap_fgetxattr,
1112 .listxattr_fn = cap_listxattr,
1113 .removexattr_fn = cap_removexattr,
1114 .fremovexattr_fn = cap_fremovexattr,
1115 .setxattr_fn = cap_setxattr,
1116 .fsetxattr_fn = cap_fsetxattr,
1117 .create_dfs_pathat_fn = cap_create_dfs_pathat,
1118 .read_dfs_pathat_fn = cap_read_dfs_pathat
1122 NTSTATUS vfs_cap_init(TALLOC_CTX *ctx)
1124 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
1128 /* For CAP functions */
1130 #define hex2bin(c) hex2bin_table[(unsigned char)(c)]
1131 #define bin2hex(c) bin2hex_table[(unsigned char)(c)]
1132 #define is_hex(s) ((s)[0] == hex_tag)
1134 static unsigned char hex2bin_table[256] = {
1135 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
1136 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
1137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
1138 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
1139 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
1140 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
1142 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
1143 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1144 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
1145 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
1146 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
1147 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
1148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
1149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
1150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
1151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
1152 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 */
1154 static unsigned char bin2hex_table[256] = "0123456789abcdef";
1156 /*******************************************************************
1157 original code -> ":xx" - CAP format
1158 ********************************************************************/
1160 static char *capencode(TALLOC_CTX *ctx, const char *from)
1167 for (p1 = from; *p1; p1++) {
1168 if ((unsigned char)*p1 >= 0x80) {
1176 to = talloc_array(ctx, char, len);
1181 for (out = to; *from;) {
1182 /* buffer husoku error */
1183 if ((unsigned char)*from >= 0x80) {
1185 *out++ = bin2hex (((*from)>>4)&0x0f);
1186 *out++ = bin2hex ((*from)&0x0f);
1196 /*******************************************************************
1197 CAP -> original code
1198 ********************************************************************/
1199 /* ":xx" -> a byte */
1201 static char *capdecode(TALLOC_CTX *ctx, const char *from)
1208 for (p1 = from; *p1; len++) {
1217 to = talloc_array(ctx, char, len);
1222 for (out = to; *from;) {
1224 *out++ = (hex2bin(from[1])<<4) | (hex2bin(from[2]));