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_renameat(vfs_handle_struct *handle,
177 files_struct *srcfsp,
178 const struct smb_filename *smb_fname_src,
179 files_struct *dstfsp,
180 const struct smb_filename *smb_fname_dst)
184 struct smb_filename *smb_fname_src_tmp = NULL;
185 struct smb_filename *smb_fname_dst_tmp = NULL;
188 capold = capencode(talloc_tos(), smb_fname_src->base_name);
189 capnew = capencode(talloc_tos(), smb_fname_dst->base_name);
190 if (!capold || !capnew) {
195 /* Setup temporary smb_filename structs. */
196 smb_fname_src_tmp = cp_smb_filename(talloc_tos(), smb_fname_src);
197 if (smb_fname_src_tmp == NULL) {
201 smb_fname_dst_tmp = cp_smb_filename(talloc_tos(), smb_fname_dst);
202 if (smb_fname_dst_tmp == NULL) {
207 smb_fname_src_tmp->base_name = capold;
208 smb_fname_dst_tmp->base_name = capnew;
210 ret = SMB_VFS_NEXT_RENAMEAT(handle,
219 TALLOC_FREE(smb_fname_src_tmp);
220 TALLOC_FREE(smb_fname_dst_tmp);
225 static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
228 char *tmp_base_name = NULL;
231 cappath = capencode(talloc_tos(), smb_fname->base_name);
238 tmp_base_name = smb_fname->base_name;
239 smb_fname->base_name = cappath;
241 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
243 smb_fname->base_name = tmp_base_name;
244 TALLOC_FREE(cappath);
249 static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
252 char *tmp_base_name = NULL;
255 cappath = capencode(talloc_tos(), smb_fname->base_name);
262 tmp_base_name = smb_fname->base_name;
263 smb_fname->base_name = cappath;
265 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
267 smb_fname->base_name = tmp_base_name;
268 TALLOC_FREE(cappath);
273 static int cap_unlinkat(vfs_handle_struct *handle,
274 struct files_struct *dirfsp,
275 const struct smb_filename *smb_fname,
278 struct smb_filename *smb_fname_tmp = NULL;
279 char *cappath = NULL;
282 cappath = capencode(talloc_tos(), smb_fname->base_name);
288 /* Setup temporary smb_filename structs. */
289 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
290 if (smb_fname_tmp == NULL) {
295 smb_fname_tmp->base_name = cappath;
297 ret = SMB_VFS_NEXT_UNLINKAT(handle,
302 TALLOC_FREE(smb_fname_tmp);
306 static int cap_chmod(vfs_handle_struct *handle,
307 const struct smb_filename *smb_fname,
310 struct smb_filename *cap_smb_fname = NULL;
311 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
320 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
326 if (cap_smb_fname == NULL) {
327 TALLOC_FREE(cappath);
332 ret = SMB_VFS_NEXT_CHMOD(handle, cap_smb_fname, mode);
334 TALLOC_FREE(cappath);
335 TALLOC_FREE(cap_smb_fname);
340 static int cap_lchown(vfs_handle_struct *handle,
341 const struct smb_filename *smb_fname,
345 struct smb_filename *cap_smb_fname = NULL;
346 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
355 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
361 if (cap_smb_fname == NULL) {
362 TALLOC_FREE(cappath);
367 ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
369 TALLOC_FREE(cappath);
370 TALLOC_FREE(cap_smb_fname);
375 static int cap_chdir(vfs_handle_struct *handle,
376 const struct smb_filename *smb_fname)
378 struct smb_filename *cap_smb_fname = NULL;
379 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
387 DEBUG(3,("cap: cap_chdir for %s\n", smb_fname->base_name));
389 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
395 if (cap_smb_fname == NULL) {
396 TALLOC_FREE(cappath);
400 ret = SMB_VFS_NEXT_CHDIR(handle, cap_smb_fname);
404 TALLOC_FREE(cappath);
405 TALLOC_FREE(cap_smb_fname);
406 if (saved_errno != 0) {
412 static int cap_ntimes(vfs_handle_struct *handle,
413 const struct smb_filename *smb_fname,
414 struct smb_file_time *ft)
416 struct smb_filename *smb_fname_tmp = NULL;
417 char *cappath = NULL;
420 cappath = capencode(talloc_tos(), smb_fname->base_name);
427 /* Setup temporary smb_filename structs. */
428 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
429 if (smb_fname_tmp == NULL) {
434 smb_fname_tmp->base_name = cappath;
436 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
438 TALLOC_FREE(smb_fname_tmp);
442 static int cap_symlinkat(vfs_handle_struct *handle,
443 const struct smb_filename *link_contents,
444 struct files_struct *dirfsp,
445 const struct smb_filename *new_smb_fname)
447 char *capold = capencode(talloc_tos(), link_contents->base_name);
448 char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
449 struct smb_filename *new_link_target = NULL;
450 struct smb_filename *new_cap_smb_fname = NULL;
454 if (!capold || !capnew) {
459 new_link_target = synthetic_smb_fname(talloc_tos(),
464 new_smb_fname->flags);
465 if (new_link_target == NULL) {
472 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
477 new_smb_fname->flags);
478 if (new_cap_smb_fname == NULL) {
481 TALLOC_FREE(new_link_target);
485 ret = SMB_VFS_NEXT_SYMLINKAT(handle,
494 TALLOC_FREE(new_link_target);
495 TALLOC_FREE(new_cap_smb_fname);
496 if (saved_errno != 0) {
502 static int cap_readlinkat(vfs_handle_struct *handle,
503 files_struct *dirfsp,
504 const struct smb_filename *smb_fname,
508 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
509 struct smb_filename *cap_smb_fname = NULL;
517 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(),
567 old_smb_fname->flags);
568 if (old_cap_smb_fname == NULL) {
574 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
579 new_smb_fname->flags);
580 if (new_cap_smb_fname == NULL) {
583 TALLOC_FREE(old_cap_smb_fname);
587 ret = SMB_VFS_NEXT_LINKAT(handle,
598 TALLOC_FREE(old_cap_smb_fname);
599 TALLOC_FREE(new_cap_smb_fname);
600 if (saved_errno != 0) {
606 static int cap_mknodat(vfs_handle_struct *handle,
607 files_struct *dirfsp,
608 const struct smb_filename *smb_fname,
612 struct smb_filename *cap_smb_fname = NULL;
613 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
621 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
627 if (cap_smb_fname == NULL) {
628 TALLOC_FREE(cappath);
632 ret = SMB_VFS_NEXT_MKNODAT(handle,
640 TALLOC_FREE(cappath);
641 TALLOC_FREE(cap_smb_fname);
642 if (saved_errno != 0) {
648 static struct smb_filename *cap_realpath(vfs_handle_struct *handle,
650 const struct smb_filename *smb_fname)
652 /* monyo need capencode'ed and capdecode'ed? */
653 struct smb_filename *cap_smb_fname = NULL;
654 struct smb_filename *return_fname = NULL;
655 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
662 cap_smb_fname = synthetic_smb_fname(ctx,
668 if (cap_smb_fname == NULL) {
669 TALLOC_FREE(cappath);
673 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, cap_smb_fname);
674 if (return_fname == NULL) {
677 TALLOC_FREE(cappath);
678 TALLOC_FREE(cap_smb_fname);
679 if (saved_errno != 0) {
685 static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle,
686 const struct smb_filename *smb_fname,
690 struct smb_filename *cap_smb_fname = NULL;
691 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
697 return (SMB_ACL_T)NULL;
699 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
705 if (cap_smb_fname == NULL) {
706 TALLOC_FREE(cappath);
708 return (SMB_ACL_T)NULL;
710 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cap_smb_fname,
715 TALLOC_FREE(cappath);
716 TALLOC_FREE(cap_smb_fname);
717 if (saved_errno != 0) {
723 static int cap_sys_acl_set_file(vfs_handle_struct *handle,
724 const struct smb_filename *smb_fname,
725 SMB_ACL_TYPE_T acltype,
728 struct smb_filename *cap_smb_fname = NULL;
729 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
737 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
743 if (cap_smb_fname == NULL) {
744 TALLOC_FREE(cappath);
748 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cap_smb_fname,
753 TALLOC_FREE(cappath);
754 TALLOC_FREE(cap_smb_fname);
755 if (saved_errno != 0) {
761 static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
762 const struct smb_filename *smb_fname)
764 struct smb_filename *cap_smb_fname = NULL;
765 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
773 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
779 if (cap_smb_fname == NULL) {
780 TALLOC_FREE(cappath);
784 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cap_smb_fname);
788 TALLOC_FREE(cappath);
789 TALLOC_FREE(cap_smb_fname);
796 static ssize_t cap_getxattr(vfs_handle_struct *handle,
797 const struct smb_filename *smb_fname,
802 struct smb_filename *cap_smb_fname = NULL;
803 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
804 char *capname = capencode(talloc_tos(), name);
808 if (!cappath || !capname) {
812 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
818 if (cap_smb_fname == NULL) {
819 TALLOC_FREE(cappath);
820 TALLOC_FREE(capname);
824 ret = SMB_VFS_NEXT_GETXATTR(handle, cap_smb_fname,
825 capname, value, size);
829 TALLOC_FREE(cappath);
830 TALLOC_FREE(capname);
831 TALLOC_FREE(cap_smb_fname);
838 static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
840 char *cappath = capencode(talloc_tos(), path);
846 return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
849 static ssize_t cap_listxattr(vfs_handle_struct *handle,
850 const struct smb_filename *smb_fname,
854 struct smb_filename *cap_smb_fname = NULL;
855 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
863 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
869 if (cap_smb_fname == NULL) {
870 TALLOC_FREE(cappath);
874 ret = SMB_VFS_NEXT_LISTXATTR(handle, cap_smb_fname, list, size);
878 TALLOC_FREE(cappath);
879 TALLOC_FREE(cap_smb_fname);
886 static int cap_removexattr(vfs_handle_struct *handle,
887 const struct smb_filename *smb_fname,
890 struct smb_filename *cap_smb_fname = NULL;
891 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
892 char *capname = capencode(talloc_tos(), name);
896 if (!cappath || !capname) {
900 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
906 if (cap_smb_fname == NULL) {
907 TALLOC_FREE(cappath);
908 TALLOC_FREE(capname);
912 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, cap_smb_fname, capname);
916 TALLOC_FREE(cappath);
917 TALLOC_FREE(capname);
918 TALLOC_FREE(cap_smb_fname);
925 static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
927 char *cappath = capencode(talloc_tos(), path);
933 return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
936 static int cap_setxattr(vfs_handle_struct *handle,
937 const struct smb_filename *smb_fname,
943 struct smb_filename *cap_smb_fname = NULL;
944 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
945 char *capname = capencode(talloc_tos(), name);
949 if (!cappath || !capname) {
953 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
959 if (cap_smb_fname == NULL) {
960 TALLOC_FREE(cappath);
961 TALLOC_FREE(capname);
965 ret = SMB_VFS_NEXT_SETXATTR(handle, cap_smb_fname,
966 capname, value, size, flags);
970 TALLOC_FREE(cappath);
971 TALLOC_FREE(capname);
972 TALLOC_FREE(cap_smb_fname);
979 static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
981 char *cappath = capencode(talloc_tos(), path);
987 return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
990 static NTSTATUS cap_create_dfs_pathat(vfs_handle_struct *handle,
991 files_struct *dirfsp,
992 const struct smb_filename *smb_fname,
993 const struct referral *reflist,
994 size_t referral_count)
996 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
997 struct smb_filename *cap_smb_fname = NULL;
1000 if (cappath == NULL) {
1001 return NT_STATUS_NO_MEMORY;
1003 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
1009 if (cap_smb_fname == NULL) {
1010 TALLOC_FREE(cappath);
1011 return NT_STATUS_NO_MEMORY;
1013 status = SMB_VFS_NEXT_CREATE_DFS_PATHAT(handle,
1018 TALLOC_FREE(cappath);
1019 TALLOC_FREE(cap_smb_fname);
1023 static NTSTATUS cap_read_dfs_pathat(struct vfs_handle_struct *handle,
1024 TALLOC_CTX *mem_ctx,
1025 struct files_struct *dirfsp,
1026 const struct smb_filename *smb_fname,
1027 struct referral **ppreflist,
1028 size_t *preferral_count)
1030 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
1031 struct smb_filename *cap_smb_fname = NULL;
1034 if (cappath == NULL) {
1035 return NT_STATUS_NO_MEMORY;
1037 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
1043 if (cap_smb_fname == NULL) {
1044 TALLOC_FREE(cappath);
1045 return NT_STATUS_NO_MEMORY;
1048 status = SMB_VFS_NEXT_READ_DFS_PATHAT(handle,
1054 TALLOC_FREE(cappath);
1055 TALLOC_FREE(cap_smb_fname);
1059 static struct vfs_fn_pointers vfs_cap_fns = {
1060 .disk_free_fn = cap_disk_free,
1061 .get_quota_fn = cap_get_quota,
1062 .readdir_fn = cap_readdir,
1063 .mkdirat_fn = cap_mkdirat,
1064 .open_fn = cap_open,
1065 .renameat_fn = cap_renameat,
1066 .stat_fn = cap_stat,
1067 .lstat_fn = cap_lstat,
1068 .unlinkat_fn = cap_unlinkat,
1069 .chmod_fn = cap_chmod,
1070 .lchown_fn = cap_lchown,
1071 .chdir_fn = cap_chdir,
1072 .ntimes_fn = cap_ntimes,
1073 .symlinkat_fn = cap_symlinkat,
1074 .readlinkat_fn = cap_readlinkat,
1075 .linkat_fn = cap_linkat,
1076 .mknodat_fn = cap_mknodat,
1077 .realpath_fn = cap_realpath,
1078 .sys_acl_get_file_fn = cap_sys_acl_get_file,
1079 .sys_acl_set_file_fn = cap_sys_acl_set_file,
1080 .sys_acl_delete_def_file_fn = cap_sys_acl_delete_def_file,
1081 .getxattr_fn = cap_getxattr,
1082 .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
1083 .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
1084 .fgetxattr_fn = cap_fgetxattr,
1085 .listxattr_fn = cap_listxattr,
1086 .removexattr_fn = cap_removexattr,
1087 .fremovexattr_fn = cap_fremovexattr,
1088 .setxattr_fn = cap_setxattr,
1089 .fsetxattr_fn = cap_fsetxattr,
1090 .create_dfs_pathat_fn = cap_create_dfs_pathat,
1091 .read_dfs_pathat_fn = cap_read_dfs_pathat
1095 NTSTATUS vfs_cap_init(TALLOC_CTX *ctx)
1097 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
1101 /* For CAP functions */
1103 #define hex2bin(c) hex2bin_table[(unsigned char)(c)]
1104 #define bin2hex(c) bin2hex_table[(unsigned char)(c)]
1105 #define is_hex(s) ((s)[0] == hex_tag)
1107 static unsigned char hex2bin_table[256] = {
1108 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
1109 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
1110 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
1111 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
1112 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
1113 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1114 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
1115 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
1116 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1117 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
1118 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
1119 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
1120 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
1121 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
1122 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
1123 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
1124 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
1125 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 */
1127 static unsigned char bin2hex_table[256] = "0123456789abcdef";
1129 /*******************************************************************
1130 original code -> ":xx" - CAP format
1131 ********************************************************************/
1133 static char *capencode(TALLOC_CTX *ctx, const char *from)
1140 for (p1 = from; *p1; p1++) {
1141 if ((unsigned char)*p1 >= 0x80) {
1149 to = talloc_array(ctx, char, len);
1154 for (out = to; *from;) {
1155 /* buffer husoku error */
1156 if ((unsigned char)*from >= 0x80) {
1158 *out++ = bin2hex (((*from)>>4)&0x0f);
1159 *out++ = bin2hex ((*from)&0x0f);
1169 /*******************************************************************
1170 CAP -> original code
1171 ********************************************************************/
1172 /* ":xx" -> a byte */
1174 static char *capdecode(TALLOC_CTX *ctx, const char *from)
1181 for (p1 = from; *p1; len++) {
1190 to = talloc_array(ctx, char, len);
1195 for (out = to; *from;) {
1197 *out++ = (hex2bin(from[1])<<4) | (hex2bin(from[2]));