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,
89 SMB_STRUCT_STAT *sbuf)
91 struct dirent *result;
92 struct dirent *newdirent;
95 DEBUG(3,("cap: cap_readdir\n"));
97 result = SMB_VFS_NEXT_READDIR(handle, dirp, NULL);
102 newname = capdecode(talloc_tos(), result->d_name);
106 DEBUG(3,("cap: cap_readdir: %s\n", newname));
107 newnamelen = strlen(newname)+1;
108 newdirent = talloc_size(
109 talloc_tos(), sizeof(struct dirent) + newnamelen);
113 talloc_set_name_const(newdirent, "struct dirent");
114 memcpy(newdirent, result, sizeof(struct dirent));
115 memcpy(&newdirent->d_name, newname, newnamelen);
119 static int cap_mkdirat(vfs_handle_struct *handle,
120 struct files_struct *dirfsp,
121 const struct smb_filename *smb_fname,
124 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
125 struct smb_filename *cap_smb_fname = NULL;
132 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
138 if (cap_smb_fname == NULL) {
139 TALLOC_FREE(cappath);
144 return SMB_VFS_NEXT_MKDIRAT(handle,
150 static int cap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname,
151 files_struct *fsp, int flags, mode_t mode)
154 char *tmp_base_name = NULL;
157 cappath = capencode(talloc_tos(), smb_fname->base_name);
164 tmp_base_name = smb_fname->base_name;
165 smb_fname->base_name = cappath;
167 DEBUG(3,("cap: cap_open for %s\n", smb_fname_str_dbg(smb_fname)));
168 ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
170 smb_fname->base_name = tmp_base_name;
171 TALLOC_FREE(cappath);
176 static int cap_openat(vfs_handle_struct *handle,
177 const struct files_struct *dirfsp,
178 const struct smb_filename *smb_fname_in,
183 char *cappath = NULL;
184 struct smb_filename *smb_fname = NULL;
188 cappath = capencode(talloc_tos(), smb_fname->base_name);
189 if (cappath == NULL) {
194 smb_fname = cp_smb_filename(talloc_tos(), smb_fname_in);
195 if (smb_fname == NULL) {
196 TALLOC_FREE(cappath);
200 smb_fname->base_name = cappath;
202 DBG_DEBUG("cap_open for %s\n", smb_fname_str_dbg(smb_fname));
203 ret = SMB_VFS_NEXT_OPENAT(handle,
213 TALLOC_FREE(cappath);
214 TALLOC_FREE(smb_fname);
215 if (saved_errno != 0) {
221 static int cap_renameat(vfs_handle_struct *handle,
222 files_struct *srcfsp,
223 const struct smb_filename *smb_fname_src,
224 files_struct *dstfsp,
225 const struct smb_filename *smb_fname_dst)
229 struct smb_filename *smb_fname_src_tmp = NULL;
230 struct smb_filename *smb_fname_dst_tmp = NULL;
233 capold = capencode(talloc_tos(), smb_fname_src->base_name);
234 capnew = capencode(talloc_tos(), smb_fname_dst->base_name);
235 if (!capold || !capnew) {
240 /* Setup temporary smb_filename structs. */
241 smb_fname_src_tmp = cp_smb_filename(talloc_tos(), smb_fname_src);
242 if (smb_fname_src_tmp == NULL) {
246 smb_fname_dst_tmp = cp_smb_filename(talloc_tos(), smb_fname_dst);
247 if (smb_fname_dst_tmp == NULL) {
252 smb_fname_src_tmp->base_name = capold;
253 smb_fname_dst_tmp->base_name = capnew;
255 ret = SMB_VFS_NEXT_RENAMEAT(handle,
264 TALLOC_FREE(smb_fname_src_tmp);
265 TALLOC_FREE(smb_fname_dst_tmp);
270 static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
273 char *tmp_base_name = NULL;
276 cappath = capencode(talloc_tos(), smb_fname->base_name);
283 tmp_base_name = smb_fname->base_name;
284 smb_fname->base_name = cappath;
286 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
288 smb_fname->base_name = tmp_base_name;
289 TALLOC_FREE(cappath);
294 static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
297 char *tmp_base_name = NULL;
300 cappath = capencode(talloc_tos(), smb_fname->base_name);
307 tmp_base_name = smb_fname->base_name;
308 smb_fname->base_name = cappath;
310 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
312 smb_fname->base_name = tmp_base_name;
313 TALLOC_FREE(cappath);
318 static int cap_unlinkat(vfs_handle_struct *handle,
319 struct files_struct *dirfsp,
320 const struct smb_filename *smb_fname,
323 struct smb_filename *smb_fname_tmp = NULL;
324 char *cappath = NULL;
327 cappath = capencode(talloc_tos(), smb_fname->base_name);
333 /* Setup temporary smb_filename structs. */
334 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
335 if (smb_fname_tmp == NULL) {
340 smb_fname_tmp->base_name = cappath;
342 ret = SMB_VFS_NEXT_UNLINKAT(handle,
347 TALLOC_FREE(smb_fname_tmp);
351 static int cap_chmod(vfs_handle_struct *handle,
352 const struct smb_filename *smb_fname,
355 struct smb_filename *cap_smb_fname = NULL;
356 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
365 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
371 if (cap_smb_fname == NULL) {
372 TALLOC_FREE(cappath);
377 ret = SMB_VFS_NEXT_CHMOD(handle, cap_smb_fname, mode);
379 TALLOC_FREE(cappath);
380 TALLOC_FREE(cap_smb_fname);
385 static int cap_lchown(vfs_handle_struct *handle,
386 const struct smb_filename *smb_fname,
390 struct smb_filename *cap_smb_fname = NULL;
391 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
400 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
406 if (cap_smb_fname == NULL) {
407 TALLOC_FREE(cappath);
412 ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
414 TALLOC_FREE(cappath);
415 TALLOC_FREE(cap_smb_fname);
420 static int cap_chdir(vfs_handle_struct *handle,
421 const struct smb_filename *smb_fname)
423 struct smb_filename *cap_smb_fname = NULL;
424 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
432 DEBUG(3,("cap: cap_chdir for %s\n", smb_fname->base_name));
434 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
440 if (cap_smb_fname == NULL) {
441 TALLOC_FREE(cappath);
445 ret = SMB_VFS_NEXT_CHDIR(handle, cap_smb_fname);
449 TALLOC_FREE(cappath);
450 TALLOC_FREE(cap_smb_fname);
451 if (saved_errno != 0) {
457 static int cap_ntimes(vfs_handle_struct *handle,
458 const struct smb_filename *smb_fname,
459 struct smb_file_time *ft)
461 struct smb_filename *smb_fname_tmp = NULL;
462 char *cappath = NULL;
465 cappath = capencode(talloc_tos(), smb_fname->base_name);
472 /* Setup temporary smb_filename structs. */
473 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
474 if (smb_fname_tmp == NULL) {
479 smb_fname_tmp->base_name = cappath;
481 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
483 TALLOC_FREE(smb_fname_tmp);
487 static int cap_symlinkat(vfs_handle_struct *handle,
488 const struct smb_filename *link_contents,
489 struct files_struct *dirfsp,
490 const struct smb_filename *new_smb_fname)
492 char *capold = capencode(talloc_tos(), link_contents->base_name);
493 char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
494 struct smb_filename *new_link_target = NULL;
495 struct smb_filename *new_cap_smb_fname = NULL;
499 if (!capold || !capnew) {
504 new_link_target = synthetic_smb_fname(talloc_tos(),
509 new_smb_fname->flags);
510 if (new_link_target == NULL) {
517 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
522 new_smb_fname->flags);
523 if (new_cap_smb_fname == NULL) {
526 TALLOC_FREE(new_link_target);
530 ret = SMB_VFS_NEXT_SYMLINKAT(handle,
539 TALLOC_FREE(new_link_target);
540 TALLOC_FREE(new_cap_smb_fname);
541 if (saved_errno != 0) {
547 static int cap_readlinkat(vfs_handle_struct *handle,
548 files_struct *dirfsp,
549 const struct smb_filename *smb_fname,
553 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
554 struct smb_filename *cap_smb_fname = NULL;
562 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
568 if (cap_smb_fname == NULL) {
569 TALLOC_FREE(cappath);
573 ret = SMB_VFS_NEXT_READLINKAT(handle,
581 TALLOC_FREE(cappath);
582 TALLOC_FREE(cap_smb_fname);
583 if (saved_errno != 0) {
589 static int cap_linkat(vfs_handle_struct *handle,
590 files_struct *srcfsp,
591 const struct smb_filename *old_smb_fname,
592 files_struct *dstfsp,
593 const struct smb_filename *new_smb_fname,
596 char *capold = capencode(talloc_tos(), old_smb_fname->base_name);
597 char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
598 struct smb_filename *old_cap_smb_fname = NULL;
599 struct smb_filename *new_cap_smb_fname = NULL;
603 if (!capold || !capnew) {
607 old_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
612 old_smb_fname->flags);
613 if (old_cap_smb_fname == NULL) {
619 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
624 new_smb_fname->flags);
625 if (new_cap_smb_fname == NULL) {
628 TALLOC_FREE(old_cap_smb_fname);
632 ret = SMB_VFS_NEXT_LINKAT(handle,
643 TALLOC_FREE(old_cap_smb_fname);
644 TALLOC_FREE(new_cap_smb_fname);
645 if (saved_errno != 0) {
651 static int cap_mknodat(vfs_handle_struct *handle,
652 files_struct *dirfsp,
653 const struct smb_filename *smb_fname,
657 struct smb_filename *cap_smb_fname = NULL;
658 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
666 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
672 if (cap_smb_fname == NULL) {
673 TALLOC_FREE(cappath);
677 ret = SMB_VFS_NEXT_MKNODAT(handle,
685 TALLOC_FREE(cappath);
686 TALLOC_FREE(cap_smb_fname);
687 if (saved_errno != 0) {
693 static struct smb_filename *cap_realpath(vfs_handle_struct *handle,
695 const struct smb_filename *smb_fname)
697 /* monyo need capencode'ed and capdecode'ed? */
698 struct smb_filename *cap_smb_fname = NULL;
699 struct smb_filename *return_fname = NULL;
700 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
707 cap_smb_fname = synthetic_smb_fname(ctx,
713 if (cap_smb_fname == NULL) {
714 TALLOC_FREE(cappath);
718 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, cap_smb_fname);
719 if (return_fname == NULL) {
722 TALLOC_FREE(cappath);
723 TALLOC_FREE(cap_smb_fname);
724 if (saved_errno != 0) {
730 static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle,
731 const struct smb_filename *smb_fname,
735 struct smb_filename *cap_smb_fname = NULL;
736 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
742 return (SMB_ACL_T)NULL;
744 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
750 if (cap_smb_fname == NULL) {
751 TALLOC_FREE(cappath);
753 return (SMB_ACL_T)NULL;
755 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cap_smb_fname,
760 TALLOC_FREE(cappath);
761 TALLOC_FREE(cap_smb_fname);
762 if (saved_errno != 0) {
768 static int cap_sys_acl_set_file(vfs_handle_struct *handle,
769 const struct smb_filename *smb_fname,
770 SMB_ACL_TYPE_T acltype,
773 struct smb_filename *cap_smb_fname = NULL;
774 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
782 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
788 if (cap_smb_fname == NULL) {
789 TALLOC_FREE(cappath);
793 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cap_smb_fname,
798 TALLOC_FREE(cappath);
799 TALLOC_FREE(cap_smb_fname);
800 if (saved_errno != 0) {
806 static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
807 const struct smb_filename *smb_fname)
809 struct smb_filename *cap_smb_fname = NULL;
810 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
818 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
824 if (cap_smb_fname == NULL) {
825 TALLOC_FREE(cappath);
829 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cap_smb_fname);
833 TALLOC_FREE(cappath);
834 TALLOC_FREE(cap_smb_fname);
841 static ssize_t cap_getxattr(vfs_handle_struct *handle,
842 const struct smb_filename *smb_fname,
847 struct smb_filename *cap_smb_fname = NULL;
848 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
849 char *capname = capencode(talloc_tos(), name);
853 if (!cappath || !capname) {
857 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
863 if (cap_smb_fname == NULL) {
864 TALLOC_FREE(cappath);
865 TALLOC_FREE(capname);
869 ret = SMB_VFS_NEXT_GETXATTR(handle, cap_smb_fname,
870 capname, value, size);
874 TALLOC_FREE(cappath);
875 TALLOC_FREE(capname);
876 TALLOC_FREE(cap_smb_fname);
883 static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
885 char *cappath = capencode(talloc_tos(), path);
891 return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
894 static ssize_t cap_listxattr(vfs_handle_struct *handle,
895 const struct smb_filename *smb_fname,
899 struct smb_filename *cap_smb_fname = NULL;
900 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
908 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
914 if (cap_smb_fname == NULL) {
915 TALLOC_FREE(cappath);
919 ret = SMB_VFS_NEXT_LISTXATTR(handle, cap_smb_fname, list, size);
923 TALLOC_FREE(cappath);
924 TALLOC_FREE(cap_smb_fname);
931 static int cap_removexattr(vfs_handle_struct *handle,
932 const struct smb_filename *smb_fname,
935 struct smb_filename *cap_smb_fname = NULL;
936 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
937 char *capname = capencode(talloc_tos(), name);
941 if (!cappath || !capname) {
945 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
951 if (cap_smb_fname == NULL) {
952 TALLOC_FREE(cappath);
953 TALLOC_FREE(capname);
957 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, cap_smb_fname, capname);
961 TALLOC_FREE(cappath);
962 TALLOC_FREE(capname);
963 TALLOC_FREE(cap_smb_fname);
970 static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
972 char *cappath = capencode(talloc_tos(), path);
978 return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
981 static int cap_setxattr(vfs_handle_struct *handle,
982 const struct smb_filename *smb_fname,
988 struct smb_filename *cap_smb_fname = NULL;
989 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
990 char *capname = capencode(talloc_tos(), name);
994 if (!cappath || !capname) {
998 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
1004 if (cap_smb_fname == NULL) {
1005 TALLOC_FREE(cappath);
1006 TALLOC_FREE(capname);
1010 ret = SMB_VFS_NEXT_SETXATTR(handle, cap_smb_fname,
1011 capname, value, size, flags);
1013 saved_errno = errno;
1015 TALLOC_FREE(cappath);
1016 TALLOC_FREE(capname);
1017 TALLOC_FREE(cap_smb_fname);
1019 errno = saved_errno;
1024 static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
1026 char *cappath = capencode(talloc_tos(), path);
1032 return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
1035 static NTSTATUS cap_create_dfs_pathat(vfs_handle_struct *handle,
1036 files_struct *dirfsp,
1037 const struct smb_filename *smb_fname,
1038 const struct referral *reflist,
1039 size_t referral_count)
1041 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
1042 struct smb_filename *cap_smb_fname = NULL;
1045 if (cappath == NULL) {
1046 return NT_STATUS_NO_MEMORY;
1048 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
1054 if (cap_smb_fname == NULL) {
1055 TALLOC_FREE(cappath);
1056 return NT_STATUS_NO_MEMORY;
1058 status = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
1063 TALLOC_FREE(cappath);
1064 TALLOC_FREE(cap_smb_fname);
1068 static NTSTATUS cap_read_dfs_pathat(struct vfs_handle_struct *handle,
1069 TALLOC_CTX *mem_ctx,
1070 struct files_struct *dirfsp,
1071 const struct smb_filename *smb_fname,
1072 struct referral **ppreflist,
1073 size_t *preferral_count)
1075 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
1076 struct smb_filename *cap_smb_fname = NULL;
1079 if (cappath == NULL) {
1080 return NT_STATUS_NO_MEMORY;
1082 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
1088 if (cap_smb_fname == NULL) {
1089 TALLOC_FREE(cappath);
1090 return NT_STATUS_NO_MEMORY;
1093 status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
1099 TALLOC_FREE(cappath);
1100 TALLOC_FREE(cap_smb_fname);
1104 static struct vfs_fn_pointers vfs_cap_fns = {
1105 .disk_free_fn = cap_disk_free,
1106 .get_quota_fn = cap_get_quota,
1107 .readdir_fn = cap_readdir,
1108 .mkdirat_fn = cap_mkdirat,
1109 .open_fn = cap_open,
1110 .openat_fn = cap_openat,
1111 .renameat_fn = cap_renameat,
1112 .stat_fn = cap_stat,
1113 .lstat_fn = cap_lstat,
1114 .unlinkat_fn = cap_unlinkat,
1115 .chmod_fn = cap_chmod,
1116 .lchown_fn = cap_lchown,
1117 .chdir_fn = cap_chdir,
1118 .ntimes_fn = cap_ntimes,
1119 .symlinkat_fn = cap_symlinkat,
1120 .readlinkat_fn = cap_readlinkat,
1121 .linkat_fn = cap_linkat,
1122 .mknodat_fn = cap_mknodat,
1123 .realpath_fn = cap_realpath,
1124 .sys_acl_get_file_fn = cap_sys_acl_get_file,
1125 .sys_acl_set_file_fn = cap_sys_acl_set_file,
1126 .sys_acl_delete_def_file_fn = cap_sys_acl_delete_def_file,
1127 .getxattr_fn = cap_getxattr,
1128 .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
1129 .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
1130 .fgetxattr_fn = cap_fgetxattr,
1131 .listxattr_fn = cap_listxattr,
1132 .removexattr_fn = cap_removexattr,
1133 .fremovexattr_fn = cap_fremovexattr,
1134 .setxattr_fn = cap_setxattr,
1135 .fsetxattr_fn = cap_fsetxattr,
1136 .create_dfs_pathat_fn = cap_create_dfs_pathat,
1137 .read_dfs_pathat_fn = cap_read_dfs_pathat
1141 NTSTATUS vfs_cap_init(TALLOC_CTX *ctx)
1143 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
1147 /* For CAP functions */
1149 #define hex2bin(c) hex2bin_table[(unsigned char)(c)]
1150 #define bin2hex(c) bin2hex_table[(unsigned char)(c)]
1151 #define is_hex(s) ((s)[0] == hex_tag)
1153 static unsigned char hex2bin_table[256] = {
1154 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
1155 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
1156 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
1157 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
1158 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
1159 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1160 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
1161 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
1162 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1163 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
1164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
1165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
1166 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
1167 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
1168 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
1169 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
1170 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
1171 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 */
1173 static unsigned char bin2hex_table[256] = "0123456789abcdef";
1175 /*******************************************************************
1176 original code -> ":xx" - CAP format
1177 ********************************************************************/
1179 static char *capencode(TALLOC_CTX *ctx, const char *from)
1186 for (p1 = from; *p1; p1++) {
1187 if ((unsigned char)*p1 >= 0x80) {
1195 to = talloc_array(ctx, char, len);
1200 for (out = to; *from;) {
1201 /* buffer husoku error */
1202 if ((unsigned char)*from >= 0x80) {
1204 *out++ = bin2hex (((*from)>>4)&0x0f);
1205 *out++ = bin2hex ((*from)&0x0f);
1215 /*******************************************************************
1216 CAP -> original code
1217 ********************************************************************/
1218 /* ":xx" -> a byte */
1220 static char *capdecode(TALLOC_CTX *ctx, const char *from)
1227 for (p1 = from; *p1; len++) {
1236 to = talloc_array(ctx, char, len);
1241 for (out = to; *from;) {
1243 *out++ = (hex2bin(from[1])<<4) | (hex2bin(from[2]));