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_mkdir(vfs_handle_struct *handle,
143 const struct smb_filename *smb_fname,
146 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
147 struct smb_filename *cap_smb_fname = NULL;
154 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
159 if (cap_smb_fname == NULL) {
160 TALLOC_FREE(cappath);
165 return SMB_VFS_NEXT_MKDIR(handle, cap_smb_fname, mode);
168 static int cap_rmdir(vfs_handle_struct *handle,
169 const struct smb_filename *smb_fname)
171 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
172 struct smb_filename *cap_smb_fname = NULL;
179 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
184 if (cap_smb_fname == NULL) {
185 TALLOC_FREE(cappath);
190 return SMB_VFS_NEXT_RMDIR(handle, cap_smb_fname);
193 static int cap_open(vfs_handle_struct *handle, struct smb_filename *smb_fname,
194 files_struct *fsp, int flags, mode_t mode)
197 char *tmp_base_name = NULL;
200 cappath = capencode(talloc_tos(), smb_fname->base_name);
207 tmp_base_name = smb_fname->base_name;
208 smb_fname->base_name = cappath;
210 DEBUG(3,("cap: cap_open for %s\n", smb_fname_str_dbg(smb_fname)));
211 ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
213 smb_fname->base_name = tmp_base_name;
214 TALLOC_FREE(cappath);
219 static int cap_renameat(vfs_handle_struct *handle,
220 files_struct *srcfsp,
221 const struct smb_filename *smb_fname_src,
222 files_struct *dstfsp,
223 const struct smb_filename *smb_fname_dst)
227 struct smb_filename *smb_fname_src_tmp = NULL;
228 struct smb_filename *smb_fname_dst_tmp = NULL;
231 capold = capencode(talloc_tos(), smb_fname_src->base_name);
232 capnew = capencode(talloc_tos(), smb_fname_dst->base_name);
233 if (!capold || !capnew) {
238 /* Setup temporary smb_filename structs. */
239 smb_fname_src_tmp = cp_smb_filename(talloc_tos(), smb_fname_src);
240 if (smb_fname_src_tmp == NULL) {
244 smb_fname_dst_tmp = cp_smb_filename(talloc_tos(), smb_fname_dst);
245 if (smb_fname_dst_tmp == NULL) {
250 smb_fname_src_tmp->base_name = capold;
251 smb_fname_dst_tmp->base_name = capnew;
253 ret = SMB_VFS_NEXT_RENAMEAT(handle,
262 TALLOC_FREE(smb_fname_src_tmp);
263 TALLOC_FREE(smb_fname_dst_tmp);
268 static int cap_stat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
271 char *tmp_base_name = NULL;
274 cappath = capencode(talloc_tos(), smb_fname->base_name);
281 tmp_base_name = smb_fname->base_name;
282 smb_fname->base_name = cappath;
284 ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
286 smb_fname->base_name = tmp_base_name;
287 TALLOC_FREE(cappath);
292 static int cap_lstat(vfs_handle_struct *handle, struct smb_filename *smb_fname)
295 char *tmp_base_name = NULL;
298 cappath = capencode(talloc_tos(), smb_fname->base_name);
305 tmp_base_name = smb_fname->base_name;
306 smb_fname->base_name = cappath;
308 ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
310 smb_fname->base_name = tmp_base_name;
311 TALLOC_FREE(cappath);
316 static int cap_unlink(vfs_handle_struct *handle,
317 const struct smb_filename *smb_fname)
319 struct smb_filename *smb_fname_tmp = NULL;
320 char *cappath = NULL;
323 cappath = capencode(talloc_tos(), smb_fname->base_name);
329 /* Setup temporary smb_filename structs. */
330 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
331 if (smb_fname_tmp == NULL) {
336 smb_fname_tmp->base_name = cappath;
338 ret = SMB_VFS_NEXT_UNLINK(handle, smb_fname_tmp);
340 TALLOC_FREE(smb_fname_tmp);
344 static int cap_chmod(vfs_handle_struct *handle,
345 const struct smb_filename *smb_fname,
348 struct smb_filename *cap_smb_fname = NULL;
349 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
358 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
363 if (cap_smb_fname == NULL) {
364 TALLOC_FREE(cappath);
369 ret = SMB_VFS_NEXT_CHMOD(handle, cap_smb_fname, mode);
371 TALLOC_FREE(cappath);
372 TALLOC_FREE(cap_smb_fname);
377 static int cap_chown(vfs_handle_struct *handle,
378 const struct smb_filename *smb_fname,
382 struct smb_filename *cap_smb_fname = NULL;
383 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
392 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
397 if (cap_smb_fname == NULL) {
398 TALLOC_FREE(cappath);
403 ret = SMB_VFS_NEXT_CHOWN(handle, cap_smb_fname, uid, gid);
405 TALLOC_FREE(cappath);
406 TALLOC_FREE(cap_smb_fname);
411 static int cap_lchown(vfs_handle_struct *handle,
412 const struct smb_filename *smb_fname,
416 struct smb_filename *cap_smb_fname = NULL;
417 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
426 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
431 if (cap_smb_fname == NULL) {
432 TALLOC_FREE(cappath);
437 ret = SMB_VFS_NEXT_LCHOWN(handle, cap_smb_fname, uid, gid);
439 TALLOC_FREE(cappath);
440 TALLOC_FREE(cap_smb_fname);
445 static int cap_chdir(vfs_handle_struct *handle,
446 const struct smb_filename *smb_fname)
448 struct smb_filename *cap_smb_fname = NULL;
449 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
457 DEBUG(3,("cap: cap_chdir for %s\n", smb_fname->base_name));
459 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
464 if (cap_smb_fname == NULL) {
465 TALLOC_FREE(cappath);
469 ret = SMB_VFS_NEXT_CHDIR(handle, cap_smb_fname);
473 TALLOC_FREE(cappath);
474 TALLOC_FREE(cap_smb_fname);
475 if (saved_errno != 0) {
481 static int cap_ntimes(vfs_handle_struct *handle,
482 const struct smb_filename *smb_fname,
483 struct smb_file_time *ft)
485 struct smb_filename *smb_fname_tmp = NULL;
486 char *cappath = NULL;
489 cappath = capencode(talloc_tos(), smb_fname->base_name);
496 /* Setup temporary smb_filename structs. */
497 smb_fname_tmp = cp_smb_filename(talloc_tos(), smb_fname);
498 if (smb_fname_tmp == NULL) {
503 smb_fname_tmp->base_name = cappath;
505 ret = SMB_VFS_NEXT_NTIMES(handle, smb_fname_tmp, ft);
507 TALLOC_FREE(smb_fname_tmp);
512 static int cap_symlink(vfs_handle_struct *handle,
513 const char *link_contents,
514 const struct smb_filename *new_smb_fname)
516 char *capold = capencode(talloc_tos(), link_contents);
517 char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
518 struct smb_filename *new_cap_smb_fname = NULL;
522 if (!capold || !capnew) {
526 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
530 new_smb_fname->flags);
531 if (new_cap_smb_fname == NULL) {
537 ret = SMB_VFS_NEXT_SYMLINK(handle,
545 TALLOC_FREE(new_cap_smb_fname);
546 if (saved_errno != 0) {
552 static int cap_readlink(vfs_handle_struct *handle,
553 const struct smb_filename *smb_fname,
557 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
558 struct smb_filename *cap_smb_fname = NULL;
566 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
571 if (cap_smb_fname == NULL) {
572 TALLOC_FREE(cappath);
576 ret = SMB_VFS_NEXT_READLINK(handle, cap_smb_fname, buf, bufsiz);
580 TALLOC_FREE(cappath);
581 TALLOC_FREE(cap_smb_fname);
582 if (saved_errno != 0) {
588 static int cap_linkat(vfs_handle_struct *handle,
589 files_struct *srcfsp,
590 const struct smb_filename *old_smb_fname,
591 files_struct *dstfsp,
592 const struct smb_filename *new_smb_fname,
595 char *capold = capencode(talloc_tos(), old_smb_fname->base_name);
596 char *capnew = capencode(talloc_tos(), new_smb_fname->base_name);
597 struct smb_filename *old_cap_smb_fname = NULL;
598 struct smb_filename *new_cap_smb_fname = NULL;
602 if (!capold || !capnew) {
606 old_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
610 old_smb_fname->flags);
611 if (old_cap_smb_fname == NULL) {
617 new_cap_smb_fname = synthetic_smb_fname(talloc_tos(),
621 new_smb_fname->flags);
622 if (new_cap_smb_fname == NULL) {
625 TALLOC_FREE(old_cap_smb_fname);
629 ret = SMB_VFS_NEXT_LINKAT(handle,
640 TALLOC_FREE(old_cap_smb_fname);
641 TALLOC_FREE(new_cap_smb_fname);
642 if (saved_errno != 0) {
648 static int cap_mknod(vfs_handle_struct *handle,
649 const struct smb_filename *smb_fname,
653 struct smb_filename *cap_smb_fname = NULL;
654 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
662 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
667 if (cap_smb_fname == NULL) {
668 TALLOC_FREE(cappath);
672 ret = SMB_VFS_NEXT_MKNOD(handle, cap_smb_fname, mode, dev);
676 TALLOC_FREE(cappath);
677 TALLOC_FREE(cap_smb_fname);
678 if (saved_errno != 0) {
684 static struct smb_filename *cap_realpath(vfs_handle_struct *handle,
686 const struct smb_filename *smb_fname)
688 /* monyo need capencode'ed and capdecode'ed? */
689 struct smb_filename *cap_smb_fname = NULL;
690 struct smb_filename *return_fname = NULL;
691 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
698 cap_smb_fname = synthetic_smb_fname(ctx,
703 if (cap_smb_fname == NULL) {
704 TALLOC_FREE(cappath);
708 return_fname = SMB_VFS_NEXT_REALPATH(handle, ctx, cap_smb_fname);
709 if (return_fname == NULL) {
712 TALLOC_FREE(cappath);
713 TALLOC_FREE(cap_smb_fname);
714 if (saved_errno != 0) {
720 static SMB_ACL_T cap_sys_acl_get_file(vfs_handle_struct *handle,
721 const struct smb_filename *smb_fname,
725 struct smb_filename *cap_smb_fname = NULL;
726 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
732 return (SMB_ACL_T)NULL;
734 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
739 if (cap_smb_fname == NULL) {
740 TALLOC_FREE(cappath);
742 return (SMB_ACL_T)NULL;
744 ret = SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, cap_smb_fname,
749 TALLOC_FREE(cappath);
750 TALLOC_FREE(cap_smb_fname);
751 if (saved_errno != 0) {
757 static int cap_sys_acl_set_file(vfs_handle_struct *handle,
758 const struct smb_filename *smb_fname,
759 SMB_ACL_TYPE_T acltype,
762 struct smb_filename *cap_smb_fname = NULL;
763 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
771 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
776 if (cap_smb_fname == NULL) {
777 TALLOC_FREE(cappath);
781 ret = SMB_VFS_NEXT_SYS_ACL_SET_FILE(handle, cap_smb_fname,
786 TALLOC_FREE(cappath);
787 TALLOC_FREE(cap_smb_fname);
788 if (saved_errno != 0) {
794 static int cap_sys_acl_delete_def_file(vfs_handle_struct *handle,
795 const struct smb_filename *smb_fname)
797 struct smb_filename *cap_smb_fname = NULL;
798 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
806 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
811 if (cap_smb_fname == NULL) {
812 TALLOC_FREE(cappath);
816 ret = SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, cap_smb_fname);
820 TALLOC_FREE(cappath);
821 TALLOC_FREE(cap_smb_fname);
828 static ssize_t cap_getxattr(vfs_handle_struct *handle,
829 const struct smb_filename *smb_fname,
834 struct smb_filename *cap_smb_fname = NULL;
835 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
836 char *capname = capencode(talloc_tos(), name);
840 if (!cappath || !capname) {
844 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
849 if (cap_smb_fname == NULL) {
850 TALLOC_FREE(cappath);
851 TALLOC_FREE(capname);
855 ret = SMB_VFS_NEXT_GETXATTR(handle, cap_smb_fname,
856 capname, value, size);
860 TALLOC_FREE(cappath);
861 TALLOC_FREE(capname);
862 TALLOC_FREE(cap_smb_fname);
869 static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, void *value, size_t size)
871 char *cappath = capencode(talloc_tos(), path);
877 return SMB_VFS_NEXT_FGETXATTR(handle, fsp, cappath, value, size);
880 static ssize_t cap_listxattr(vfs_handle_struct *handle,
881 const struct smb_filename *smb_fname,
885 struct smb_filename *cap_smb_fname = NULL;
886 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
894 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
899 if (cap_smb_fname == NULL) {
900 TALLOC_FREE(cappath);
904 ret = SMB_VFS_NEXT_LISTXATTR(handle, cap_smb_fname, list, size);
908 TALLOC_FREE(cappath);
909 TALLOC_FREE(cap_smb_fname);
916 static int cap_removexattr(vfs_handle_struct *handle,
917 const struct smb_filename *smb_fname,
920 struct smb_filename *cap_smb_fname = NULL;
921 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
922 char *capname = capencode(talloc_tos(), name);
926 if (!cappath || !capname) {
930 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
935 if (cap_smb_fname == NULL) {
936 TALLOC_FREE(cappath);
937 TALLOC_FREE(capname);
941 ret = SMB_VFS_NEXT_REMOVEXATTR(handle, cap_smb_fname, capname);
945 TALLOC_FREE(cappath);
946 TALLOC_FREE(capname);
947 TALLOC_FREE(cap_smb_fname);
954 static int cap_fremovexattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path)
956 char *cappath = capencode(talloc_tos(), path);
962 return SMB_VFS_NEXT_FREMOVEXATTR(handle, fsp, cappath);
965 static int cap_setxattr(vfs_handle_struct *handle,
966 const struct smb_filename *smb_fname,
972 struct smb_filename *cap_smb_fname = NULL;
973 char *cappath = capencode(talloc_tos(), smb_fname->base_name);
974 char *capname = capencode(talloc_tos(), name);
978 if (!cappath || !capname) {
982 cap_smb_fname = synthetic_smb_fname(talloc_tos(),
987 if (cap_smb_fname == NULL) {
988 TALLOC_FREE(cappath);
989 TALLOC_FREE(capname);
993 ret = SMB_VFS_NEXT_SETXATTR(handle, cap_smb_fname,
994 capname, value, size, flags);
998 TALLOC_FREE(cappath);
999 TALLOC_FREE(capname);
1000 TALLOC_FREE(cap_smb_fname);
1002 errno = saved_errno;
1007 static int cap_fsetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *path, const void *value, size_t size, int flags)
1009 char *cappath = capencode(talloc_tos(), path);
1015 return SMB_VFS_NEXT_FSETXATTR(handle, fsp, cappath, value, size, flags);
1018 static struct vfs_fn_pointers vfs_cap_fns = {
1019 .disk_free_fn = cap_disk_free,
1020 .get_quota_fn = cap_get_quota,
1021 .opendir_fn = cap_opendir,
1022 .readdir_fn = cap_readdir,
1023 .mkdir_fn = cap_mkdir,
1024 .rmdir_fn = cap_rmdir,
1025 .open_fn = cap_open,
1026 .renameat_fn = cap_renameat,
1027 .stat_fn = cap_stat,
1028 .lstat_fn = cap_lstat,
1029 .unlink_fn = cap_unlink,
1030 .chmod_fn = cap_chmod,
1031 .chown_fn = cap_chown,
1032 .lchown_fn = cap_lchown,
1033 .chdir_fn = cap_chdir,
1034 .ntimes_fn = cap_ntimes,
1035 .symlink_fn = cap_symlink,
1036 .readlink_fn = cap_readlink,
1037 .linkat_fn = cap_linkat,
1038 .mknod_fn = cap_mknod,
1039 .realpath_fn = cap_realpath,
1040 .sys_acl_get_file_fn = cap_sys_acl_get_file,
1041 .sys_acl_set_file_fn = cap_sys_acl_set_file,
1042 .sys_acl_delete_def_file_fn = cap_sys_acl_delete_def_file,
1043 .getxattr_fn = cap_getxattr,
1044 .getxattrat_send_fn = vfs_not_implemented_getxattrat_send,
1045 .getxattrat_recv_fn = vfs_not_implemented_getxattrat_recv,
1046 .fgetxattr_fn = cap_fgetxattr,
1047 .listxattr_fn = cap_listxattr,
1048 .removexattr_fn = cap_removexattr,
1049 .fremovexattr_fn = cap_fremovexattr,
1050 .setxattr_fn = cap_setxattr,
1051 .fsetxattr_fn = cap_fsetxattr
1055 NTSTATUS vfs_cap_init(TALLOC_CTX *ctx)
1057 return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "cap",
1061 /* For CAP functions */
1063 #define hex2bin(c) hex2bin_table[(unsigned char)(c)]
1064 #define bin2hex(c) bin2hex_table[(unsigned char)(c)]
1065 #define is_hex(s) ((s)[0] == hex_tag)
1067 static unsigned char hex2bin_table[256] = {
1068 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x00 */
1069 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 */
1070 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 */
1071 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 0x30 */
1072 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x40 */
1073 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1074 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 */
1075 0000, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0000, /* 0x60 */
1076 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,
1077 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 */
1078 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 */
1079 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 */
1080 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 */
1081 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 */
1082 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 */
1083 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 */
1084 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 */
1085 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 */
1087 static unsigned char bin2hex_table[256] = "0123456789abcdef";
1089 /*******************************************************************
1090 original code -> ":xx" - CAP format
1091 ********************************************************************/
1093 static char *capencode(TALLOC_CTX *ctx, const char *from)
1100 for (p1 = from; *p1; p1++) {
1101 if ((unsigned char)*p1 >= 0x80) {
1109 to = talloc_array(ctx, char, len);
1114 for (out = to; *from;) {
1115 /* buffer husoku error */
1116 if ((unsigned char)*from >= 0x80) {
1118 *out++ = bin2hex (((*from)>>4)&0x0f);
1119 *out++ = bin2hex ((*from)&0x0f);
1129 /*******************************************************************
1130 CAP -> original code
1131 ********************************************************************/
1132 /* ":xx" -> a byte */
1134 static char *capdecode(TALLOC_CTX *ctx, const char *from)
1141 for (p1 = from; *p1; len++) {
1150 to = talloc_array(ctx, char, len);
1155 for (out = to; *from;) {
1157 *out++ = (hex2bin(from[1])<<4) | (hex2bin(from[2]));