2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1998-2005
6 Copyright (C) Timur Bakeyev 2005
7 Copyright (C) Bjoern Jacke 2006-2007
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #ifdef HAVE_SYS_PRCTL_H
27 #include <sys/prctl.h>
31 The idea is that this file will eventually have wrappers around all
32 important system calls in samba. The aims are:
34 - to enable easier porting by putting OS dependent stuff in here
36 - to allow for hooks into other "pseudo-filesystems"
38 - to allow easier integration of things like the japanese extensions
40 - to support the philosophy of Samba to expose the features of
41 the OS within the SMB model. In general whatever file/printer/variable
42 expansions/etc make sense to the OS should be acceptable to Samba.
47 /*******************************************************************
48 A wrapper for memalign
49 ********************************************************************/
51 void *sys_memalign( size_t align
, size_t size
)
53 #if defined(HAVE_POSIX_MEMALIGN)
55 int ret
= posix_memalign( &p
, align
, size
);
60 #elif defined(HAVE_MEMALIGN)
61 return memalign( align
, size
);
63 /* On *BSD systems memaligns doesn't exist, but memory will
64 * be aligned on allocations of > pagesize. */
65 #if defined(SYSCONF_SC_PAGESIZE)
66 size_t pagesize
= (size_t)sysconf(_SC_PAGESIZE
);
67 #elif defined(HAVE_GETPAGESIZE)
68 size_t pagesize
= (size_t)getpagesize();
70 size_t pagesize
= (size_t)-1;
72 if (pagesize
== (size_t)-1) {
73 DEBUG(0,("memalign functionalaity not available on this platform!\n"));
76 if (size
< pagesize
) {
79 return SMB_MALLOC(size
);
83 /*******************************************************************
84 A wrapper for usleep in case we don't have one.
85 ********************************************************************/
87 int sys_usleep(long usecs
)
94 * We need this braindamage as the glibc usleep
95 * is not SPEC1170 complient... grumble... JRA.
98 if(usecs
< 0 || usecs
> 1000000) {
106 #else /* HAVE_USLEEP */
108 * Fake it with select...
111 tval
.tv_usec
= usecs
/1000;
112 select(0,NULL
,NULL
,NULL
,&tval
);
114 #endif /* HAVE_USLEEP */
117 /*******************************************************************
118 A read wrapper that will deal with EINTR.
119 ********************************************************************/
121 ssize_t
sys_read(int fd
, void *buf
, size_t count
)
126 ret
= read(fd
, buf
, count
);
127 } while (ret
== -1 && errno
== EINTR
);
131 /*******************************************************************
132 A write wrapper that will deal with EINTR.
133 ********************************************************************/
135 ssize_t
sys_write(int fd
, const void *buf
, size_t count
)
140 ret
= write(fd
, buf
, count
);
141 } while (ret
== -1 && errno
== EINTR
);
145 /*******************************************************************
146 A pread wrapper that will deal with EINTR and 64-bit file offsets.
147 ********************************************************************/
149 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
150 ssize_t
sys_pread(int fd
, void *buf
, size_t count
, SMB_OFF_T off
)
155 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
156 ret
= pread64(fd
, buf
, count
, off
);
158 ret
= pread(fd
, buf
, count
, off
);
160 } while (ret
== -1 && errno
== EINTR
);
165 /*******************************************************************
166 A write wrapper that will deal with EINTR and 64-bit file offsets.
167 ********************************************************************/
169 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
170 ssize_t
sys_pwrite(int fd
, const void *buf
, size_t count
, SMB_OFF_T off
)
175 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
176 ret
= pwrite64(fd
, buf
, count
, off
);
178 ret
= pwrite(fd
, buf
, count
, off
);
180 } while (ret
== -1 && errno
== EINTR
);
185 /*******************************************************************
186 A send wrapper that will deal with EINTR.
187 ********************************************************************/
189 ssize_t
sys_send(int s
, const void *msg
, size_t len
, int flags
)
194 ret
= send(s
, msg
, len
, flags
);
195 } while (ret
== -1 && errno
== EINTR
);
199 /*******************************************************************
200 A sendto wrapper that will deal with EINTR.
201 ********************************************************************/
203 ssize_t
sys_sendto(int s
, const void *msg
, size_t len
, int flags
, const struct sockaddr
*to
, socklen_t tolen
)
208 ret
= sendto(s
, msg
, len
, flags
, to
, tolen
);
209 } while (ret
== -1 && errno
== EINTR
);
213 /*******************************************************************
214 A recv wrapper that will deal with EINTR.
215 ********************************************************************/
217 ssize_t
sys_recv(int fd
, void *buf
, size_t count
, int flags
)
222 ret
= recv(fd
, buf
, count
, flags
);
223 } while (ret
== -1 && errno
== EINTR
);
227 /*******************************************************************
228 A recvfrom wrapper that will deal with EINTR.
229 ********************************************************************/
231 ssize_t
sys_recvfrom(int s
, void *buf
, size_t len
, int flags
, struct sockaddr
*from
, socklen_t
*fromlen
)
236 ret
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
);
237 } while (ret
== -1 && errno
== EINTR
);
241 /*******************************************************************
242 A fcntl wrapper that will deal with EINTR.
243 ********************************************************************/
245 int sys_fcntl_ptr(int fd
, int cmd
, void *arg
)
250 ret
= fcntl(fd
, cmd
, arg
);
251 } while (ret
== -1 && errno
== EINTR
);
255 /*******************************************************************
256 A fcntl wrapper that will deal with EINTR.
257 ********************************************************************/
259 int sys_fcntl_long(int fd
, int cmd
, long arg
)
264 ret
= fcntl(fd
, cmd
, arg
);
265 } while (ret
== -1 && errno
== EINTR
);
269 /*******************************************************************
270 A stat() wrapper that will deal with 64 bit filesizes.
271 ********************************************************************/
273 int sys_stat(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
276 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
277 ret
= stat64(fname
, sbuf
);
279 ret
= stat(fname
, sbuf
);
281 /* we always want directories to appear zero size */
282 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
286 /*******************************************************************
287 An fstat() wrapper that will deal with 64 bit filesizes.
288 ********************************************************************/
290 int sys_fstat(int fd
,SMB_STRUCT_STAT
*sbuf
)
293 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
294 ret
= fstat64(fd
, sbuf
);
296 ret
= fstat(fd
, sbuf
);
298 /* we always want directories to appear zero size */
299 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
303 /*******************************************************************
304 An lstat() wrapper that will deal with 64 bit filesizes.
305 ********************************************************************/
307 int sys_lstat(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
310 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
311 ret
= lstat64(fname
, sbuf
);
313 ret
= lstat(fname
, sbuf
);
315 /* we always want directories to appear zero size */
316 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
320 /*******************************************************************
321 An ftruncate() wrapper that will deal with 64 bit filesizes.
322 ********************************************************************/
324 int sys_ftruncate(int fd
, SMB_OFF_T offset
)
326 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
327 return ftruncate64(fd
, offset
);
329 return ftruncate(fd
, offset
);
333 /*******************************************************************
334 An lseek() wrapper that will deal with 64 bit filesizes.
335 ********************************************************************/
337 SMB_OFF_T
sys_lseek(int fd
, SMB_OFF_T offset
, int whence
)
339 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
340 return lseek64(fd
, offset
, whence
);
342 return lseek(fd
, offset
, whence
);
346 /*******************************************************************
347 An fseek() wrapper that will deal with 64 bit filesizes.
348 ********************************************************************/
350 int sys_fseek(FILE *fp
, SMB_OFF_T offset
, int whence
)
352 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
353 return fseek64(fp
, offset
, whence
);
354 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
355 return fseeko64(fp
, offset
, whence
);
357 return fseek(fp
, offset
, whence
);
361 /*******************************************************************
362 An ftell() wrapper that will deal with 64 bit filesizes.
363 ********************************************************************/
365 SMB_OFF_T
sys_ftell(FILE *fp
)
367 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
368 return (SMB_OFF_T
)ftell64(fp
);
369 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
370 return (SMB_OFF_T
)ftello64(fp
);
372 return (SMB_OFF_T
)ftell(fp
);
376 /*******************************************************************
377 A creat() wrapper that will deal with 64 bit filesizes.
378 ********************************************************************/
380 int sys_creat(const char *path
, mode_t mode
)
382 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
383 return creat64(path
, mode
);
386 * If creat64 isn't defined then ensure we call a potential open64.
389 return sys_open(path
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
393 /*******************************************************************
394 An open() wrapper that will deal with 64 bit filesizes.
395 ********************************************************************/
397 int sys_open(const char *path
, int oflag
, mode_t mode
)
399 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
400 return open64(path
, oflag
, mode
);
402 return open(path
, oflag
, mode
);
406 /*******************************************************************
407 An fopen() wrapper that will deal with 64 bit filesizes.
408 ********************************************************************/
410 FILE *sys_fopen(const char *path
, const char *type
)
412 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
413 return fopen64(path
, type
);
415 return fopen(path
, type
);
420 /*******************************************************************
421 A flock() wrapper that will perform the kernel flock.
422 ********************************************************************/
424 void kernel_flock(int fd
, uint32 share_mode
)
426 #if HAVE_KERNEL_SHARE_MODES
428 if (share_mode
== FILE_SHARE_WRITE
) {
429 kernel_mode
= LOCK_MAND
|LOCK_WRITE
;
430 } else if (share_mode
== FILE_SHARE_READ
) {
431 kernel_mode
= LOCK_MAND
|LOCK_READ
;
432 } else if (share_mode
== FILE_SHARE_NONE
) {
433 kernel_mode
= LOCK_MAND
;
436 flock(fd
, kernel_mode
);
444 /*******************************************************************
445 An opendir wrapper that will deal with 64 bit filesizes.
446 ********************************************************************/
448 SMB_STRUCT_DIR
*sys_opendir(const char *name
)
450 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
451 return opendir64(name
);
453 return opendir(name
);
457 /*******************************************************************
458 A readdir wrapper that will deal with 64 bit filesizes.
459 ********************************************************************/
461 SMB_STRUCT_DIRENT
*sys_readdir(SMB_STRUCT_DIR
*dirp
)
463 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
464 return readdir64(dirp
);
466 return readdir(dirp
);
470 /*******************************************************************
471 A seekdir wrapper that will deal with 64 bit filesizes.
472 ********************************************************************/
474 void sys_seekdir(SMB_STRUCT_DIR
*dirp
, long offset
)
476 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
477 seekdir64(dirp
, offset
);
479 seekdir(dirp
, offset
);
483 /*******************************************************************
484 A telldir wrapper that will deal with 64 bit filesizes.
485 ********************************************************************/
487 long sys_telldir(SMB_STRUCT_DIR
*dirp
)
489 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
490 return (long)telldir64(dirp
);
492 return (long)telldir(dirp
);
496 /*******************************************************************
497 A rewinddir wrapper that will deal with 64 bit filesizes.
498 ********************************************************************/
500 void sys_rewinddir(SMB_STRUCT_DIR
*dirp
)
502 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
509 /*******************************************************************
510 A close wrapper that will deal with 64 bit filesizes.
511 ********************************************************************/
513 int sys_closedir(SMB_STRUCT_DIR
*dirp
)
515 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
516 return closedir64(dirp
);
518 return closedir(dirp
);
522 /*******************************************************************
523 An mknod() wrapper that will deal with 64 bit filesizes.
524 ********************************************************************/
526 int sys_mknod(const char *path
, mode_t mode
, SMB_DEV_T dev
)
528 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
529 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
530 return mknod64(path
, mode
, dev
);
532 return mknod(path
, mode
, dev
);
535 /* No mknod system call. */
541 /*******************************************************************
542 Wrapper for realpath.
543 ********************************************************************/
545 char *sys_realpath(const char *path
, char *resolved_path
)
547 #if defined(HAVE_REALPATH)
548 return realpath(path
, resolved_path
);
550 /* As realpath is not a system call we can't return ENOSYS. */
556 /*******************************************************************
557 The wait() calls vary between systems
558 ********************************************************************/
560 int sys_waitpid(pid_t pid
,int *status
,int options
)
563 return waitpid(pid
,status
,options
);
564 #else /* HAVE_WAITPID */
565 return wait4(pid
, status
, options
, NULL
);
566 #endif /* HAVE_WAITPID */
569 /*******************************************************************
570 System wrapper for getwd
571 ********************************************************************/
573 char *sys_getwd(char *s
)
577 wd
= (char *)getcwd(s
, sizeof (pstring
));
579 wd
= (char *)getwd(s
);
584 /*******************************************************************
585 system wrapper for symlink
586 ********************************************************************/
588 int sys_symlink(const char *oldpath
, const char *newpath
)
594 return symlink(oldpath
, newpath
);
598 /*******************************************************************
599 system wrapper for readlink
600 ********************************************************************/
602 int sys_readlink(const char *path
, char *buf
, size_t bufsiz
)
604 #ifndef HAVE_READLINK
608 return readlink(path
, buf
, bufsiz
);
612 /*******************************************************************
613 system wrapper for link
614 ********************************************************************/
616 int sys_link(const char *oldpath
, const char *newpath
)
622 return link(oldpath
, newpath
);
626 /*******************************************************************
627 chown isn't used much but OS/2 doesn't have it
628 ********************************************************************/
630 int sys_chown(const char *fname
,uid_t uid
,gid_t gid
)
635 DEBUG(1,("WARNING: no chown!\n"));
641 return(chown(fname
,uid
,gid
));
645 /*******************************************************************
646 os/2 also doesn't have chroot
647 ********************************************************************/
648 int sys_chroot(const char *dname
)
653 DEBUG(1,("WARNING: no chroot!\n"));
659 return(chroot(dname
));
663 /**************************************************************************
664 A wrapper for gethostbyname() that tries avoids looking up hostnames
665 in the root domain, which can cause dial-on-demand links to come up for no
667 ****************************************************************************/
669 struct hostent
*sys_gethostbyname(const char *name
)
671 #ifdef REDUCE_ROOT_DNS_LOOKUPS
672 char query
[256], hostname
[256];
675 /* Does this name have any dots in it? If so, make no change */
677 if (strchr_m(name
, '.'))
678 return(gethostbyname(name
));
680 /* Get my hostname, which should have domain name
681 attached. If not, just do the gethostname on the
685 gethostname(hostname
, sizeof(hostname
) - 1);
686 hostname
[sizeof(hostname
) - 1] = 0;
687 if ((domain
= strchr_m(hostname
, '.')) == NULL
)
688 return(gethostbyname(name
));
690 /* Attach domain name to query and do modified query.
691 If names too large, just do gethostname on the
695 if((strlen(name
) + strlen(domain
)) >= sizeof(query
))
696 return(gethostbyname(name
));
698 slprintf(query
, sizeof(query
)-1, "%s%s", name
, domain
);
699 return(gethostbyname(query
));
700 #else /* REDUCE_ROOT_DNS_LOOKUPS */
701 return(gethostbyname(name
));
702 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
706 #if defined(HAVE_POSIX_CAPABILITIES)
708 #ifdef HAVE_SYS_CAPABILITY_H
710 #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
711 #define _I386_STATFS_H
712 #define _PPC_STATFS_H
713 #define BROKEN_REDHAT_7_STATFS_WORKAROUND
716 #include <sys/capability.h>
718 #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
719 #undef _I386_STATFS_H
721 #undef BROKEN_REDHAT_7_STATFS_WORKAROUND
724 #endif /* HAVE_SYS_CAPABILITY_H */
726 /**************************************************************************
727 Try and abstract process capabilities (for systems that have them).
728 ****************************************************************************/
730 /* Set the POSIX capabilities needed for the given purpose into the effective
731 * capability set of the current process. Make sure they are always removed
732 * from the inheritable set, because there is no circumstance in which our
733 * children should inherit our elevated privileges.
735 static BOOL
set_process_capability(enum smbd_capability capability
,
738 cap_value_t cap_vals
[2] = {0};
739 int num_cap_vals
= 0;
743 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
744 /* On Linux, make sure that any capabilities we grab are sticky
745 * across UID changes. We expect that this would allow us to keep both
746 * the effective and permitted capability sets, but as of circa 2.6.16,
747 * only the permitted set is kept. It is a bug (which we work around)
748 * that the effective set is lost, but we still require the effective
751 if (!prctl(PR_GET_KEEPCAPS
)) {
752 prctl(PR_SET_KEEPCAPS
, 1);
756 cap
= cap_get_proc();
758 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
763 switch (capability
) {
764 case KERNEL_OPLOCK_CAPABILITY
:
765 #ifdef CAP_NETWORK_MGT
766 /* IRIX has CAP_NETWORK_MGT for oplocks. */
767 cap_vals
[num_cap_vals
++] = CAP_NETWORK_MGT
;
770 case DMAPI_ACCESS_CAPABILITY
:
771 #ifdef CAP_DEVICE_MGT
772 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
773 cap_vals
[num_cap_vals
++] = CAP_DEVICE_MGT
;
775 /* Linux has CAP_MKNOD for DMAPI access. */
776 cap_vals
[num_cap_vals
++] = CAP_MKNOD
;
779 case LEASE_CAPABILITY
:
781 cap_vals
[num_cap_vals
++] = CAP_LEASE
;
786 SMB_ASSERT(num_cap_vals
<= ARRAY_SIZE(cap_vals
));
788 if (num_cap_vals
== 0) {
793 cap_set_flag(cap
, CAP_EFFECTIVE
, num_cap_vals
, cap_vals
,
794 enable
? CAP_SET
: CAP_CLEAR
);
796 /* We never want to pass capabilities down to our children, so make
797 * sure they are not inherited.
799 cap_set_flag(cap
, CAP_INHERITABLE
, num_cap_vals
, cap_vals
, CAP_CLEAR
);
801 if (cap_set_proc(cap
) == -1) {
802 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
812 #endif /* HAVE_POSIX_CAPABILITIES */
814 /****************************************************************************
815 Gain the oplock capability from the kernel if possible.
816 ****************************************************************************/
818 void set_effective_capability(enum smbd_capability capability
)
820 #if defined(HAVE_POSIX_CAPABILITIES)
821 set_process_capability(capability
, True
);
822 #endif /* HAVE_POSIX_CAPABILITIES */
825 void drop_effective_capability(enum smbd_capability capability
)
827 #if defined(HAVE_POSIX_CAPABILITIES)
828 set_process_capability(capability
, False
);
829 #endif /* HAVE_POSIX_CAPABILITIES */
832 /**************************************************************************
833 Wrapper for random().
834 ****************************************************************************/
836 long sys_random(void)
838 #if defined(HAVE_RANDOM)
839 return (long)random();
840 #elif defined(HAVE_RAND)
843 DEBUG(0,("Error - no random function available !\n"));
848 /**************************************************************************
849 Wrapper for srandom().
850 ****************************************************************************/
852 void sys_srandom(unsigned int seed
)
854 #if defined(HAVE_SRANDOM)
856 #elif defined(HAVE_SRAND)
859 DEBUG(0,("Error - no srandom function available !\n"));
864 /**************************************************************************
865 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
866 ****************************************************************************/
870 #if defined(SYSCONF_SC_NGROUPS_MAX)
871 int ret
= sysconf(_SC_NGROUPS_MAX
);
872 return (ret
== -1) ? NGROUPS_MAX
: ret
;
878 /**************************************************************************
879 Wrapper for getgroups. Deals with broken (int) case.
880 ****************************************************************************/
882 int sys_getgroups(int setlen
, gid_t
*gidset
)
884 #if !defined(HAVE_BROKEN_GETGROUPS)
885 return getgroups(setlen
, gidset
);
893 return getgroups(setlen
, &gid
);
897 * Broken case. We need to allocate a
898 * GID_T array of size setlen.
907 setlen
= groups_max();
909 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
910 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
914 if((ngroups
= getgroups(setlen
, group_list
)) < 0) {
915 int saved_errno
= errno
;
916 SAFE_FREE(group_list
);
921 for(i
= 0; i
< ngroups
; i
++)
922 gidset
[i
] = (gid_t
)group_list
[i
];
924 SAFE_FREE(group_list
);
926 #endif /* HAVE_BROKEN_GETGROUPS */
930 /**************************************************************************
931 Wrapper for setgroups. Deals with broken (int) case. Automatically used
932 if we have broken getgroups.
933 ****************************************************************************/
935 int sys_setgroups(int setlen
, gid_t
*gidset
)
937 #if !defined(HAVE_SETGROUPS)
940 #endif /* HAVE_SETGROUPS */
942 #if !defined(HAVE_BROKEN_GETGROUPS)
943 return setgroups(setlen
, gidset
);
952 if (setlen
< 0 || setlen
> groups_max()) {
958 * Broken case. We need to allocate a
959 * GID_T array of size setlen.
962 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
963 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
967 for(i
= 0; i
< setlen
; i
++)
968 group_list
[i
] = (GID_T
) gidset
[i
];
970 if(setgroups(setlen
, group_list
) != 0) {
971 int saved_errno
= errno
;
972 SAFE_FREE(group_list
);
977 SAFE_FREE(group_list
);
979 #endif /* HAVE_BROKEN_GETGROUPS */
982 /**************************************************************************
983 Wrappers for setpwent(), getpwent() and endpwent()
984 ****************************************************************************/
986 void sys_setpwent(void)
991 struct passwd
*sys_getpwent(void)
996 void sys_endpwent(void)
1001 /**************************************************************************
1002 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
1003 ****************************************************************************/
1005 #ifdef ENABLE_BUILD_FARM_HACKS
1008 * In the build farm we want to be able to join machines to the domain. As we
1009 * don't have root access, we need to bypass direct access to /etc/passwd
1010 * after a user has been created via samr. Fake those users.
1013 static struct passwd
*fake_pwd
;
1014 static int num_fake_pwd
;
1016 struct passwd
*sys_getpwnam(const char *name
)
1020 for (i
=0; i
<num_fake_pwd
; i
++) {
1021 if (strcmp(fake_pwd
[i
].pw_name
, name
) == 0) {
1022 DEBUG(10, ("Returning fake user %s\n", name
));
1023 return &fake_pwd
[i
];
1027 return getpwnam(name
);
1030 struct passwd
*sys_getpwuid(uid_t uid
)
1034 for (i
=0; i
<num_fake_pwd
; i
++) {
1035 if (fake_pwd
[i
].pw_uid
== uid
) {
1036 DEBUG(10, ("Returning fake user %s\n",
1037 fake_pwd
[i
].pw_name
));
1038 return &fake_pwd
[i
];
1042 return getpwuid(uid
);
1045 void faked_create_user(const char *name
)
1049 struct passwd new_pwd
;
1051 for (i
=0; i
<10; i
++) {
1052 generate_random_buffer((unsigned char *)&uid
,
1054 if (getpwuid(uid
) == NULL
) {
1060 /* Weird. No free uid found... */
1064 new_pwd
.pw_name
= SMB_STRDUP(name
);
1065 new_pwd
.pw_passwd
= SMB_STRDUP("x");
1066 new_pwd
.pw_uid
= uid
;
1067 new_pwd
.pw_gid
= 100;
1068 new_pwd
.pw_gecos
= SMB_STRDUP("faked user");
1069 new_pwd
.pw_dir
= SMB_STRDUP("/nodir");
1070 new_pwd
.pw_shell
= SMB_STRDUP("/bin/false");
1072 ADD_TO_ARRAY(NULL
, struct passwd
, new_pwd
, &fake_pwd
,
1075 DEBUG(10, ("Added fake user %s, have %d fake users\n",
1076 name
, num_fake_pwd
));
1081 struct passwd
*sys_getpwnam(const char *name
)
1083 return getpwnam(name
);
1086 struct passwd
*sys_getpwuid(uid_t uid
)
1088 return getpwuid(uid
);
1093 struct group
*sys_getgrnam(const char *name
)
1095 return getgrnam(name
);
1098 struct group
*sys_getgrgid(gid_t gid
)
1100 return getgrgid(gid
);
1103 #if 0 /* NOT CURRENTLY USED - JRA */
1104 /**************************************************************************
1105 The following are the UNICODE versions of *all* system interface functions
1106 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
1107 which currently are left as ascii as they are not used other than in name
1109 ****************************************************************************/
1111 /**************************************************************************
1112 Wide stat. Just narrow and call sys_xxx.
1113 ****************************************************************************/
1115 int wsys_stat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
1118 return sys_stat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
1121 /**************************************************************************
1122 Wide lstat. Just narrow and call sys_xxx.
1123 ****************************************************************************/
1125 int wsys_lstat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
1128 return sys_lstat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
1131 /**************************************************************************
1132 Wide creat. Just narrow and call sys_xxx.
1133 ****************************************************************************/
1135 int wsys_creat(const smb_ucs2_t
*wfname
, mode_t mode
)
1138 return sys_creat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), mode
);
1141 /**************************************************************************
1142 Wide open. Just narrow and call sys_xxx.
1143 ****************************************************************************/
1145 int wsys_open(const smb_ucs2_t
*wfname
, int oflag
, mode_t mode
)
1148 return sys_open(unicode_to_unix(fname
,wfname
,sizeof(fname
)), oflag
, mode
);
1151 /**************************************************************************
1152 Wide fopen. Just narrow and call sys_xxx.
1153 ****************************************************************************/
1155 FILE *wsys_fopen(const smb_ucs2_t
*wfname
, const char *type
)
1158 return sys_fopen(unicode_to_unix(fname
,wfname
,sizeof(fname
)), type
);
1161 /**************************************************************************
1162 Wide opendir. Just narrow and call sys_xxx.
1163 ****************************************************************************/
1165 SMB_STRUCT_DIR
*wsys_opendir(const smb_ucs2_t
*wfname
)
1168 return opendir(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
1171 /**************************************************************************
1172 Wide readdir. Return a structure pointer containing a wide filename.
1173 ****************************************************************************/
1175 SMB_STRUCT_WDIRENT
*wsys_readdir(SMB_STRUCT_DIR
*dirp
)
1177 static SMB_STRUCT_WDIRENT retval
;
1178 SMB_STRUCT_DIRENT
*dirval
= sys_readdir(dirp
);
1184 * The only POSIX defined member of this struct is d_name.
1187 unix_to_unicode(retval
.d_name
,dirval
->d_name
,sizeof(retval
.d_name
));
1192 /**************************************************************************
1193 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
1194 ****************************************************************************/
1196 smb_ucs2_t
*wsys_getwd(smb_ucs2_t
*s
)
1199 char *p
= sys_getwd(fname
);
1204 return unix_to_unicode(s
, p
, sizeof(wpstring
));
1207 /**************************************************************************
1208 Wide chown. Just narrow and call sys_xxx.
1209 ****************************************************************************/
1211 int wsys_chown(const smb_ucs2_t
*wfname
, uid_t uid
, gid_t gid
)
1214 return chown(unicode_to_unix(fname
,wfname
,sizeof(fname
)), uid
, gid
);
1217 /**************************************************************************
1218 Wide chroot. Just narrow and call sys_xxx.
1219 ****************************************************************************/
1221 int wsys_chroot(const smb_ucs2_t
*wfname
)
1224 return chroot(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
1227 /**************************************************************************
1228 Wide getpwnam. Return a structure pointer containing wide names.
1229 ****************************************************************************/
1231 SMB_STRUCT_WPASSWD
*wsys_getpwnam(const smb_ucs2_t
*wname
)
1233 static SMB_STRUCT_WPASSWD retval
;
1235 struct passwd
*pwret
= sys_getpwnam(unicode_to_unix(name
,wname
,sizeof(name
)));
1240 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
1241 retval
.pw_passwd
= pwret
->pw_passwd
;
1242 retval
.pw_uid
= pwret
->pw_uid
;
1243 retval
.pw_gid
= pwret
->pw_gid
;
1244 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
1245 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
1246 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
1251 /**************************************************************************
1252 Wide getpwuid. Return a structure pointer containing wide names.
1253 ****************************************************************************/
1255 SMB_STRUCT_WPASSWD
*wsys_getpwuid(uid_t uid
)
1257 static SMB_STRUCT_WPASSWD retval
;
1258 struct passwd
*pwret
= sys_getpwuid(uid
);
1263 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
1264 retval
.pw_passwd
= pwret
->pw_passwd
;
1265 retval
.pw_uid
= pwret
->pw_uid
;
1266 retval
.pw_gid
= pwret
->pw_gid
;
1267 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
1268 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
1269 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
1273 #endif /* NOT CURRENTLY USED - JRA */
1275 /**************************************************************************
1276 Extract a command into an arg list. Uses a static pstring for storage.
1277 Caller frees returned arg list (which contains pointers into the static pstring).
1278 ****************************************************************************/
1280 static char **extract_args(const char *command
)
1282 static pstring trunc_cmd
;
1288 pstrcpy(trunc_cmd
, command
);
1290 if(!(ptr
= strtok(trunc_cmd
, " \t"))) {
1299 for( argcl
= 1; ptr
; ptr
= strtok(NULL
, " \t"))
1302 if((argl
= (char **)SMB_MALLOC((argcl
+ 1) * sizeof(char *))) == NULL
)
1306 * Now do the extraction.
1309 pstrcpy(trunc_cmd
, command
);
1311 ptr
= strtok(trunc_cmd
, " \t");
1315 while((ptr
= strtok(NULL
, " \t")) != NULL
)
1322 /**************************************************************************
1323 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1324 a sys_getpid() that only does a system call *once*.
1325 ****************************************************************************/
1327 static pid_t mypid
= (pid_t
)-1;
1329 pid_t
sys_fork(void)
1331 pid_t forkret
= fork();
1333 if (forkret
== (pid_t
)0) /* Child - reset mypid so sys_getpid does a system call. */
1339 /**************************************************************************
1340 Wrapper for getpid. Ensures we only do a system call *once*.
1341 ****************************************************************************/
1343 pid_t
sys_getpid(void)
1345 if (mypid
== (pid_t
)-1)
1351 /**************************************************************************
1352 Wrapper for popen. Safer as it doesn't search a path.
1353 Modified from the glibc sources.
1354 modified by tridge to return a file descriptor. We must kick our FILE* habit
1355 ****************************************************************************/
1357 typedef struct _popen_list
1361 struct _popen_list
*next
;
1364 static popen_list
*popen_chain
;
1366 int sys_popen(const char *command
)
1368 int parent_end
, child_end
;
1370 popen_list
*entry
= NULL
;
1373 if (pipe(pipe_fds
) < 0)
1376 parent_end
= pipe_fds
[0];
1377 child_end
= pipe_fds
[1];
1384 if((entry
= SMB_MALLOC_P(popen_list
)) == NULL
)
1387 ZERO_STRUCTP(entry
);
1390 * Extract the command and args into a NULL terminated array.
1393 if(!(argl
= extract_args(command
)))
1396 entry
->child_pid
= sys_fork();
1398 if (entry
->child_pid
== -1) {
1402 if (entry
->child_pid
== 0) {
1408 int child_std_end
= STDOUT_FILENO
;
1412 if (child_end
!= child_std_end
) {
1413 dup2 (child_end
, child_std_end
);
1418 * POSIX.2: "popen() shall ensure that any streams from previous
1419 * popen() calls that remain open in the parent process are closed
1420 * in the new child process."
1423 for (p
= popen_chain
; p
; p
= p
->next
)
1426 execv(argl
[0], argl
);
1437 /* Link into popen_chain. */
1438 entry
->next
= popen_chain
;
1439 popen_chain
= entry
;
1440 entry
->fd
= parent_end
;
1453 /**************************************************************************
1454 Wrapper for pclose. Modified from the glibc sources.
1455 ****************************************************************************/
1457 int sys_pclose(int fd
)
1460 popen_list
**ptr
= &popen_chain
;
1461 popen_list
*entry
= NULL
;
1465 /* Unlink from popen_chain. */
1466 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
) {
1467 if ((*ptr
)->fd
== fd
) {
1469 *ptr
= (*ptr
)->next
;
1475 if (status
< 0 || close(entry
->fd
) < 0)
1479 * As Samba is catching and eating child process
1480 * exits we don't really care about the child exit
1481 * code, a -1 with errno = ECHILD will do fine for us.
1485 wait_pid
= sys_waitpid (entry
->child_pid
, &wstatus
, 0);
1486 } while (wait_pid
== -1 && errno
== EINTR
);
1495 /**************************************************************************
1496 Wrappers for dlopen, dlsym, dlclose.
1497 ****************************************************************************/
1499 void *sys_dlopen(const char *name
, int flags
)
1501 #if defined(HAVE_DLOPEN)
1502 return dlopen(name
, flags
);
1508 void *sys_dlsym(void *handle
, const char *symbol
)
1510 #if defined(HAVE_DLSYM)
1511 return dlsym(handle
, symbol
);
1517 int sys_dlclose (void *handle
)
1519 #if defined(HAVE_DLCLOSE)
1520 return dlclose(handle
);
1526 const char *sys_dlerror(void)
1528 #if defined(HAVE_DLERROR)
1535 int sys_dup2(int oldfd
, int newfd
)
1537 #if defined(HAVE_DUP2)
1538 return dup2(oldfd
, newfd
);
1545 /**************************************************************************
1546 Wrapper for Admin Logs.
1547 ****************************************************************************/
1549 void sys_adminlog(int priority
, const char *format_str
, ...)
1553 char *msgbuf
= NULL
;
1555 va_start( ap
, format_str
);
1556 ret
= vasprintf( &msgbuf
, format_str
, ap
);
1562 #if defined(HAVE_SYSLOG)
1563 syslog( priority
, "%s", msgbuf
);
1565 DEBUG(0,("%s", msgbuf
));
1570 /******** Solaris EA helper function prototypes ********/
1571 #ifdef HAVE_ATTROPEN
1572 #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
1573 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
);
1574 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
);
1575 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
);
1576 static int solaris_unlinkat(int attrdirfd
, const char *name
);
1577 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
);
1578 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
);
1581 /**************************************************************************
1582 Wrappers for extented attribute calls. Based on the Linux package with
1583 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1584 ****************************************************************************/
1586 ssize_t
sys_getxattr (const char *path
, const char *name
, void *value
, size_t size
)
1588 #if defined(HAVE_GETXATTR)
1589 #ifndef XATTR_ADD_OPT
1590 return getxattr(path
, name
, value
, size
);
1593 return getxattr(path
, name
, value
, size
, 0, options
);
1595 #elif defined(HAVE_GETEA)
1596 return getea(path
, name
, value
, size
);
1597 #elif defined(HAVE_EXTATTR_GET_FILE)
1600 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1601 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1602 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1604 * The BSD implementation has a nasty habit of silently truncating
1605 * the returned value to the size of the buffer, so we have to check
1606 * that the buffer is large enough to fit the returned value.
1608 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1613 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1617 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno
)));
1619 #elif defined(HAVE_ATTR_GET)
1620 int retval
, flags
= 0;
1621 int valuelength
= (int)size
;
1622 char *attrname
= strchr(name
,'.') + 1;
1624 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1626 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1628 return retval
? retval
: valuelength
;
1629 #elif defined(HAVE_ATTROPEN)
1631 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
, 0);
1633 ret
= solaris_read_xattr(attrfd
, value
, size
);
1643 ssize_t
sys_lgetxattr (const char *path
, const char *name
, void *value
, size_t size
)
1645 #if defined(HAVE_LGETXATTR)
1646 return lgetxattr(path
, name
, value
, size
);
1647 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1648 int options
= XATTR_NOFOLLOW
;
1649 return getxattr(path
, name
, value
, size
, 0, options
);
1650 #elif defined(HAVE_LGETEA)
1651 return lgetea(path
, name
, value
, size
);
1652 #elif defined(HAVE_EXTATTR_GET_LINK)
1655 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1656 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1657 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1659 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1664 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1668 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno
)));
1670 #elif defined(HAVE_ATTR_GET)
1671 int retval
, flags
= ATTR_DONTFOLLOW
;
1672 int valuelength
= (int)size
;
1673 char *attrname
= strchr(name
,'.') + 1;
1675 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1677 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1679 return retval
? retval
: valuelength
;
1680 #elif defined(HAVE_ATTROPEN)
1682 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1684 ret
= solaris_read_xattr(attrfd
, value
, size
);
1694 ssize_t
sys_fgetxattr (int filedes
, const char *name
, void *value
, size_t size
)
1696 #if defined(HAVE_FGETXATTR)
1697 #ifndef XATTR_ADD_OPT
1698 return fgetxattr(filedes
, name
, value
, size
);
1701 return fgetxattr(filedes
, name
, value
, size
, 0, options
);
1703 #elif defined(HAVE_FGETEA)
1704 return fgetea(filedes
, name
, value
, size
);
1705 #elif defined(HAVE_EXTATTR_GET_FD)
1708 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1709 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1710 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1712 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1717 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, value
, size
)) >= 0)
1721 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno
)));
1723 #elif defined(HAVE_ATTR_GETF)
1724 int retval
, flags
= 0;
1725 int valuelength
= (int)size
;
1726 char *attrname
= strchr(name
,'.') + 1;
1728 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1730 retval
= attr_getf(filedes
, attrname
, (char *)value
, &valuelength
, flags
);
1732 return retval
? retval
: valuelength
;
1733 #elif defined(HAVE_ATTROPEN)
1735 int attrfd
= solaris_openat(filedes
, name
, O_RDONLY
|O_XATTR
, 0);
1737 ret
= solaris_read_xattr(attrfd
, value
, size
);
1747 #if defined(HAVE_EXTATTR_LIST_FILE)
1749 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1757 { EXTATTR_NAMESPACE_SYSTEM
, EXTATTR_PREFIX("system.") },
1758 { EXTATTR_NAMESPACE_USER
, EXTATTR_PREFIX("user.") },
1766 static ssize_t
bsd_attr_list (int type
, extattr_arg arg
, char *list
, size_t size
)
1768 ssize_t list_size
, total_size
= 0;
1771 /* Iterate through extattr(2) namespaces */
1772 for(t
= 0; t
< (sizeof(extattr
)/sizeof(extattr
[0])); t
++) {
1774 #if defined(HAVE_EXTATTR_LIST_FILE)
1776 list_size
= extattr_list_file(arg
.path
, extattr
[t
].space
, list
, size
);
1779 #if defined(HAVE_EXTATTR_LIST_LINK)
1781 list_size
= extattr_list_link(arg
.path
, extattr
[t
].space
, list
, size
);
1784 #if defined(HAVE_EXTATTR_LIST_FD)
1786 list_size
= extattr_list_fd(arg
.filedes
, extattr
[t
].space
, list
, size
);
1793 /* Some error happend. Errno should be set by the previous call */
1799 /* XXX: Call with an empty buffer may be used to calculate
1800 necessary buffer size. Unfortunately, we can't say, how
1801 many attributes were returned, so here is the potential
1802 problem with the emulation.
1805 /* Take the worse case of one char attribute names -
1806 two bytes per name plus one more for sanity.
1808 total_size
+= list_size
+ (list_size
/2 + 1)*extattr
[t
].len
;
1811 /* Count necessary offset to fit namespace prefixes */
1813 for(i
= 0; i
< list_size
; i
+= list
[i
] + 1)
1814 len
+= extattr
[t
].len
;
1816 total_size
+= list_size
+ len
;
1817 /* Buffer is too small to fit the results */
1818 if(total_size
> size
) {
1822 /* Shift results back, so we can prepend prefixes */
1823 buf
= memmove(list
+ len
, list
, list_size
);
1825 for(i
= 0; i
< list_size
; i
+= len
+ 1) {
1827 strncpy(list
, extattr
[t
].name
, extattr
[t
].len
+ 1);
1828 list
+= extattr
[t
].len
;
1829 strncpy(list
, buf
+ i
+ 1, len
);
1840 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1841 static char attr_buffer
[ATTR_MAX_VALUELEN
];
1843 static ssize_t
irix_attr_list(const char *path
, int filedes
, char *list
, size_t size
, int flags
)
1845 int retval
= 0, index
;
1846 attrlist_cursor_t
*cursor
= 0;
1848 attrlist_t
* al
= (attrlist_t
*)attr_buffer
;
1850 size_t ent_size
, left
= size
;
1855 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1857 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1859 for (index
= 0; index
< al
->al_count
; index
++) {
1860 ae
= ATTR_ENTRY(attr_buffer
, index
);
1861 ent_size
= strlen(ae
->a_name
) + sizeof("user.");
1862 if (left
>= ent_size
) {
1863 strncpy(bp
, "user.", sizeof("user."));
1864 strncat(bp
, ae
->a_name
, ent_size
- sizeof("user."));
1872 total_size
+= ent_size
;
1874 if (al
->al_more
== 0) break;
1881 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1883 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1885 for (index
= 0; index
< al
->al_count
; index
++) {
1886 ae
= ATTR_ENTRY(attr_buffer
, index
);
1887 ent_size
= strlen(ae
->a_name
) + sizeof("system.");
1888 if (left
>= ent_size
) {
1889 strncpy(bp
, "system.", sizeof("system."));
1890 strncat(bp
, ae
->a_name
, ent_size
- sizeof("system."));
1898 total_size
+= ent_size
;
1900 if (al
->al_more
== 0) break;
1903 return (ssize_t
)(retval
? retval
: total_size
);
1908 ssize_t
sys_listxattr (const char *path
, char *list
, size_t size
)
1910 #if defined(HAVE_LISTXATTR)
1911 #ifndef XATTR_ADD_OPT
1912 return listxattr(path
, list
, size
);
1915 return listxattr(path
, list
, size
, options
);
1917 #elif defined(HAVE_LISTEA)
1918 return listea(path
, list
, size
);
1919 #elif defined(HAVE_EXTATTR_LIST_FILE)
1922 return bsd_attr_list(0, arg
, list
, size
);
1923 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1924 return irix_attr_list(path
, 0, list
, size
, 0);
1925 #elif defined(HAVE_ATTROPEN)
1927 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
1928 if (attrdirfd
>= 0) {
1929 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1939 ssize_t
sys_llistxattr (const char *path
, char *list
, size_t size
)
1941 #if defined(HAVE_LLISTXATTR)
1942 return llistxattr(path
, list
, size
);
1943 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1944 int options
= XATTR_NOFOLLOW
;
1945 return listxattr(path
, list
, size
, options
);
1946 #elif defined(HAVE_LLISTEA)
1947 return llistea(path
, list
, size
);
1948 #elif defined(HAVE_EXTATTR_LIST_LINK)
1951 return bsd_attr_list(1, arg
, list
, size
);
1952 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1953 return irix_attr_list(path
, 0, list
, size
, ATTR_DONTFOLLOW
);
1954 #elif defined(HAVE_ATTROPEN)
1956 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1957 if (attrdirfd
>= 0) {
1958 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1968 ssize_t
sys_flistxattr (int filedes
, char *list
, size_t size
)
1970 #if defined(HAVE_FLISTXATTR)
1971 #ifndef XATTR_ADD_OPT
1972 return flistxattr(filedes
, list
, size
);
1975 return flistxattr(filedes
, list
, size
, options
);
1977 #elif defined(HAVE_FLISTEA)
1978 return flistea(filedes
, list
, size
);
1979 #elif defined(HAVE_EXTATTR_LIST_FD)
1981 arg
.filedes
= filedes
;
1982 return bsd_attr_list(2, arg
, list
, size
);
1983 #elif defined(HAVE_ATTR_LISTF)
1984 return irix_attr_list(NULL
, filedes
, list
, size
, 0);
1985 #elif defined(HAVE_ATTROPEN)
1987 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
1988 if (attrdirfd
>= 0) {
1989 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1999 int sys_removexattr (const char *path
, const char *name
)
2001 #if defined(HAVE_REMOVEXATTR)
2002 #ifndef XATTR_ADD_OPT
2003 return removexattr(path
, name
);
2006 return removexattr(path
, name
, options
);
2008 #elif defined(HAVE_REMOVEEA)
2009 return removeea(path
, name
);
2010 #elif defined(HAVE_EXTATTR_DELETE_FILE)
2012 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2013 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2014 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2016 return extattr_delete_file(path
, attrnamespace
, attrname
);
2017 #elif defined(HAVE_ATTR_REMOVE)
2019 char *attrname
= strchr(name
,'.') + 1;
2021 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2023 return attr_remove(path
, attrname
, flags
);
2024 #elif defined(HAVE_ATTROPEN)
2026 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
2027 if (attrdirfd
>= 0) {
2028 ret
= solaris_unlinkat(attrdirfd
, name
);
2038 int sys_lremovexattr (const char *path
, const char *name
)
2040 #if defined(HAVE_LREMOVEXATTR)
2041 return lremovexattr(path
, name
);
2042 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
2043 int options
= XATTR_NOFOLLOW
;
2044 return removexattr(path
, name
, options
);
2045 #elif defined(HAVE_LREMOVEEA)
2046 return lremoveea(path
, name
);
2047 #elif defined(HAVE_EXTATTR_DELETE_LINK)
2049 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2050 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2051 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2053 return extattr_delete_link(path
, attrnamespace
, attrname
);
2054 #elif defined(HAVE_ATTR_REMOVE)
2055 int flags
= ATTR_DONTFOLLOW
;
2056 char *attrname
= strchr(name
,'.') + 1;
2058 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2060 return attr_remove(path
, attrname
, flags
);
2061 #elif defined(HAVE_ATTROPEN)
2063 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
2064 if (attrdirfd
>= 0) {
2065 ret
= solaris_unlinkat(attrdirfd
, name
);
2075 int sys_fremovexattr (int filedes
, const char *name
)
2077 #if defined(HAVE_FREMOVEXATTR)
2078 #ifndef XATTR_ADD_OPT
2079 return fremovexattr(filedes
, name
);
2082 return fremovexattr(filedes
, name
, options
);
2084 #elif defined(HAVE_FREMOVEEA)
2085 return fremoveea(filedes
, name
);
2086 #elif defined(HAVE_EXTATTR_DELETE_FD)
2088 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2089 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2090 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2092 return extattr_delete_fd(filedes
, attrnamespace
, attrname
);
2093 #elif defined(HAVE_ATTR_REMOVEF)
2095 char *attrname
= strchr(name
,'.') + 1;
2097 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2099 return attr_removef(filedes
, attrname
, flags
);
2100 #elif defined(HAVE_ATTROPEN)
2102 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
2103 if (attrdirfd
>= 0) {
2104 ret
= solaris_unlinkat(attrdirfd
, name
);
2114 #if !defined(HAVE_SETXATTR)
2115 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
2116 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
2119 int sys_setxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2121 #if defined(HAVE_SETXATTR)
2122 #ifndef XATTR_ADD_OPT
2123 return setxattr(path
, name
, value
, size
, flags
);
2126 return setxattr(path
, name
, value
, size
, 0, options
);
2128 #elif defined(HAVE_SETEA)
2129 return setea(path
, name
, value
, size
, flags
);
2130 #elif defined(HAVE_EXTATTR_SET_FILE)
2133 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2134 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2135 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2137 /* Check attribute existence */
2138 retval
= extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0);
2140 /* REPLACE attribute, that doesn't exist */
2141 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2145 /* Ignore other errors */
2148 /* CREATE attribute, that already exists */
2149 if (flags
& XATTR_CREATE
) {
2155 retval
= extattr_set_file(path
, attrnamespace
, attrname
, value
, size
);
2156 return (retval
< 0) ? -1 : 0;
2157 #elif defined(HAVE_ATTR_SET)
2159 char *attrname
= strchr(name
,'.') + 1;
2161 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2162 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2163 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2165 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2166 #elif defined(HAVE_ATTROPEN)
2168 int myflags
= O_RDWR
;
2170 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2171 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2172 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2174 ret
= solaris_write_xattr(attrfd
, value
, size
);
2184 int sys_lsetxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2186 #if defined(HAVE_LSETXATTR)
2187 return lsetxattr(path
, name
, value
, size
, flags
);
2188 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2189 int options
= XATTR_NOFOLLOW
;
2190 return setxattr(path
, name
, value
, size
, 0, options
);
2191 #elif defined(LSETEA)
2192 return lsetea(path
, name
, value
, size
, flags
);
2193 #elif defined(HAVE_EXTATTR_SET_LINK)
2196 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2197 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2198 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2200 /* Check attribute existence */
2201 retval
= extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0);
2203 /* REPLACE attribute, that doesn't exist */
2204 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2208 /* Ignore other errors */
2211 /* CREATE attribute, that already exists */
2212 if (flags
& XATTR_CREATE
) {
2219 retval
= extattr_set_link(path
, attrnamespace
, attrname
, value
, size
);
2220 return (retval
< 0) ? -1 : 0;
2221 #elif defined(HAVE_ATTR_SET)
2222 int myflags
= ATTR_DONTFOLLOW
;
2223 char *attrname
= strchr(name
,'.') + 1;
2225 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2226 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2227 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2229 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2230 #elif defined(HAVE_ATTROPEN)
2232 int myflags
= O_RDWR
| AT_SYMLINK_NOFOLLOW
;
2234 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2235 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2236 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2238 ret
= solaris_write_xattr(attrfd
, value
, size
);
2248 int sys_fsetxattr (int filedes
, const char *name
, const void *value
, size_t size
, int flags
)
2250 #if defined(HAVE_FSETXATTR)
2251 #ifndef XATTR_ADD_OPT
2252 return fsetxattr(filedes
, name
, value
, size
, flags
);
2255 return fsetxattr(filedes
, name
, value
, size
, 0, options
);
2257 #elif defined(HAVE_FSETEA)
2258 return fsetea(filedes
, name
, value
, size
, flags
);
2259 #elif defined(HAVE_EXTATTR_SET_FD)
2262 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2263 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2264 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2266 /* Check attribute existence */
2267 retval
= extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0);
2269 /* REPLACE attribute, that doesn't exist */
2270 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2274 /* Ignore other errors */
2277 /* CREATE attribute, that already exists */
2278 if (flags
& XATTR_CREATE
) {
2284 retval
= extattr_set_fd(filedes
, attrnamespace
, attrname
, value
, size
);
2285 return (retval
< 0) ? -1 : 0;
2286 #elif defined(HAVE_ATTR_SETF)
2288 char *attrname
= strchr(name
,'.') + 1;
2290 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2291 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2292 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2294 return attr_setf(filedes
, attrname
, (const char *)value
, size
, myflags
);
2295 #elif defined(HAVE_ATTROPEN)
2297 int myflags
= O_RDWR
| O_XATTR
;
2299 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2300 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2301 attrfd
= solaris_openat(filedes
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2303 ret
= solaris_write_xattr(attrfd
, value
, size
);
2313 /**************************************************************************
2314 helper functions for Solaris' EA support
2315 ****************************************************************************/
2316 #ifdef HAVE_ATTROPEN
2317 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
)
2321 if (fstat(attrfd
, &sbuf
) == -1) {
2326 /* This is to return the current size of the named extended attribute */
2328 return sbuf
.st_size
;
2331 /* check size and read xattr */
2332 if (sbuf
.st_size
> size
) {
2337 return read(attrfd
, value
, sbuf
.st_size
);
2340 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
)
2346 int newfd
= dup(attrdirfd
);
2347 /* CAUTION: The originating file descriptor should not be
2348 used again following the call to fdopendir().
2349 For that reason we dup() the file descriptor
2350 here to make things more clear. */
2351 dirp
= fdopendir(newfd
);
2353 while ((de
= readdir(dirp
))) {
2354 size_t listlen
= strlen(de
->d_name
);
2355 if (!strcmp(de
->d_name
, ".") || !strcmp(de
->d_name
, "..")) {
2356 /* we don't want "." and ".." here: */
2357 DEBUG(10,("skipped EA %s\n",de
->d_name
));
2362 /* return the current size of the list of extended attribute names*/
2365 /* check size and copy entrieѕ + nul into list. */
2366 if ((len
+ listlen
+ 1) > size
) {
2371 safe_strcpy(list
+ len
, de
->d_name
, listlen
);
2372 pstrcpy(list
+ len
, de
->d_name
);
2380 if (closedir(dirp
) == -1) {
2381 DEBUG(0,("closedir dirp failed: %s\n",strerror(errno
)));
2387 static int solaris_unlinkat(int attrdirfd
, const char *name
)
2389 if (unlinkat(attrdirfd
, name
, 0) == -1) {
2390 if (errno
== ENOENT
) {
2398 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
)
2400 int filedes
= attropen(path
, attrpath
, oflag
, mode
);
2401 if (filedes
== -1) {
2402 DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path
,attrpath
,strerror(errno
)));
2403 if (errno
== EINVAL
) {
2412 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
)
2414 int filedes
= openat(fildes
, path
, oflag
, mode
);
2415 if (filedes
== -1) {
2416 DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes
,path
,strerror(errno
)));
2417 if (errno
== EINVAL
) {
2426 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
)
2428 if ((ftruncate(attrfd
, 0) == 0) && (write(attrfd
, value
, size
) == size
)) {
2431 DEBUG(10,("solaris_write_xattr FAILED!\n"));
2435 #endif /*HAVE_ATTROPEN*/
2437 /****************************************************************************
2438 Return the major devicenumber for UNIX extensions.
2439 ****************************************************************************/
2441 uint32
unix_dev_major(SMB_DEV_T dev
)
2443 #if defined(HAVE_DEVICE_MAJOR_FN)
2444 return (uint32
)major(dev
);
2446 return (uint32
)(dev
>> 8);
2450 /****************************************************************************
2451 Return the minor devicenumber for UNIX extensions.
2452 ****************************************************************************/
2454 uint32
unix_dev_minor(SMB_DEV_T dev
)
2456 #if defined(HAVE_DEVICE_MINOR_FN)
2457 return (uint32
)minor(dev
);
2459 return (uint32
)(dev
& 0xff);
2463 #if defined(WITH_AIO)
2465 /*******************************************************************
2466 An aio_read wrapper that will deal with 64-bit sizes.
2467 ********************************************************************/
2469 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2471 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2472 return aio_read64(aiocb
);
2473 #elif defined(HAVE_AIO_READ)
2474 return aio_read(aiocb
);
2481 /*******************************************************************
2482 An aio_write wrapper that will deal with 64-bit sizes.
2483 ********************************************************************/
2485 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2487 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2488 return aio_write64(aiocb
);
2489 #elif defined(HAVE_AIO_WRITE)
2490 return aio_write(aiocb
);
2497 /*******************************************************************
2498 An aio_return wrapper that will deal with 64-bit sizes.
2499 ********************************************************************/
2501 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2503 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2504 return aio_return64(aiocb
);
2505 #elif defined(HAVE_AIO_RETURN)
2506 return aio_return(aiocb
);
2513 /*******************************************************************
2514 An aio_cancel wrapper that will deal with 64-bit sizes.
2515 ********************************************************************/
2517 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2519 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2520 return aio_cancel64(fd
, aiocb
);
2521 #elif defined(HAVE_AIO_CANCEL)
2522 return aio_cancel(fd
, aiocb
);
2529 /*******************************************************************
2530 An aio_error wrapper that will deal with 64-bit sizes.
2531 ********************************************************************/
2533 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2535 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2536 return aio_error64(aiocb
);
2537 #elif defined(HAVE_AIO_ERROR)
2538 return aio_error(aiocb
);
2545 /*******************************************************************
2546 An aio_fsync wrapper that will deal with 64-bit sizes.
2547 ********************************************************************/
2549 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2551 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2552 return aio_fsync64(op
, aiocb
);
2553 #elif defined(HAVE_AIO_FSYNC)
2554 return aio_fsync(op
, aiocb
);
2561 /*******************************************************************
2562 An aio_fsync wrapper that will deal with 64-bit sizes.
2563 ********************************************************************/
2565 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2567 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2568 return aio_suspend64(cblist
, n
, timeout
);
2569 #elif defined(HAVE_AIO_FSYNC)
2570 return aio_suspend(cblist
, n
, timeout
);
2576 #else /* !WITH_AIO */
2578 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2584 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2590 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2596 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2602 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2608 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2614 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2619 #endif /* WITH_AIO */
2621 int sys_getpeereid( int s
, uid_t
*uid
)
2623 #if defined(HAVE_PEERCRED)
2625 socklen_t cred_len
= sizeof(struct ucred
);
2628 ret
= getsockopt(s
, SOL_SOCKET
, SO_PEERCRED
, (void *)&cred
, &cred_len
);
2633 if (cred_len
!= sizeof(struct ucred
)) {