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
;
781 SMB_ASSERT(num_cap_vals
<= ARRAY_SIZE(cap_vals
));
783 if (num_cap_vals
== 0) {
788 cap_set_flag(cap
, CAP_EFFECTIVE
, num_cap_vals
, cap_vals
,
789 enable
? CAP_SET
: CAP_CLEAR
);
791 /* We never want to pass capabilities down to our children, so make
792 * sure they are not inherited.
794 cap_set_flag(cap
, CAP_INHERITABLE
, num_cap_vals
, cap_vals
, CAP_CLEAR
);
796 if (cap_set_proc(cap
) == -1) {
797 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
807 #endif /* HAVE_POSIX_CAPABILITIES */
809 /****************************************************************************
810 Gain the oplock capability from the kernel if possible.
811 ****************************************************************************/
813 void set_effective_capability(enum smbd_capability capability
)
815 #if defined(HAVE_POSIX_CAPABILITIES)
816 set_process_capability(capability
, True
);
817 #endif /* HAVE_POSIX_CAPABILITIES */
820 void drop_effective_capability(enum smbd_capability capability
)
822 #if defined(HAVE_POSIX_CAPABILITIES)
823 set_process_capability(capability
, False
);
824 #endif /* HAVE_POSIX_CAPABILITIES */
827 /**************************************************************************
828 Wrapper for random().
829 ****************************************************************************/
831 long sys_random(void)
833 #if defined(HAVE_RANDOM)
834 return (long)random();
835 #elif defined(HAVE_RAND)
838 DEBUG(0,("Error - no random function available !\n"));
843 /**************************************************************************
844 Wrapper for srandom().
845 ****************************************************************************/
847 void sys_srandom(unsigned int seed
)
849 #if defined(HAVE_SRANDOM)
851 #elif defined(HAVE_SRAND)
854 DEBUG(0,("Error - no srandom function available !\n"));
859 /**************************************************************************
860 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
861 ****************************************************************************/
865 #if defined(SYSCONF_SC_NGROUPS_MAX)
866 int ret
= sysconf(_SC_NGROUPS_MAX
);
867 return (ret
== -1) ? NGROUPS_MAX
: ret
;
873 /**************************************************************************
874 Wrapper for getgroups. Deals with broken (int) case.
875 ****************************************************************************/
877 int sys_getgroups(int setlen
, gid_t
*gidset
)
879 #if !defined(HAVE_BROKEN_GETGROUPS)
880 return getgroups(setlen
, gidset
);
888 return getgroups(setlen
, &gid
);
892 * Broken case. We need to allocate a
893 * GID_T array of size setlen.
902 setlen
= groups_max();
904 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
905 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
909 if((ngroups
= getgroups(setlen
, group_list
)) < 0) {
910 int saved_errno
= errno
;
911 SAFE_FREE(group_list
);
916 for(i
= 0; i
< ngroups
; i
++)
917 gidset
[i
] = (gid_t
)group_list
[i
];
919 SAFE_FREE(group_list
);
921 #endif /* HAVE_BROKEN_GETGROUPS */
925 /**************************************************************************
926 Wrapper for setgroups. Deals with broken (int) case. Automatically used
927 if we have broken getgroups.
928 ****************************************************************************/
930 int sys_setgroups(int setlen
, gid_t
*gidset
)
932 #if !defined(HAVE_SETGROUPS)
935 #endif /* HAVE_SETGROUPS */
937 #if !defined(HAVE_BROKEN_GETGROUPS)
938 return setgroups(setlen
, gidset
);
947 if (setlen
< 0 || setlen
> groups_max()) {
953 * Broken case. We need to allocate a
954 * GID_T array of size setlen.
957 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
958 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
962 for(i
= 0; i
< setlen
; i
++)
963 group_list
[i
] = (GID_T
) gidset
[i
];
965 if(setgroups(setlen
, group_list
) != 0) {
966 int saved_errno
= errno
;
967 SAFE_FREE(group_list
);
972 SAFE_FREE(group_list
);
974 #endif /* HAVE_BROKEN_GETGROUPS */
977 /**************************************************************************
978 Wrappers for setpwent(), getpwent() and endpwent()
979 ****************************************************************************/
981 void sys_setpwent(void)
986 struct passwd
*sys_getpwent(void)
991 void sys_endpwent(void)
996 /**************************************************************************
997 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
998 ****************************************************************************/
1000 #ifdef ENABLE_BUILD_FARM_HACKS
1003 * In the build farm we want to be able to join machines to the domain. As we
1004 * don't have root access, we need to bypass direct access to /etc/passwd
1005 * after a user has been created via samr. Fake those users.
1008 static struct passwd
*fake_pwd
;
1009 static int num_fake_pwd
;
1011 struct passwd
*sys_getpwnam(const char *name
)
1015 for (i
=0; i
<num_fake_pwd
; i
++) {
1016 if (strcmp(fake_pwd
[i
].pw_name
, name
) == 0) {
1017 DEBUG(10, ("Returning fake user %s\n", name
));
1018 return &fake_pwd
[i
];
1022 return getpwnam(name
);
1025 struct passwd
*sys_getpwuid(uid_t uid
)
1029 for (i
=0; i
<num_fake_pwd
; i
++) {
1030 if (fake_pwd
[i
].pw_uid
== uid
) {
1031 DEBUG(10, ("Returning fake user %s\n",
1032 fake_pwd
[i
].pw_name
));
1033 return &fake_pwd
[i
];
1037 return getpwuid(uid
);
1040 void faked_create_user(const char *name
)
1044 struct passwd new_pwd
;
1046 for (i
=0; i
<10; i
++) {
1047 generate_random_buffer((unsigned char *)&uid
,
1049 if (getpwuid(uid
) == NULL
) {
1055 /* Weird. No free uid found... */
1059 new_pwd
.pw_name
= SMB_STRDUP(name
);
1060 new_pwd
.pw_passwd
= SMB_STRDUP("x");
1061 new_pwd
.pw_uid
= uid
;
1062 new_pwd
.pw_gid
= 100;
1063 new_pwd
.pw_gecos
= SMB_STRDUP("faked user");
1064 new_pwd
.pw_dir
= SMB_STRDUP("/nodir");
1065 new_pwd
.pw_shell
= SMB_STRDUP("/bin/false");
1067 ADD_TO_ARRAY(NULL
, struct passwd
, new_pwd
, &fake_pwd
,
1070 DEBUG(10, ("Added fake user %s, have %d fake users\n",
1071 name
, num_fake_pwd
));
1076 struct passwd
*sys_getpwnam(const char *name
)
1078 return getpwnam(name
);
1081 struct passwd
*sys_getpwuid(uid_t uid
)
1083 return getpwuid(uid
);
1088 struct group
*sys_getgrnam(const char *name
)
1090 return getgrnam(name
);
1093 struct group
*sys_getgrgid(gid_t gid
)
1095 return getgrgid(gid
);
1098 #if 0 /* NOT CURRENTLY USED - JRA */
1099 /**************************************************************************
1100 The following are the UNICODE versions of *all* system interface functions
1101 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
1102 which currently are left as ascii as they are not used other than in name
1104 ****************************************************************************/
1106 /**************************************************************************
1107 Wide stat. Just narrow and call sys_xxx.
1108 ****************************************************************************/
1110 int wsys_stat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
1113 return sys_stat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
1116 /**************************************************************************
1117 Wide lstat. Just narrow and call sys_xxx.
1118 ****************************************************************************/
1120 int wsys_lstat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
1123 return sys_lstat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
1126 /**************************************************************************
1127 Wide creat. Just narrow and call sys_xxx.
1128 ****************************************************************************/
1130 int wsys_creat(const smb_ucs2_t
*wfname
, mode_t mode
)
1133 return sys_creat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), mode
);
1136 /**************************************************************************
1137 Wide open. Just narrow and call sys_xxx.
1138 ****************************************************************************/
1140 int wsys_open(const smb_ucs2_t
*wfname
, int oflag
, mode_t mode
)
1143 return sys_open(unicode_to_unix(fname
,wfname
,sizeof(fname
)), oflag
, mode
);
1146 /**************************************************************************
1147 Wide fopen. Just narrow and call sys_xxx.
1148 ****************************************************************************/
1150 FILE *wsys_fopen(const smb_ucs2_t
*wfname
, const char *type
)
1153 return sys_fopen(unicode_to_unix(fname
,wfname
,sizeof(fname
)), type
);
1156 /**************************************************************************
1157 Wide opendir. Just narrow and call sys_xxx.
1158 ****************************************************************************/
1160 SMB_STRUCT_DIR
*wsys_opendir(const smb_ucs2_t
*wfname
)
1163 return opendir(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
1166 /**************************************************************************
1167 Wide readdir. Return a structure pointer containing a wide filename.
1168 ****************************************************************************/
1170 SMB_STRUCT_WDIRENT
*wsys_readdir(SMB_STRUCT_DIR
*dirp
)
1172 static SMB_STRUCT_WDIRENT retval
;
1173 SMB_STRUCT_DIRENT
*dirval
= sys_readdir(dirp
);
1179 * The only POSIX defined member of this struct is d_name.
1182 unix_to_unicode(retval
.d_name
,dirval
->d_name
,sizeof(retval
.d_name
));
1187 /**************************************************************************
1188 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
1189 ****************************************************************************/
1191 smb_ucs2_t
*wsys_getwd(smb_ucs2_t
*s
)
1194 char *p
= sys_getwd(fname
);
1199 return unix_to_unicode(s
, p
, sizeof(wpstring
));
1202 /**************************************************************************
1203 Wide chown. Just narrow and call sys_xxx.
1204 ****************************************************************************/
1206 int wsys_chown(const smb_ucs2_t
*wfname
, uid_t uid
, gid_t gid
)
1209 return chown(unicode_to_unix(fname
,wfname
,sizeof(fname
)), uid
, gid
);
1212 /**************************************************************************
1213 Wide chroot. Just narrow and call sys_xxx.
1214 ****************************************************************************/
1216 int wsys_chroot(const smb_ucs2_t
*wfname
)
1219 return chroot(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
1222 /**************************************************************************
1223 Wide getpwnam. Return a structure pointer containing wide names.
1224 ****************************************************************************/
1226 SMB_STRUCT_WPASSWD
*wsys_getpwnam(const smb_ucs2_t
*wname
)
1228 static SMB_STRUCT_WPASSWD retval
;
1230 struct passwd
*pwret
= sys_getpwnam(unicode_to_unix(name
,wname
,sizeof(name
)));
1235 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
1236 retval
.pw_passwd
= pwret
->pw_passwd
;
1237 retval
.pw_uid
= pwret
->pw_uid
;
1238 retval
.pw_gid
= pwret
->pw_gid
;
1239 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
1240 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
1241 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
1246 /**************************************************************************
1247 Wide getpwuid. Return a structure pointer containing wide names.
1248 ****************************************************************************/
1250 SMB_STRUCT_WPASSWD
*wsys_getpwuid(uid_t uid
)
1252 static SMB_STRUCT_WPASSWD retval
;
1253 struct passwd
*pwret
= sys_getpwuid(uid
);
1258 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
1259 retval
.pw_passwd
= pwret
->pw_passwd
;
1260 retval
.pw_uid
= pwret
->pw_uid
;
1261 retval
.pw_gid
= pwret
->pw_gid
;
1262 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
1263 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
1264 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
1268 #endif /* NOT CURRENTLY USED - JRA */
1270 /**************************************************************************
1271 Extract a command into an arg list. Uses a static pstring for storage.
1272 Caller frees returned arg list (which contains pointers into the static pstring).
1273 ****************************************************************************/
1275 static char **extract_args(const char *command
)
1277 static pstring trunc_cmd
;
1283 pstrcpy(trunc_cmd
, command
);
1285 if(!(ptr
= strtok(trunc_cmd
, " \t"))) {
1294 for( argcl
= 1; ptr
; ptr
= strtok(NULL
, " \t"))
1297 if((argl
= (char **)SMB_MALLOC((argcl
+ 1) * sizeof(char *))) == NULL
)
1301 * Now do the extraction.
1304 pstrcpy(trunc_cmd
, command
);
1306 ptr
= strtok(trunc_cmd
, " \t");
1310 while((ptr
= strtok(NULL
, " \t")) != NULL
)
1317 /**************************************************************************
1318 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1319 a sys_getpid() that only does a system call *once*.
1320 ****************************************************************************/
1322 static pid_t mypid
= (pid_t
)-1;
1324 pid_t
sys_fork(void)
1326 pid_t forkret
= fork();
1328 if (forkret
== (pid_t
)0) /* Child - reset mypid so sys_getpid does a system call. */
1334 /**************************************************************************
1335 Wrapper for getpid. Ensures we only do a system call *once*.
1336 ****************************************************************************/
1338 pid_t
sys_getpid(void)
1340 if (mypid
== (pid_t
)-1)
1346 /**************************************************************************
1347 Wrapper for popen. Safer as it doesn't search a path.
1348 Modified from the glibc sources.
1349 modified by tridge to return a file descriptor. We must kick our FILE* habit
1350 ****************************************************************************/
1352 typedef struct _popen_list
1356 struct _popen_list
*next
;
1359 static popen_list
*popen_chain
;
1361 int sys_popen(const char *command
)
1363 int parent_end
, child_end
;
1365 popen_list
*entry
= NULL
;
1368 if (pipe(pipe_fds
) < 0)
1371 parent_end
= pipe_fds
[0];
1372 child_end
= pipe_fds
[1];
1379 if((entry
= SMB_MALLOC_P(popen_list
)) == NULL
)
1382 ZERO_STRUCTP(entry
);
1385 * Extract the command and args into a NULL terminated array.
1388 if(!(argl
= extract_args(command
)))
1391 entry
->child_pid
= sys_fork();
1393 if (entry
->child_pid
== -1) {
1397 if (entry
->child_pid
== 0) {
1403 int child_std_end
= STDOUT_FILENO
;
1407 if (child_end
!= child_std_end
) {
1408 dup2 (child_end
, child_std_end
);
1413 * POSIX.2: "popen() shall ensure that any streams from previous
1414 * popen() calls that remain open in the parent process are closed
1415 * in the new child process."
1418 for (p
= popen_chain
; p
; p
= p
->next
)
1421 execv(argl
[0], argl
);
1432 /* Link into popen_chain. */
1433 entry
->next
= popen_chain
;
1434 popen_chain
= entry
;
1435 entry
->fd
= parent_end
;
1448 /**************************************************************************
1449 Wrapper for pclose. Modified from the glibc sources.
1450 ****************************************************************************/
1452 int sys_pclose(int fd
)
1455 popen_list
**ptr
= &popen_chain
;
1456 popen_list
*entry
= NULL
;
1460 /* Unlink from popen_chain. */
1461 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
) {
1462 if ((*ptr
)->fd
== fd
) {
1464 *ptr
= (*ptr
)->next
;
1470 if (status
< 0 || close(entry
->fd
) < 0)
1474 * As Samba is catching and eating child process
1475 * exits we don't really care about the child exit
1476 * code, a -1 with errno = ECHILD will do fine for us.
1480 wait_pid
= sys_waitpid (entry
->child_pid
, &wstatus
, 0);
1481 } while (wait_pid
== -1 && errno
== EINTR
);
1490 /**************************************************************************
1491 Wrappers for dlopen, dlsym, dlclose.
1492 ****************************************************************************/
1494 void *sys_dlopen(const char *name
, int flags
)
1496 #if defined(HAVE_DLOPEN)
1497 return dlopen(name
, flags
);
1503 void *sys_dlsym(void *handle
, const char *symbol
)
1505 #if defined(HAVE_DLSYM)
1506 return dlsym(handle
, symbol
);
1512 int sys_dlclose (void *handle
)
1514 #if defined(HAVE_DLCLOSE)
1515 return dlclose(handle
);
1521 const char *sys_dlerror(void)
1523 #if defined(HAVE_DLERROR)
1530 int sys_dup2(int oldfd
, int newfd
)
1532 #if defined(HAVE_DUP2)
1533 return dup2(oldfd
, newfd
);
1540 /**************************************************************************
1541 Wrapper for Admin Logs.
1542 ****************************************************************************/
1544 void sys_adminlog(int priority
, const char *format_str
, ...)
1548 char *msgbuf
= NULL
;
1550 va_start( ap
, format_str
);
1551 ret
= vasprintf( &msgbuf
, format_str
, ap
);
1557 #if defined(HAVE_SYSLOG)
1558 syslog( priority
, "%s", msgbuf
);
1560 DEBUG(0,("%s", msgbuf
));
1565 /******** Solaris EA helper function prototypes ********/
1566 #ifdef HAVE_ATTROPEN
1567 #define SOLARIS_ATTRMODE S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP
1568 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
);
1569 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
);
1570 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
);
1571 static int solaris_unlinkat(int attrdirfd
, const char *name
);
1572 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
);
1573 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
);
1576 /**************************************************************************
1577 Wrappers for extented attribute calls. Based on the Linux package with
1578 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1579 ****************************************************************************/
1581 ssize_t
sys_getxattr (const char *path
, const char *name
, void *value
, size_t size
)
1583 #if defined(HAVE_GETXATTR)
1584 #ifndef XATTR_ADD_OPT
1585 return getxattr(path
, name
, value
, size
);
1588 return getxattr(path
, name
, value
, size
, 0, options
);
1590 #elif defined(HAVE_GETEA)
1591 return getea(path
, name
, value
, size
);
1592 #elif defined(HAVE_EXTATTR_GET_FILE)
1595 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1596 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1597 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1599 * The BSD implementation has a nasty habit of silently truncating
1600 * the returned value to the size of the buffer, so we have to check
1601 * that the buffer is large enough to fit the returned value.
1603 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1608 if((retval
=extattr_get_file(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1612 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno
)));
1614 #elif defined(HAVE_ATTR_GET)
1615 int retval
, flags
= 0;
1616 int valuelength
= (int)size
;
1617 char *attrname
= strchr(name
,'.') + 1;
1619 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1621 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1623 return retval
? retval
: valuelength
;
1624 #elif defined(HAVE_ATTROPEN)
1626 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
, 0);
1628 ret
= solaris_read_xattr(attrfd
, value
, size
);
1638 ssize_t
sys_lgetxattr (const char *path
, const char *name
, void *value
, size_t size
)
1640 #if defined(HAVE_LGETXATTR)
1641 return lgetxattr(path
, name
, value
, size
);
1642 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1643 int options
= XATTR_NOFOLLOW
;
1644 return getxattr(path
, name
, value
, size
, 0, options
);
1645 #elif defined(HAVE_LGETEA)
1646 return lgetea(path
, name
, value
, size
);
1647 #elif defined(HAVE_EXTATTR_GET_LINK)
1650 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1651 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1652 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1654 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1659 if((retval
=extattr_get_link(path
, attrnamespace
, attrname
, value
, size
)) >= 0)
1663 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno
)));
1665 #elif defined(HAVE_ATTR_GET)
1666 int retval
, flags
= ATTR_DONTFOLLOW
;
1667 int valuelength
= (int)size
;
1668 char *attrname
= strchr(name
,'.') + 1;
1670 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1672 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1674 return retval
? retval
: valuelength
;
1675 #elif defined(HAVE_ATTROPEN)
1677 int attrfd
= solaris_attropen(path
, name
, O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1679 ret
= solaris_read_xattr(attrfd
, value
, size
);
1689 ssize_t
sys_fgetxattr (int filedes
, const char *name
, void *value
, size_t size
)
1691 #if defined(HAVE_FGETXATTR)
1692 #ifndef XATTR_ADD_OPT
1693 return fgetxattr(filedes
, name
, value
, size
);
1696 return fgetxattr(filedes
, name
, value
, size
, 0, options
);
1698 #elif defined(HAVE_FGETEA)
1699 return fgetea(filedes
, name
, value
, size
);
1700 #elif defined(HAVE_EXTATTR_GET_FD)
1703 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
1704 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
1705 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
1707 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0)) >= 0) {
1712 if((retval
=extattr_get_fd(filedes
, attrnamespace
, attrname
, value
, size
)) >= 0)
1716 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno
)));
1718 #elif defined(HAVE_ATTR_GETF)
1719 int retval
, flags
= 0;
1720 int valuelength
= (int)size
;
1721 char *attrname
= strchr(name
,'.') + 1;
1723 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1725 retval
= attr_getf(filedes
, attrname
, (char *)value
, &valuelength
, flags
);
1727 return retval
? retval
: valuelength
;
1728 #elif defined(HAVE_ATTROPEN)
1730 int attrfd
= solaris_openat(filedes
, name
, O_RDONLY
|O_XATTR
, 0);
1732 ret
= solaris_read_xattr(attrfd
, value
, size
);
1742 #if defined(HAVE_EXTATTR_LIST_FILE)
1744 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1752 { EXTATTR_NAMESPACE_SYSTEM
, EXTATTR_PREFIX("system.") },
1753 { EXTATTR_NAMESPACE_USER
, EXTATTR_PREFIX("user.") },
1761 static ssize_t
bsd_attr_list (int type
, extattr_arg arg
, char *list
, size_t size
)
1763 ssize_t list_size
, total_size
= 0;
1766 /* Iterate through extattr(2) namespaces */
1767 for(t
= 0; t
< (sizeof(extattr
)/sizeof(extattr
[0])); t
++) {
1769 #if defined(HAVE_EXTATTR_LIST_FILE)
1771 list_size
= extattr_list_file(arg
.path
, extattr
[t
].space
, list
, size
);
1774 #if defined(HAVE_EXTATTR_LIST_LINK)
1776 list_size
= extattr_list_link(arg
.path
, extattr
[t
].space
, list
, size
);
1779 #if defined(HAVE_EXTATTR_LIST_FD)
1781 list_size
= extattr_list_fd(arg
.filedes
, extattr
[t
].space
, list
, size
);
1788 /* Some error happend. Errno should be set by the previous call */
1794 /* XXX: Call with an empty buffer may be used to calculate
1795 necessary buffer size. Unfortunately, we can't say, how
1796 many attributes were returned, so here is the potential
1797 problem with the emulation.
1800 /* Take the worse case of one char attribute names -
1801 two bytes per name plus one more for sanity.
1803 total_size
+= list_size
+ (list_size
/2 + 1)*extattr
[t
].len
;
1806 /* Count necessary offset to fit namespace prefixes */
1808 for(i
= 0; i
< list_size
; i
+= list
[i
] + 1)
1809 len
+= extattr
[t
].len
;
1811 total_size
+= list_size
+ len
;
1812 /* Buffer is too small to fit the results */
1813 if(total_size
> size
) {
1817 /* Shift results back, so we can prepend prefixes */
1818 buf
= memmove(list
+ len
, list
, list_size
);
1820 for(i
= 0; i
< list_size
; i
+= len
+ 1) {
1822 strncpy(list
, extattr
[t
].name
, extattr
[t
].len
+ 1);
1823 list
+= extattr
[t
].len
;
1824 strncpy(list
, buf
+ i
+ 1, len
);
1835 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1836 static char attr_buffer
[ATTR_MAX_VALUELEN
];
1838 static ssize_t
irix_attr_list(const char *path
, int filedes
, char *list
, size_t size
, int flags
)
1840 int retval
= 0, index
;
1841 attrlist_cursor_t
*cursor
= 0;
1843 attrlist_t
* al
= (attrlist_t
*)attr_buffer
;
1845 size_t ent_size
, left
= size
;
1850 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1852 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1854 for (index
= 0; index
< al
->al_count
; index
++) {
1855 ae
= ATTR_ENTRY(attr_buffer
, index
);
1856 ent_size
= strlen(ae
->a_name
) + sizeof("user.");
1857 if (left
>= ent_size
) {
1858 strncpy(bp
, "user.", sizeof("user."));
1859 strncat(bp
, ae
->a_name
, ent_size
- sizeof("user."));
1867 total_size
+= ent_size
;
1869 if (al
->al_more
== 0) break;
1876 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1878 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1880 for (index
= 0; index
< al
->al_count
; index
++) {
1881 ae
= ATTR_ENTRY(attr_buffer
, index
);
1882 ent_size
= strlen(ae
->a_name
) + sizeof("system.");
1883 if (left
>= ent_size
) {
1884 strncpy(bp
, "system.", sizeof("system."));
1885 strncat(bp
, ae
->a_name
, ent_size
- sizeof("system."));
1893 total_size
+= ent_size
;
1895 if (al
->al_more
== 0) break;
1898 return (ssize_t
)(retval
? retval
: total_size
);
1903 ssize_t
sys_listxattr (const char *path
, char *list
, size_t size
)
1905 #if defined(HAVE_LISTXATTR)
1906 #ifndef XATTR_ADD_OPT
1907 return listxattr(path
, list
, size
);
1910 return listxattr(path
, list
, size
, options
);
1912 #elif defined(HAVE_LISTEA)
1913 return listea(path
, list
, size
);
1914 #elif defined(HAVE_EXTATTR_LIST_FILE)
1917 return bsd_attr_list(0, arg
, list
, size
);
1918 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1919 return irix_attr_list(path
, 0, list
, size
, 0);
1920 #elif defined(HAVE_ATTROPEN)
1922 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
1923 if (attrdirfd
>= 0) {
1924 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1934 ssize_t
sys_llistxattr (const char *path
, char *list
, size_t size
)
1936 #if defined(HAVE_LLISTXATTR)
1937 return llistxattr(path
, list
, size
);
1938 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1939 int options
= XATTR_NOFOLLOW
;
1940 return listxattr(path
, list
, size
, options
);
1941 #elif defined(HAVE_LLISTEA)
1942 return llistea(path
, list
, size
);
1943 #elif defined(HAVE_EXTATTR_LIST_LINK)
1946 return bsd_attr_list(1, arg
, list
, size
);
1947 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1948 return irix_attr_list(path
, 0, list
, size
, ATTR_DONTFOLLOW
);
1949 #elif defined(HAVE_ATTROPEN)
1951 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
1952 if (attrdirfd
>= 0) {
1953 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1963 ssize_t
sys_flistxattr (int filedes
, char *list
, size_t size
)
1965 #if defined(HAVE_FLISTXATTR)
1966 #ifndef XATTR_ADD_OPT
1967 return flistxattr(filedes
, list
, size
);
1970 return flistxattr(filedes
, list
, size
, options
);
1972 #elif defined(HAVE_FLISTEA)
1973 return flistea(filedes
, list
, size
);
1974 #elif defined(HAVE_EXTATTR_LIST_FD)
1976 arg
.filedes
= filedes
;
1977 return bsd_attr_list(2, arg
, list
, size
);
1978 #elif defined(HAVE_ATTR_LISTF)
1979 return irix_attr_list(NULL
, filedes
, list
, size
, 0);
1980 #elif defined(HAVE_ATTROPEN)
1982 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
1983 if (attrdirfd
>= 0) {
1984 ret
= solaris_list_xattr(attrdirfd
, list
, size
);
1994 int sys_removexattr (const char *path
, const char *name
)
1996 #if defined(HAVE_REMOVEXATTR)
1997 #ifndef XATTR_ADD_OPT
1998 return removexattr(path
, name
);
2001 return removexattr(path
, name
, options
);
2003 #elif defined(HAVE_REMOVEEA)
2004 return removeea(path
, name
);
2005 #elif defined(HAVE_EXTATTR_DELETE_FILE)
2007 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2008 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2009 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2011 return extattr_delete_file(path
, attrnamespace
, attrname
);
2012 #elif defined(HAVE_ATTR_REMOVE)
2014 char *attrname
= strchr(name
,'.') + 1;
2016 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2018 return attr_remove(path
, attrname
, flags
);
2019 #elif defined(HAVE_ATTROPEN)
2021 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
, 0);
2022 if (attrdirfd
>= 0) {
2023 ret
= solaris_unlinkat(attrdirfd
, name
);
2033 int sys_lremovexattr (const char *path
, const char *name
)
2035 #if defined(HAVE_LREMOVEXATTR)
2036 return lremovexattr(path
, name
);
2037 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
2038 int options
= XATTR_NOFOLLOW
;
2039 return removexattr(path
, name
, options
);
2040 #elif defined(HAVE_LREMOVEEA)
2041 return lremoveea(path
, name
);
2042 #elif defined(HAVE_EXTATTR_DELETE_LINK)
2044 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2045 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2046 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2048 return extattr_delete_link(path
, attrnamespace
, attrname
);
2049 #elif defined(HAVE_ATTR_REMOVE)
2050 int flags
= ATTR_DONTFOLLOW
;
2051 char *attrname
= strchr(name
,'.') + 1;
2053 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2055 return attr_remove(path
, attrname
, flags
);
2056 #elif defined(HAVE_ATTROPEN)
2058 int attrdirfd
= solaris_attropen(path
, ".", O_RDONLY
|AT_SYMLINK_NOFOLLOW
, 0);
2059 if (attrdirfd
>= 0) {
2060 ret
= solaris_unlinkat(attrdirfd
, name
);
2070 int sys_fremovexattr (int filedes
, const char *name
)
2072 #if defined(HAVE_FREMOVEXATTR)
2073 #ifndef XATTR_ADD_OPT
2074 return fremovexattr(filedes
, name
);
2077 return fremovexattr(filedes
, name
, options
);
2079 #elif defined(HAVE_FREMOVEEA)
2080 return fremoveea(filedes
, name
);
2081 #elif defined(HAVE_EXTATTR_DELETE_FD)
2083 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2084 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2085 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2087 return extattr_delete_fd(filedes
, attrnamespace
, attrname
);
2088 #elif defined(HAVE_ATTR_REMOVEF)
2090 char *attrname
= strchr(name
,'.') + 1;
2092 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
2094 return attr_removef(filedes
, attrname
, flags
);
2095 #elif defined(HAVE_ATTROPEN)
2097 int attrdirfd
= solaris_openat(filedes
, ".", O_RDONLY
|O_XATTR
, 0);
2098 if (attrdirfd
>= 0) {
2099 ret
= solaris_unlinkat(attrdirfd
, name
);
2109 #if !defined(HAVE_SETXATTR)
2110 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
2111 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
2114 int sys_setxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2116 #if defined(HAVE_SETXATTR)
2117 #ifndef XATTR_ADD_OPT
2118 return setxattr(path
, name
, value
, size
, flags
);
2121 return setxattr(path
, name
, value
, size
, 0, options
);
2123 #elif defined(HAVE_SETEA)
2124 return setea(path
, name
, value
, size
, flags
);
2125 #elif defined(HAVE_EXTATTR_SET_FILE)
2128 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2129 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2130 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2132 /* Check attribute existence */
2133 retval
= extattr_get_file(path
, attrnamespace
, attrname
, NULL
, 0);
2135 /* REPLACE attribute, that doesn't exist */
2136 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2140 /* Ignore other errors */
2143 /* CREATE attribute, that already exists */
2144 if (flags
& XATTR_CREATE
) {
2150 retval
= extattr_set_file(path
, attrnamespace
, attrname
, value
, size
);
2151 return (retval
< 0) ? -1 : 0;
2152 #elif defined(HAVE_ATTR_SET)
2154 char *attrname
= strchr(name
,'.') + 1;
2156 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2157 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2158 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2160 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2161 #elif defined(HAVE_ATTROPEN)
2163 int myflags
= O_RDWR
;
2164 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2165 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2166 int attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2168 ret
= solaris_write_xattr(attrfd
, value
, size
);
2178 int sys_lsetxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
2180 #if defined(HAVE_LSETXATTR)
2181 return lsetxattr(path
, name
, value
, size
, flags
);
2182 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2183 int options
= XATTR_NOFOLLOW
;
2184 return setxattr(path
, name
, value
, size
, 0, options
);
2185 #elif defined(LSETEA)
2186 return lsetea(path
, name
, value
, size
, flags
);
2187 #elif defined(HAVE_EXTATTR_SET_LINK)
2190 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2191 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2192 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2194 /* Check attribute existence */
2195 retval
= extattr_get_link(path
, attrnamespace
, attrname
, NULL
, 0);
2197 /* REPLACE attribute, that doesn't exist */
2198 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2202 /* Ignore other errors */
2205 /* CREATE attribute, that already exists */
2206 if (flags
& XATTR_CREATE
) {
2213 retval
= extattr_set_link(path
, attrnamespace
, attrname
, value
, size
);
2214 return (retval
< 0) ? -1 : 0;
2215 #elif defined(HAVE_ATTR_SET)
2216 int myflags
= ATTR_DONTFOLLOW
;
2217 char *attrname
= strchr(name
,'.') + 1;
2219 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2220 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2221 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2223 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
2224 #elif defined(HAVE_ATTROPEN)
2226 int myflags
= O_RDWR
| AT_SYMLINK_NOFOLLOW
;
2227 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2228 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2229 int attrfd
= solaris_attropen(path
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2231 ret
= solaris_write_xattr(attrfd
, value
, size
);
2241 int sys_fsetxattr (int filedes
, const char *name
, const void *value
, size_t size
, int flags
)
2243 #if defined(HAVE_FSETXATTR)
2244 #ifndef XATTR_ADD_OPT
2245 return fsetxattr(filedes
, name
, value
, size
, flags
);
2248 return fsetxattr(filedes
, name
, value
, size
, 0, options
);
2250 #elif defined(HAVE_FSETEA)
2251 return fsetea(filedes
, name
, value
, size
, flags
);
2252 #elif defined(HAVE_EXTATTR_SET_FD)
2255 int attrnamespace
= (strncmp(name
, "system", 6) == 0) ?
2256 EXTATTR_NAMESPACE_SYSTEM
: EXTATTR_NAMESPACE_USER
;
2257 const char *attrname
= ((s
=strchr_m(name
, '.')) == NULL
) ? name
: s
+ 1;
2259 /* Check attribute existence */
2260 retval
= extattr_get_fd(filedes
, attrnamespace
, attrname
, NULL
, 0);
2262 /* REPLACE attribute, that doesn't exist */
2263 if (flags
& XATTR_REPLACE
&& errno
== ENOATTR
) {
2267 /* Ignore other errors */
2270 /* CREATE attribute, that already exists */
2271 if (flags
& XATTR_CREATE
) {
2277 retval
= extattr_set_fd(filedes
, attrnamespace
, attrname
, value
, size
);
2278 return (retval
< 0) ? -1 : 0;
2279 #elif defined(HAVE_ATTR_SETF)
2281 char *attrname
= strchr(name
,'.') + 1;
2283 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
2284 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
2285 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
2287 return attr_setf(filedes
, attrname
, (const char *)value
, size
, myflags
);
2288 #elif defined(HAVE_ATTROPEN)
2290 int myflags
= O_RDWR
| O_XATTR
;
2291 if (flags
& XATTR_CREATE
) myflags
|= O_EXCL
;
2292 if (!(flags
& XATTR_REPLACE
)) myflags
|= O_CREAT
;
2293 int attrfd
= solaris_openat(filedes
, name
, myflags
, (mode_t
) SOLARIS_ATTRMODE
);
2295 ret
= solaris_write_xattr(attrfd
, value
, size
);
2305 /**************************************************************************
2306 helper functions for Solaris' EA support
2307 ****************************************************************************/
2308 #ifdef HAVE_ATTROPEN
2309 static ssize_t
solaris_read_xattr(int attrfd
, void *value
, size_t size
)
2313 if (fstat(attrfd
, &sbuf
) == -1) {
2318 /* This is to return the current size of the named extended attribute */
2320 return sbuf
.st_size
;
2323 /* check size and read xattr */
2324 if (sbuf
.st_size
> size
) {
2329 return read(attrfd
, value
, sbuf
.st_size
);
2332 static ssize_t
solaris_list_xattr(int attrdirfd
, char *list
, size_t size
)
2338 int newfd
= dup(attrdirfd
);
2339 /* CAUTION: The originating file descriptor should not be
2340 used again following the call to fdopendir().
2341 For that reason we dup() the file descriptor
2342 here to make things more clear. */
2343 dirp
= fdopendir(newfd
);
2345 while ((de
= readdir(dirp
))) {
2346 size_t listlen
= strlen(de
->d_name
);
2347 if (!strcmp(de
->d_name
, ".") || !strcmp(de
->d_name
, "..")) {
2348 /* we don't want "." and ".." here: */
2349 DEBUG(10,("skipped EA %s\n",de
->d_name
));
2354 /* return the current size of the list of extended attribute names*/
2357 /* check size and copy entrieѕ + nul into list. */
2358 if ((len
+ listlen
+ 1) > size
) {
2363 safe_strcpy(list
+ len
, de
->d_name
, listlen
);
2364 pstrcpy(list
+ len
, de
->d_name
);
2372 if (closedir(dirp
) == -1) {
2373 DEBUG(0,("closedir dirp failed: %s\n",strerror(errno
)));
2379 static int solaris_unlinkat(int attrdirfd
, const char *name
)
2381 if (unlinkat(attrdirfd
, name
, 0) == -1) {
2382 if (errno
== ENOENT
) {
2390 static int solaris_attropen(const char *path
, const char *attrpath
, int oflag
, mode_t mode
)
2392 int filedes
= attropen(path
, attrpath
, oflag
, mode
);
2393 if (filedes
== -1) {
2394 DEBUG(10,("attropen FAILED: path: %s, name: %s, errno: %s\n",path
,attrpath
,strerror(errno
)));
2395 if (errno
== EINVAL
) {
2404 static int solaris_openat(int fildes
, const char *path
, int oflag
, mode_t mode
)
2406 int filedes
= openat(fildes
, path
, oflag
, mode
);
2407 if (filedes
== -1) {
2408 DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes
,path
,strerror(errno
)));
2409 if (errno
== EINVAL
) {
2418 static int solaris_write_xattr(int attrfd
, const char *value
, size_t size
)
2420 if ((ftruncate(attrfd
, 0) == 0) && (write(attrfd
, value
, size
) == size
)) {
2423 DEBUG(10,("solaris_write_xattr FAILED!\n"));
2427 #endif /*HAVE_ATTROPEN*/
2429 /****************************************************************************
2430 Return the major devicenumber for UNIX extensions.
2431 ****************************************************************************/
2433 uint32
unix_dev_major(SMB_DEV_T dev
)
2435 #if defined(HAVE_DEVICE_MAJOR_FN)
2436 return (uint32
)major(dev
);
2438 return (uint32
)(dev
>> 8);
2442 /****************************************************************************
2443 Return the minor devicenumber for UNIX extensions.
2444 ****************************************************************************/
2446 uint32
unix_dev_minor(SMB_DEV_T dev
)
2448 #if defined(HAVE_DEVICE_MINOR_FN)
2449 return (uint32
)minor(dev
);
2451 return (uint32
)(dev
& 0xff);
2455 #if defined(WITH_AIO)
2457 /*******************************************************************
2458 An aio_read wrapper that will deal with 64-bit sizes.
2459 ********************************************************************/
2461 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2463 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2464 return aio_read64(aiocb
);
2465 #elif defined(HAVE_AIO_READ)
2466 return aio_read(aiocb
);
2473 /*******************************************************************
2474 An aio_write wrapper that will deal with 64-bit sizes.
2475 ********************************************************************/
2477 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2479 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2480 return aio_write64(aiocb
);
2481 #elif defined(HAVE_AIO_WRITE)
2482 return aio_write(aiocb
);
2489 /*******************************************************************
2490 An aio_return wrapper that will deal with 64-bit sizes.
2491 ********************************************************************/
2493 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2495 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2496 return aio_return64(aiocb
);
2497 #elif defined(HAVE_AIO_RETURN)
2498 return aio_return(aiocb
);
2505 /*******************************************************************
2506 An aio_cancel wrapper that will deal with 64-bit sizes.
2507 ********************************************************************/
2509 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2511 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2512 return aio_cancel64(fd
, aiocb
);
2513 #elif defined(HAVE_AIO_CANCEL)
2514 return aio_cancel(fd
, aiocb
);
2521 /*******************************************************************
2522 An aio_error wrapper that will deal with 64-bit sizes.
2523 ********************************************************************/
2525 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2527 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2528 return aio_error64(aiocb
);
2529 #elif defined(HAVE_AIO_ERROR)
2530 return aio_error(aiocb
);
2537 /*******************************************************************
2538 An aio_fsync wrapper that will deal with 64-bit sizes.
2539 ********************************************************************/
2541 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2543 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2544 return aio_fsync64(op
, aiocb
);
2545 #elif defined(HAVE_AIO_FSYNC)
2546 return aio_fsync(op
, aiocb
);
2553 /*******************************************************************
2554 An aio_fsync wrapper that will deal with 64-bit sizes.
2555 ********************************************************************/
2557 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2559 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2560 return aio_suspend64(cblist
, n
, timeout
);
2561 #elif defined(HAVE_AIO_FSYNC)
2562 return aio_suspend(cblist
, n
, timeout
);
2568 #else /* !WITH_AIO */
2570 int sys_aio_read(SMB_STRUCT_AIOCB
*aiocb
)
2576 int sys_aio_write(SMB_STRUCT_AIOCB
*aiocb
)
2582 ssize_t
sys_aio_return(SMB_STRUCT_AIOCB
*aiocb
)
2588 int sys_aio_cancel(int fd
, SMB_STRUCT_AIOCB
*aiocb
)
2594 int sys_aio_error(const SMB_STRUCT_AIOCB
*aiocb
)
2600 int sys_aio_fsync(int op
, SMB_STRUCT_AIOCB
*aiocb
)
2606 int sys_aio_suspend(const SMB_STRUCT_AIOCB
* const cblist
[], int n
, const struct timespec
*timeout
)
2611 #endif /* WITH_AIO */
2613 int sys_getpeereid( int s
, uid_t
*uid
)
2615 #if defined(HAVE_PEERCRED)
2617 socklen_t cred_len
= sizeof(struct ucred
);
2620 ret
= getsockopt(s
, SOL_SOCKET
, SO_PEERCRED
, (void *)&cred
, &cred_len
);
2625 if (cred_len
!= sizeof(struct ucred
)) {