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)
1505 return dlopen(name
, flags
);
1512 void *sys_dlsym(void *handle
, const char *symbol
)
1514 #if defined(HAVE_DLSYM)
1515 return dlsym(handle
, symbol
);
1521 int sys_dlclose (void *handle
)
1523 #if defined(HAVE_DLCLOSE)
1524 return dlclose(handle
);
1530 const char *sys_dlerror(void)
1532 #if defined(HAVE_DLERROR)
1539 int sys_dup2(int oldfd
, int newfd
)
1541 #if defined(HAVE_DUP2)
1542 return dup2(oldfd
, newfd
);
1549 /**************************************************************************
1550 Wrapper for Admin Logs.
1551 ****************************************************************************/
1553 void sys_adminlog(int priority
, const char *format_str
, ...)
1557 char *msgbuf
= NULL
;
1559 va_start( ap
, format_str
);
1560 ret
= vasprintf( &msgbuf
, format_str
, ap
);
1566 #if defined(HAVE_SYSLOG)
1567 syslog( priority
, "%s", msgbuf
);
1569 DEBUG(0,("%s", msgbuf
));
1574 /******** Solaris EA helper function prototypes ********/
1575 #ifdef HAVE_ATTROPEN
1576 #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
1577 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
);
1578 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
);
1579 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
);
1580 static int solaris_unlinkat(int attrdirfd
, const char *name
);
1581 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
);
1582 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
);
1585 /**************************************************************************
1586 Wrappers for extented attribute calls. Based on the Linux package with
1587 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1588 ****************************************************************************/
1590 ssize_t
sys_getxattr (const char *path
, const char *name
, void *value
, size_t size
)
1592 #if defined(HAVE_GETXATTR)
1593 #ifndef XATTR_ADD_OPT
1594 return getxattr(path
, name
, value
, size
);
1597 return getxattr(path
, name
, value
, size
, 0, options
);
1599 #elif defined(HAVE_GETEA)
1600 return getea(path
, name
, value
, size
);
1601 #elif defined(HAVE_EXTATTR_GET_FILE)
1604 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1605 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1606 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1608 * The BSD implementation has a nasty habit of silently truncating
1609 * the returned value to the size of the buffer, so we have to check
1610 * that the buffer is large enough to fit the returned value.
1612 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1617 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1621 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno
)));
1623 #elif defined(HAVE_ATTR_GET)
1624 int retval
, flags
= 0;
1625 int valuelength
= (int)size
;
1626 char *attrname
= strchr(name
,'.') + 1;
1628 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1630 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1632 return retval
? retval
: valuelength
;
1633 #elif defined(HAVE_ATTROPEN)
1635 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
, 0);
1637 ret
= solaris_read_xattr(attrfd
, value
, size
);
1647 ssize_t
sys_lgetxattr (const char *path
, const char *name
, void *value
, size_t size
)
1649 #if defined(HAVE_LGETXATTR)
1650 return lgetxattr(path
, name
, value
, size
);
1651 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1652 int options
= XATTR_NOFOLLOW
;
1653 return getxattr(path
, name
, value
, size
, 0, options
);
1654 #elif defined(HAVE_LGETEA)
1655 return lgetea(path
, name
, value
, size
);
1656 #elif defined(HAVE_EXTATTR_GET_LINK)
1659 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1660 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1661 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1663 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1668 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1672 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno
)));
1674 #elif defined(HAVE_ATTR_GET)
1675 int retval
, flags
= ATTR_DONTFOLLOW
;
1676 int valuelength
= (int)size
;
1677 char *attrname
= strchr(name
,'.') + 1;
1679 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1681 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1683 return retval
? retval
: valuelength
;
1684 #elif defined(HAVE_ATTROPEN)
1686 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1688 ret
= solaris_read_xattr(attrfd
, value
, size
);
1698 ssize_t
sys_fgetxattr (int filedes
, const char *name
, void *value
, size_t size
)
1700 #if defined(HAVE_FGETXATTR)
1701 #ifndef XATTR_ADD_OPT
1702 return fgetxattr(filedes
, name
, value
, size
);
1705 return fgetxattr(filedes
, name
, value
, size
, 0, options
);
1707 #elif defined(HAVE_FGETEA)
1708 return fgetea(filedes
, name
, value
, size
);
1709 #elif defined(HAVE_EXTATTR_GET_FD)
1712 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1713 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1714 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1716 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1721 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, value
, size
)) >= 0)
1725 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno
)));
1727 #elif defined(HAVE_ATTR_GETF)
1728 int retval
, flags
= 0;
1729 int valuelength
= (int)size
;
1730 char *attrname
= strchr(name
,'.') + 1;
1732 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1734 retval
= attr_getf(filedes
, attrname
, (char *)value
, &valuelength
, flags
);
1736 return retval
? retval
: valuelength
;
1737 #elif defined(HAVE_ATTROPEN)
1739 int attrfd
= solaris_openat(filedes
, name
, O_RDONLY
|O_XATTR
, 0);
1741 ret
= solaris_read_xattr(attrfd
, value
, size
);
1751 #if defined(HAVE_EXTATTR_LIST_FILE)
1753 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1761 { EXTATTR_NAMESPACE_SYSTEM
, EXTATTR_PREFIX("system.") },
1762 { EXTATTR_NAMESPACE_USER
, EXTATTR_PREFIX("user.") },
1770 static ssize_t
bsd_attr_list (int type
, extattr_arg arg
, char *list
, size_t size
)
1772 ssize_t list_size
, total_size
= 0;
1775 /* Iterate through extattr(2) namespaces */
1776 for(t
= 0; t
< (sizeof(extattr
)/sizeof(extattr
[0])); t
++) {
1778 #if defined(HAVE_EXTATTR_LIST_FILE)
1780 list_size
= extattr_list_file(arg
.path
, extattr
[t
].space
, list
, size
);
1783 #if defined(HAVE_EXTATTR_LIST_LINK)
1785 list_size
= extattr_list_link(arg
.path
, extattr
[t
].space
, list
, size
);
1788 #if defined(HAVE_EXTATTR_LIST_FD)
1790 list_size
= extattr_list_fd(arg
.filedes
, extattr
[t
].space
, list
, size
);
1797 /* Some error happend. Errno should be set by the previous call */
1803 /* XXX: Call with an empty buffer may be used to calculate
1804 necessary buffer size. Unfortunately, we can't say, how
1805 many attributes were returned, so here is the potential
1806 problem with the emulation.
1809 /* Take the worse case of one char attribute names -
1810 two bytes per name plus one more for sanity.
1812 total_size
+= list_size
+ (list_size
/2 + 1)*extattr
[t
].len
;
1815 /* Count necessary offset to fit namespace prefixes */
1817 for(i
= 0; i
< list_size
; i
+= list
[i
] + 1)
1818 len
+= extattr
[t
].len
;
1820 total_size
+= list_size
+ len
;
1821 /* Buffer is too small to fit the results */
1822 if(total_size
> size
) {
1826 /* Shift results back, so we can prepend prefixes */
1827 buf
= memmove(list
+ len
, list
, list_size
);
1829 for(i
= 0; i
< list_size
; i
+= len
+ 1) {
1831 strncpy(list
, extattr
[t
].name
, extattr
[t
].len
+ 1);
1832 list
+= extattr
[t
].len
;
1833 strncpy(list
, buf
+ i
+ 1, len
);
1844 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1845 static char attr_buffer
[ATTR_MAX_VALUELEN
];
1847 static ssize_t
irix_attr_list(const char *path
, int filedes
, char *list
, size_t size
, int flags
)
1849 int retval
= 0, index
;
1850 attrlist_cursor_t
*cursor
= 0;
1852 attrlist_t
* al
= (attrlist_t
*)attr_buffer
;
1854 size_t ent_size
, left
= size
;
1859 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1861 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1863 for (index
= 0; index
< al
->al_count
; index
++) {
1864 ae
= ATTR_ENTRY(attr_buffer
, index
);
1865 ent_size
= strlen(ae
->a_name
) + sizeof("user.");
1866 if (left
>= ent_size
) {
1867 strncpy(bp
, "user.", sizeof("user."));
1868 strncat(bp
, ae
->a_name
, ent_size
- sizeof("user."));
1876 total_size
+= ent_size
;
1878 if (al
->al_more
== 0) break;
1885 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1887 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1889 for (index
= 0; index
< al
->al_count
; index
++) {
1890 ae
= ATTR_ENTRY(attr_buffer
, index
);
1891 ent_size
= strlen(ae
->a_name
) + sizeof("system.");
1892 if (left
>= ent_size
) {
1893 strncpy(bp
, "system.", sizeof("system."));
1894 strncat(bp
, ae
->a_name
, ent_size
- sizeof("system."));
1902 total_size
+= ent_size
;
1904 if (al
->al_more
== 0) break;
1907 return (ssize_t
)(retval
? retval
: total_size
);
1912 ssize_t
sys_listxattr (const char *path
, char *list
, size_t size
)
1914 #if defined(HAVE_LISTXATTR)
1915 #ifndef XATTR_ADD_OPT
1916 return listxattr(path
, list
, size
);
1919 return listxattr(path
, list
, size
, options
);
1921 #elif defined(HAVE_LISTEA)
1922 return listea(path
, list
, size
);
1923 #elif defined(HAVE_EXTATTR_LIST_FILE)
1926 return bsd_attr_list(0, arg
, list
, size
);
1927 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1928 return irix_attr_list(path
, 0, list
, size
, 0);
1929 #elif defined(HAVE_ATTROPEN)
1931 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
1932 if (attrdirfd
>= 0) {
1933 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1943 ssize_t
sys_llistxattr (const char *path
, char *list
, size_t size
)
1945 #if defined(HAVE_LLISTXATTR)
1946 return llistxattr(path
, list
, size
);
1947 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1948 int options
= XATTR_NOFOLLOW
;
1949 return listxattr(path
, list
, size
, options
);
1950 #elif defined(HAVE_LLISTEA)
1951 return llistea(path
, list
, size
);
1952 #elif defined(HAVE_EXTATTR_LIST_LINK)
1955 return bsd_attr_list(1, arg
, list
, size
);
1956 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1957 return irix_attr_list(path
, 0, list
, size
, ATTR_DONTFOLLOW
);
1958 #elif defined(HAVE_ATTROPEN)
1960 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1961 if (attrdirfd
>= 0) {
1962 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1972 ssize_t
sys_flistxattr (int filedes
, char *list
, size_t size
)
1974 #if defined(HAVE_FLISTXATTR)
1975 #ifndef XATTR_ADD_OPT
1976 return flistxattr(filedes
, list
, size
);
1979 return flistxattr(filedes
, list
, size
, options
);
1981 #elif defined(HAVE_FLISTEA)
1982 return flistea(filedes
, list
, size
);
1983 #elif defined(HAVE_EXTATTR_LIST_FD)
1985 arg
.filedes
= filedes
;
1986 return bsd_attr_list(2, arg
, list
, size
);
1987 #elif defined(HAVE_ATTR_LISTF)
1988 return irix_attr_list(NULL
, filedes
, list
, size
, 0);
1989 #elif defined(HAVE_ATTROPEN)
1991 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
1992 if (attrdirfd
>= 0) {
1993 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
2003 int sys_removexattr (const char *path
, const char *name
)
2005 #if defined(HAVE_REMOVEXATTR)
2006 #ifndef XATTR_ADD_OPT
2007 return removexattr(path
, name
);
2010 return removexattr(path
, name
, options
);
2012 #elif defined(HAVE_REMOVEEA)
2013 return removeea(path
, name
);
2014 #elif defined(HAVE_EXTATTR_DELETE_FILE)
2016 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2017 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2018 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2020 return extattr_delete_file(path
, attrnamespace
, attrname
);
2021 #elif defined(HAVE_ATTR_REMOVE)
2023 char *attrname
= strchr(name
,'.') + 1;
2025 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2027 return attr_remove(path
, attrname
, flags
);
2028 #elif defined(HAVE_ATTROPEN)
2030 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
2031 if (attrdirfd
>= 0) {
2032 ret
= solaris_unlinkat(attrdirfd
, name
);
2042 int sys_lremovexattr (const char *path
, const char *name
)
2044 #if defined(HAVE_LREMOVEXATTR)
2045 return lremovexattr(path
, name
);
2046 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
2047 int options
= XATTR_NOFOLLOW
;
2048 return removexattr(path
, name
, options
);
2049 #elif defined(HAVE_LREMOVEEA)
2050 return lremoveea(path
, name
);
2051 #elif defined(HAVE_EXTATTR_DELETE_LINK)
2053 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2054 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2055 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2057 return extattr_delete_link(path
, attrnamespace
, attrname
);
2058 #elif defined(HAVE_ATTR_REMOVE)
2059 int flags
= ATTR_DONTFOLLOW
;
2060 char *attrname
= strchr(name
,'.') + 1;
2062 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2064 return attr_remove(path
, attrname
, flags
);
2065 #elif defined(HAVE_ATTROPEN)
2067 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
2068 if (attrdirfd
>= 0) {
2069 ret
= solaris_unlinkat(attrdirfd
, name
);
2079 int sys_fremovexattr (int filedes
, const char *name
)
2081 #if defined(HAVE_FREMOVEXATTR)
2082 #ifndef XATTR_ADD_OPT
2083 return fremovexattr(filedes
, name
);
2086 return fremovexattr(filedes
, name
, options
);
2088 #elif defined(HAVE_FREMOVEEA)
2089 return fremoveea(filedes
, name
);
2090 #elif defined(HAVE_EXTATTR_DELETE_FD)
2092 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2093 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2094 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2096 return extattr_delete_fd(filedes
, attrnamespace
, attrname
);
2097 #elif defined(HAVE_ATTR_REMOVEF)
2099 char *attrname
= strchr(name
,'.') + 1;
2101 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2103 return attr_removef(filedes
, attrname
, flags
);
2104 #elif defined(HAVE_ATTROPEN)
2106 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
2107 if (attrdirfd
>= 0) {
2108 ret
= solaris_unlinkat(attrdirfd
, name
);
2118 #if !defined(HAVE_SETXATTR)
2119 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
2120 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
2123 int sys_setxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2125 #if defined(HAVE_SETXATTR)
2126 #ifndef XATTR_ADD_OPT
2127 return setxattr(path
, name
, value
, size
, flags
);
2130 return setxattr(path
, name
, value
, size
, 0, options
);
2132 #elif defined(HAVE_SETEA)
2133 return setea(path
, name
, value
, size
, flags
);
2134 #elif defined(HAVE_EXTATTR_SET_FILE)
2137 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2138 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2139 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2141 /* Check attribute existence */
2142 retval
= extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0);
2144 /* REPLACE attribute, that doesn't exist */
2145 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2149 /* Ignore other errors */
2152 /* CREATE attribute, that already exists */
2153 if (flags
& XATTR_CREATE
) {
2159 retval
= extattr_set_file(path
, attrnamespace
, attrname
, value
, size
);
2160 return (retval
< 0) ? -1 : 0;
2161 #elif defined(HAVE_ATTR_SET)
2163 char *attrname
= strchr(name
,'.') + 1;
2165 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2166 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2167 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2169 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2170 #elif defined(HAVE_ATTROPEN)
2172 int myflags
= O_RDWR
;
2174 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2175 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2176 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2178 ret
= solaris_write_xattr(attrfd
, value
, size
);
2188 int sys_lsetxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2190 #if defined(HAVE_LSETXATTR)
2191 return lsetxattr(path
, name
, value
, size
, flags
);
2192 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2193 int options
= XATTR_NOFOLLOW
;
2194 return setxattr(path
, name
, value
, size
, 0, options
);
2195 #elif defined(LSETEA)
2196 return lsetea(path
, name
, value
, size
, flags
);
2197 #elif defined(HAVE_EXTATTR_SET_LINK)
2200 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2201 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2202 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2204 /* Check attribute existence */
2205 retval
= extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0);
2207 /* REPLACE attribute, that doesn't exist */
2208 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2212 /* Ignore other errors */
2215 /* CREATE attribute, that already exists */
2216 if (flags
& XATTR_CREATE
) {
2223 retval
= extattr_set_link(path
, attrnamespace
, attrname
, value
, size
);
2224 return (retval
< 0) ? -1 : 0;
2225 #elif defined(HAVE_ATTR_SET)
2226 int myflags
= ATTR_DONTFOLLOW
;
2227 char *attrname
= strchr(name
,'.') + 1;
2229 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2230 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2231 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2233 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2234 #elif defined(HAVE_ATTROPEN)
2236 int myflags
= O_RDWR
| AT_SYMLINK_NOFOLLOW
;
2238 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2239 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2240 attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2242 ret
= solaris_write_xattr(attrfd
, value
, size
);
2252 int sys_fsetxattr (int filedes
, const char *name
, const void *value
, size_t size
, int flags
)
2254 #if defined(HAVE_FSETXATTR)
2255 #ifndef XATTR_ADD_OPT
2256 return fsetxattr(filedes
, name
, value
, size
, flags
);
2259 return fsetxattr(filedes
, name
, value
, size
, 0, options
);
2261 #elif defined(HAVE_FSETEA)
2262 return fsetea(filedes
, name
, value
, size
, flags
);
2263 #elif defined(HAVE_EXTATTR_SET_FD)
2266 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2267 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2268 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2270 /* Check attribute existence */
2271 retval
= extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0);
2273 /* REPLACE attribute, that doesn't exist */
2274 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2278 /* Ignore other errors */
2281 /* CREATE attribute, that already exists */
2282 if (flags
& XATTR_CREATE
) {
2288 retval
= extattr_set_fd(filedes
, attrnamespace
, attrname
, value
, size
);
2289 return (retval
< 0) ? -1 : 0;
2290 #elif defined(HAVE_ATTR_SETF)
2292 char *attrname
= strchr(name
,'.') + 1;
2294 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2295 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2296 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2298 return attr_setf(filedes
, attrname
, (const char *)value
, size
, myflags
);
2299 #elif defined(HAVE_ATTROPEN)
2301 int myflags
= O_RDWR
| O_XATTR
;
2303 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2304 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2305 attrfd
= solaris_openat(filedes
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2307 ret
= solaris_write_xattr(attrfd
, value
, size
);
2317 /**************************************************************************
2318 helper functions for Solaris' EA support
2319 ****************************************************************************/
2320 #ifdef HAVE_ATTROPEN
2321 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
)
2325 if (fstat(attrfd
, &sbuf
) == -1) {
2330 /* This is to return the current size of the named extended attribute */
2332 return sbuf
.st_size
;
2335 /* check size and read xattr */
2336 if (sbuf
.st_size
> size
) {
2341 return read(attrfd
, value
, sbuf
.st_size
);
2344 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
)
2350 int newfd
= dup(attrdirfd
);
2351 /* CAUTION: The originating file descriptor should not be
2352 used again following the call to fdopendir().
2353 For that reason we dup() the file descriptor
2354 here to make things more clear. */
2355 dirp
= fdopendir(newfd
);
2357 while ((de
= readdir(dirp
))) {
2358 size_t listlen
= strlen(de
->d_name
);
2359 if (!strcmp(de
->d_name
, ".") || !strcmp(de
->d_name
, "..")) {
2360 /* we don't want "." and ".." here: */
2361 DEBUG(10,("skipped EA %s\n",de
->d_name
));
2366 /* return the current size of the list of extended attribute names*/
2369 /* check size and copy entrieѕ + nul into list. */
2370 if ((len
+ listlen
+ 1) > size
) {
2375 safe_strcpy(list
+ len
, de
->d_name
, listlen
);
2376 pstrcpy(list
+ len
, de
->d_name
);
2384 if (closedir(dirp
) == -1) {
2385 DEBUG(0,("closedir dirp failed: %s\n",strerror(errno
)));
2391 static int solaris_unlinkat(int attrdirfd
, const char *name
)
2393 if (unlinkat(attrdirfd
, name
, 0) == -1) {
2394 if (errno
== ENOENT
) {
2402 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
)
2404 int filedes
= attropen(path
, attrpath
, oflag
, mode
);
2405 if (filedes
== -1) {
2406 DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path
,attrpath
,strerror(errno
)));
2407 if (errno
== EINVAL
) {
2416 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
)
2418 int filedes
= openat(fildes
, path
, oflag
, mode
);
2419 if (filedes
== -1) {
2420 DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes
,path
,strerror(errno
)));
2421 if (errno
== EINVAL
) {
2430 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
)
2432 if ((ftruncate(attrfd
, 0) == 0) && (write(attrfd
, value
, size
) == size
)) {
2435 DEBUG(10,("solaris_write_xattr FAILED!\n"));
2439 #endif /*HAVE_ATTROPEN*/
2441 /****************************************************************************
2442 Return the major devicenumber for UNIX extensions.
2443 ****************************************************************************/
2445 uint32
unix_dev_major(SMB_DEV_T dev
)
2447 #if defined(HAVE_DEVICE_MAJOR_FN)
2448 return (uint32
)major(dev
);
2450 return (uint32
)(dev
>> 8);
2454 /****************************************************************************
2455 Return the minor devicenumber for UNIX extensions.
2456 ****************************************************************************/
2458 uint32
unix_dev_minor(SMB_DEV_T dev
)
2460 #if defined(HAVE_DEVICE_MINOR_FN)
2461 return (uint32
)minor(dev
);
2463 return (uint32
)(dev
& 0xff);
2467 #if defined(WITH_AIO)
2469 /*******************************************************************
2470 An aio_read wrapper that will deal with 64-bit sizes.
2471 ********************************************************************/
2473 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2475 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2476 return aio_read64(aiocb
);
2477 #elif defined(HAVE_AIO_READ)
2478 return aio_read(aiocb
);
2485 /*******************************************************************
2486 An aio_write wrapper that will deal with 64-bit sizes.
2487 ********************************************************************/
2489 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2491 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2492 return aio_write64(aiocb
);
2493 #elif defined(HAVE_AIO_WRITE)
2494 return aio_write(aiocb
);
2501 /*******************************************************************
2502 An aio_return wrapper that will deal with 64-bit sizes.
2503 ********************************************************************/
2505 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2507 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2508 return aio_return64(aiocb
);
2509 #elif defined(HAVE_AIO_RETURN)
2510 return aio_return(aiocb
);
2517 /*******************************************************************
2518 An aio_cancel wrapper that will deal with 64-bit sizes.
2519 ********************************************************************/
2521 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2523 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2524 return aio_cancel64(fd
, aiocb
);
2525 #elif defined(HAVE_AIO_CANCEL)
2526 return aio_cancel(fd
, aiocb
);
2533 /*******************************************************************
2534 An aio_error wrapper that will deal with 64-bit sizes.
2535 ********************************************************************/
2537 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2539 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2540 return aio_error64(aiocb
);
2541 #elif defined(HAVE_AIO_ERROR)
2542 return aio_error(aiocb
);
2549 /*******************************************************************
2550 An aio_fsync wrapper that will deal with 64-bit sizes.
2551 ********************************************************************/
2553 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2555 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2556 return aio_fsync64(op
, aiocb
);
2557 #elif defined(HAVE_AIO_FSYNC)
2558 return aio_fsync(op
, aiocb
);
2565 /*******************************************************************
2566 An aio_fsync wrapper that will deal with 64-bit sizes.
2567 ********************************************************************/
2569 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2571 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2572 return aio_suspend64(cblist
, n
, timeout
);
2573 #elif defined(HAVE_AIO_FSYNC)
2574 return aio_suspend(cblist
, n
, timeout
);
2580 #else /* !WITH_AIO */
2582 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2588 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2594 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2600 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2606 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2612 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2618 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2623 #endif /* WITH_AIO */
2625 int sys_getpeereid( int s
, uid_t
*uid
)
2627 #if defined(HAVE_PEERCRED)
2629 socklen_t cred_len
= sizeof(struct ucred
);
2632 ret
= getsockopt(s
, SOL_SOCKET
, SO_PEERCRED
, (void *)&cred
, &cred_len
);
2637 if (cred_len
!= sizeof(struct ucred
)) {