r21526: Fix stray character in sys_memalign() that is only
[Samba.git] / source / lib / system.c
blob20b31113ecd71a17cd49e6d6d54af11d404eb014
1 /*
2 Unix SMB/CIFS implementation.
3 Samba system utilities
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1998-2005
6 Copyright (C) Timur Bakeyev 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 #include "includes.h"
25 #ifdef HAVE_SYS_PRCTL_H
26 #include <sys/prctl.h>
27 #endif
30 The idea is that this file will eventually have wrappers around all
31 important system calls in samba. The aims are:
33 - to enable easier porting by putting OS dependent stuff in here
35 - to allow for hooks into other "pseudo-filesystems"
37 - to allow easier integration of things like the japanese extensions
39 - to support the philosophy of Samba to expose the features of
40 the OS within the SMB model. In general whatever file/printer/variable
41 expansions/etc make sense to the OS should be acceptable to Samba.
46 /*******************************************************************
47 A wrapper for memalign
48 ********************************************************************/
50 void* sys_memalign( size_t align, size_t size )
52 #if defined(HAVE_MEMALIGN)
53 return memalign( align, size );
54 #elif defined(HAVE_POSIX_MEMALIGN)
55 char *p = NULL;
56 int ret = posix_memalign( &p, align, size );
57 if ( ret == 0 )
58 return p;
60 return NULL;
61 #else
62 DEBUG(0,("memalign functionalaity not available on this platform!\n"));
63 return NULL;
64 #endif
67 /*******************************************************************
68 A wrapper for usleep in case we don't have one.
69 ********************************************************************/
71 int sys_usleep(long usecs)
73 #ifndef HAVE_USLEEP
74 struct timeval tval;
75 #endif
78 * We need this braindamage as the glibc usleep
79 * is not SPEC1170 complient... grumble... JRA.
82 if(usecs < 0 || usecs > 1000000) {
83 errno = EINVAL;
84 return -1;
87 #if HAVE_USLEEP
88 usleep(usecs);
89 return 0;
90 #else /* HAVE_USLEEP */
92 * Fake it with select...
94 tval.tv_sec = 0;
95 tval.tv_usec = usecs/1000;
96 select(0,NULL,NULL,NULL,&tval);
97 return 0;
98 #endif /* HAVE_USLEEP */
101 /*******************************************************************
102 A read wrapper that will deal with EINTR.
103 ********************************************************************/
105 ssize_t sys_read(int fd, void *buf, size_t count)
107 ssize_t ret;
109 do {
110 ret = read(fd, buf, count);
111 } while (ret == -1 && errno == EINTR);
112 return ret;
115 /*******************************************************************
116 A write wrapper that will deal with EINTR.
117 ********************************************************************/
119 ssize_t sys_write(int fd, const void *buf, size_t count)
121 ssize_t ret;
123 do {
124 ret = write(fd, buf, count);
125 } while (ret == -1 && errno == EINTR);
126 return ret;
129 /*******************************************************************
130 A pread wrapper that will deal with EINTR and 64-bit file offsets.
131 ********************************************************************/
133 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
134 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
136 ssize_t ret;
138 do {
139 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
140 ret = pread64(fd, buf, count, off);
141 #else
142 ret = pread(fd, buf, count, off);
143 #endif
144 } while (ret == -1 && errno == EINTR);
145 return ret;
147 #endif
149 /*******************************************************************
150 A write wrapper that will deal with EINTR and 64-bit file offsets.
151 ********************************************************************/
153 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
154 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
156 ssize_t ret;
158 do {
159 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
160 ret = pwrite64(fd, buf, count, off);
161 #else
162 ret = pwrite(fd, buf, count, off);
163 #endif
164 } while (ret == -1 && errno == EINTR);
165 return ret;
167 #endif
169 /*******************************************************************
170 A send wrapper that will deal with EINTR.
171 ********************************************************************/
173 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
175 ssize_t ret;
177 do {
178 ret = send(s, msg, len, flags);
179 } while (ret == -1 && errno == EINTR);
180 return ret;
183 /*******************************************************************
184 A sendto wrapper that will deal with EINTR.
185 ********************************************************************/
187 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
189 ssize_t ret;
191 do {
192 ret = sendto(s, msg, len, flags, to, tolen);
193 } while (ret == -1 && errno == EINTR);
194 return ret;
197 /*******************************************************************
198 A recv wrapper that will deal with EINTR.
199 ********************************************************************/
201 ssize_t sys_recv(int fd, void *buf, size_t count, int flags)
203 ssize_t ret;
205 do {
206 ret = recv(fd, buf, count, flags);
207 } while (ret == -1 && errno == EINTR);
208 return ret;
211 /*******************************************************************
212 A recvfrom wrapper that will deal with EINTR.
213 ********************************************************************/
215 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
217 ssize_t ret;
219 do {
220 ret = recvfrom(s, buf, len, flags, from, fromlen);
221 } while (ret == -1 && errno == EINTR);
222 return ret;
225 /*******************************************************************
226 A fcntl wrapper that will deal with EINTR.
227 ********************************************************************/
229 int sys_fcntl_ptr(int fd, int cmd, void *arg)
231 int ret;
233 do {
234 ret = fcntl(fd, cmd, arg);
235 } while (ret == -1 && errno == EINTR);
236 return ret;
239 /*******************************************************************
240 A fcntl wrapper that will deal with EINTR.
241 ********************************************************************/
243 int sys_fcntl_long(int fd, int cmd, long arg)
245 int ret;
247 do {
248 ret = fcntl(fd, cmd, arg);
249 } while (ret == -1 && errno == EINTR);
250 return ret;
253 /*******************************************************************
254 A stat() wrapper that will deal with 64 bit filesizes.
255 ********************************************************************/
257 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
259 int ret;
260 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
261 ret = stat64(fname, sbuf);
262 #else
263 ret = stat(fname, sbuf);
264 #endif
265 /* we always want directories to appear zero size */
266 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
267 return ret;
270 /*******************************************************************
271 An fstat() wrapper that will deal with 64 bit filesizes.
272 ********************************************************************/
274 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
276 int ret;
277 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
278 ret = fstat64(fd, sbuf);
279 #else
280 ret = fstat(fd, sbuf);
281 #endif
282 /* we always want directories to appear zero size */
283 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
284 return ret;
287 /*******************************************************************
288 An lstat() wrapper that will deal with 64 bit filesizes.
289 ********************************************************************/
291 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
293 int ret;
294 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
295 ret = lstat64(fname, sbuf);
296 #else
297 ret = lstat(fname, sbuf);
298 #endif
299 /* we always want directories to appear zero size */
300 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
301 return ret;
304 /*******************************************************************
305 An ftruncate() wrapper that will deal with 64 bit filesizes.
306 ********************************************************************/
308 int sys_ftruncate(int fd, SMB_OFF_T offset)
310 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
311 return ftruncate64(fd, offset);
312 #else
313 return ftruncate(fd, offset);
314 #endif
317 /*******************************************************************
318 An lseek() wrapper that will deal with 64 bit filesizes.
319 ********************************************************************/
321 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
323 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
324 return lseek64(fd, offset, whence);
325 #else
326 return lseek(fd, offset, whence);
327 #endif
330 /*******************************************************************
331 An fseek() wrapper that will deal with 64 bit filesizes.
332 ********************************************************************/
334 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
336 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
337 return fseek64(fp, offset, whence);
338 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
339 return fseeko64(fp, offset, whence);
340 #else
341 return fseek(fp, offset, whence);
342 #endif
345 /*******************************************************************
346 An ftell() wrapper that will deal with 64 bit filesizes.
347 ********************************************************************/
349 SMB_OFF_T sys_ftell(FILE *fp)
351 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
352 return (SMB_OFF_T)ftell64(fp);
353 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
354 return (SMB_OFF_T)ftello64(fp);
355 #else
356 return (SMB_OFF_T)ftell(fp);
357 #endif
360 /*******************************************************************
361 A creat() wrapper that will deal with 64 bit filesizes.
362 ********************************************************************/
364 int sys_creat(const char *path, mode_t mode)
366 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
367 return creat64(path, mode);
368 #else
370 * If creat64 isn't defined then ensure we call a potential open64.
371 * JRA.
373 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
374 #endif
377 /*******************************************************************
378 An open() wrapper that will deal with 64 bit filesizes.
379 ********************************************************************/
381 int sys_open(const char *path, int oflag, mode_t mode)
383 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
384 return open64(path, oflag, mode);
385 #else
386 return open(path, oflag, mode);
387 #endif
390 /*******************************************************************
391 An fopen() wrapper that will deal with 64 bit filesizes.
392 ********************************************************************/
394 FILE *sys_fopen(const char *path, const char *type)
396 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
397 return fopen64(path, type);
398 #else
399 return fopen(path, type);
400 #endif
404 /*******************************************************************
405 A flock() wrapper that will perform the kernel flock.
406 ********************************************************************/
408 void kernel_flock(int fd, uint32 share_mode)
410 #if HAVE_KERNEL_SHARE_MODES
411 int kernel_mode = 0;
412 if (share_mode == FILE_SHARE_WRITE) {
413 kernel_mode = LOCK_MAND|LOCK_WRITE;
414 } else if (share_mode == FILE_SHARE_READ) {
415 kernel_mode = LOCK_MAND|LOCK_READ;
416 } else if (share_mode == FILE_SHARE_NONE) {
417 kernel_mode = LOCK_MAND;
419 if (kernel_mode) {
420 flock(fd, kernel_mode);
422 #endif
428 /*******************************************************************
429 An opendir wrapper that will deal with 64 bit filesizes.
430 ********************************************************************/
432 SMB_STRUCT_DIR *sys_opendir(const char *name)
434 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
435 return opendir64(name);
436 #else
437 return opendir(name);
438 #endif
441 /*******************************************************************
442 A readdir wrapper that will deal with 64 bit filesizes.
443 ********************************************************************/
445 SMB_STRUCT_DIRENT *sys_readdir(SMB_STRUCT_DIR *dirp)
447 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
448 return readdir64(dirp);
449 #else
450 return readdir(dirp);
451 #endif
454 /*******************************************************************
455 A seekdir wrapper that will deal with 64 bit filesizes.
456 ********************************************************************/
458 void sys_seekdir(SMB_STRUCT_DIR *dirp, long offset)
460 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
461 seekdir64(dirp, offset);
462 #else
463 seekdir(dirp, offset);
464 #endif
467 /*******************************************************************
468 A telldir wrapper that will deal with 64 bit filesizes.
469 ********************************************************************/
471 long sys_telldir(SMB_STRUCT_DIR *dirp)
473 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
474 return (long)telldir64(dirp);
475 #else
476 return (long)telldir(dirp);
477 #endif
480 /*******************************************************************
481 A rewinddir wrapper that will deal with 64 bit filesizes.
482 ********************************************************************/
484 void sys_rewinddir(SMB_STRUCT_DIR *dirp)
486 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
487 rewinddir64(dirp);
488 #else
489 rewinddir(dirp);
490 #endif
493 /*******************************************************************
494 A close wrapper that will deal with 64 bit filesizes.
495 ********************************************************************/
497 int sys_closedir(SMB_STRUCT_DIR *dirp)
499 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
500 return closedir64(dirp);
501 #else
502 return closedir(dirp);
503 #endif
506 /*******************************************************************
507 An mknod() wrapper that will deal with 64 bit filesizes.
508 ********************************************************************/
510 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
512 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
513 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
514 return mknod64(path, mode, dev);
515 #else
516 return mknod(path, mode, dev);
517 #endif
518 #else
519 /* No mknod system call. */
520 errno = ENOSYS;
521 return -1;
522 #endif
525 /*******************************************************************
526 Wrapper for realpath.
527 ********************************************************************/
529 char *sys_realpath(const char *path, char *resolved_path)
531 #if defined(HAVE_REALPATH)
532 return realpath(path, resolved_path);
533 #else
534 /* As realpath is not a system call we can't return ENOSYS. */
535 errno = EINVAL;
536 return NULL;
537 #endif
540 /*******************************************************************
541 The wait() calls vary between systems
542 ********************************************************************/
544 int sys_waitpid(pid_t pid,int *status,int options)
546 #ifdef HAVE_WAITPID
547 return waitpid(pid,status,options);
548 #else /* HAVE_WAITPID */
549 return wait4(pid, status, options, NULL);
550 #endif /* HAVE_WAITPID */
553 /*******************************************************************
554 System wrapper for getwd
555 ********************************************************************/
557 char *sys_getwd(char *s)
559 char *wd;
560 #ifdef HAVE_GETCWD
561 wd = (char *)getcwd(s, sizeof (pstring));
562 #else
563 wd = (char *)getwd(s);
564 #endif
565 return wd;
568 /*******************************************************************
569 system wrapper for symlink
570 ********************************************************************/
572 int sys_symlink(const char *oldpath, const char *newpath)
574 #ifndef HAVE_SYMLINK
575 errno = ENOSYS;
576 return -1;
577 #else
578 return symlink(oldpath, newpath);
579 #endif
582 /*******************************************************************
583 system wrapper for readlink
584 ********************************************************************/
586 int sys_readlink(const char *path, char *buf, size_t bufsiz)
588 #ifndef HAVE_READLINK
589 errno = ENOSYS;
590 return -1;
591 #else
592 return readlink(path, buf, bufsiz);
593 #endif
596 /*******************************************************************
597 system wrapper for link
598 ********************************************************************/
600 int sys_link(const char *oldpath, const char *newpath)
602 #ifndef HAVE_LINK
603 errno = ENOSYS;
604 return -1;
605 #else
606 return link(oldpath, newpath);
607 #endif
610 /*******************************************************************
611 chown isn't used much but OS/2 doesn't have it
612 ********************************************************************/
614 int sys_chown(const char *fname,uid_t uid,gid_t gid)
616 #ifndef HAVE_CHOWN
617 static int done;
618 if (!done) {
619 DEBUG(1,("WARNING: no chown!\n"));
620 done=1;
622 errno = ENOSYS;
623 return -1;
624 #else
625 return(chown(fname,uid,gid));
626 #endif
629 /*******************************************************************
630 os/2 also doesn't have chroot
631 ********************************************************************/
632 int sys_chroot(const char *dname)
634 #ifndef HAVE_CHROOT
635 static int done;
636 if (!done) {
637 DEBUG(1,("WARNING: no chroot!\n"));
638 done=1;
640 errno = ENOSYS;
641 return -1;
642 #else
643 return(chroot(dname));
644 #endif
647 /**************************************************************************
648 A wrapper for gethostbyname() that tries avoids looking up hostnames
649 in the root domain, which can cause dial-on-demand links to come up for no
650 apparent reason.
651 ****************************************************************************/
653 struct hostent *sys_gethostbyname(const char *name)
655 #ifdef REDUCE_ROOT_DNS_LOOKUPS
656 char query[256], hostname[256];
657 char *domain;
659 /* Does this name have any dots in it? If so, make no change */
661 if (strchr_m(name, '.'))
662 return(gethostbyname(name));
664 /* Get my hostname, which should have domain name
665 attached. If not, just do the gethostname on the
666 original string.
669 gethostname(hostname, sizeof(hostname) - 1);
670 hostname[sizeof(hostname) - 1] = 0;
671 if ((domain = strchr_m(hostname, '.')) == NULL)
672 return(gethostbyname(name));
674 /* Attach domain name to query and do modified query.
675 If names too large, just do gethostname on the
676 original string.
679 if((strlen(name) + strlen(domain)) >= sizeof(query))
680 return(gethostbyname(name));
682 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
683 return(gethostbyname(query));
684 #else /* REDUCE_ROOT_DNS_LOOKUPS */
685 return(gethostbyname(name));
686 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
690 #if defined(HAVE_POSIX_CAPABILITIES)
692 #ifdef HAVE_SYS_CAPABILITY_H
694 #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
695 #define _I386_STATFS_H
696 #define _PPC_STATFS_H
697 #define BROKEN_REDHAT_7_STATFS_WORKAROUND
698 #endif
700 #include <sys/capability.h>
702 #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
703 #undef _I386_STATFS_H
704 #undef _PPC_STATFS_H
705 #undef BROKEN_REDHAT_7_STATFS_WORKAROUND
706 #endif
708 #endif /* HAVE_SYS_CAPABILITY_H */
710 /**************************************************************************
711 Try and abstract process capabilities (for systems that have them).
712 ****************************************************************************/
714 /* Set the POSIX capabilities needed for the given purpose into the effective
715 * capability set of the current process. Make sure they are always removed
716 * from the inheritable set, because there is no circumstance in which our
717 * children should inherit our elevated privileges.
719 static BOOL set_process_capability(enum smbd_capability capability,
720 BOOL enable)
722 cap_value_t cap_vals[2] = {0};
723 int num_cap_vals = 0;
725 cap_t cap;
727 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
728 /* On Linux, make sure that any capabilities we grab are sticky
729 * across UID changes. We expect that this would allow us to keep both
730 * the effective and permitted capability sets, but as of circa 2.6.16,
731 * only the permitted set is kept. It is a bug (which we work around)
732 * that the effective set is lost, but we still require the effective
733 * set to be kept.
735 if (!prctl(PR_GET_KEEPCAPS)) {
736 prctl(PR_SET_KEEPCAPS, 1);
738 #endif
740 cap = cap_get_proc();
741 if (cap == NULL) {
742 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
743 strerror(errno)));
744 return False;
747 switch (capability) {
748 case KERNEL_OPLOCK_CAPABILITY:
749 #ifdef CAP_NETWORK_MGT
750 /* IRIX has CAP_NETWORK_MGT for oplocks. */
751 cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
752 #endif
753 break;
754 case DMAPI_ACCESS_CAPABILITY:
755 #ifdef CAP_DEVICE_MGT
756 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
757 cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
758 #elif CAP_MKNOD
759 /* Linux has CAP_MKNOD for DMAPI access. */
760 cap_vals[num_cap_vals++] = CAP_MKNOD;
761 #endif
762 break;
765 SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
767 if (num_cap_vals == 0) {
768 cap_free(cap);
769 return True;
772 cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
773 enable ? CAP_SET : CAP_CLEAR);
775 /* We never want to pass capabilities down to our children, so make
776 * sure they are not inherited.
778 cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
780 if (cap_set_proc(cap) == -1) {
781 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
782 strerror(errno)));
783 cap_free(cap);
784 return False;
787 cap_free(cap);
788 return True;
791 #endif /* HAVE_POSIX_CAPABILITIES */
793 /****************************************************************************
794 Gain the oplock capability from the kernel if possible.
795 ****************************************************************************/
797 void set_effective_capability(enum smbd_capability capability)
799 #if defined(HAVE_POSIX_CAPABILITIES)
800 set_process_capability(capability, True);
801 #endif /* HAVE_POSIX_CAPABILITIES */
804 void drop_effective_capability(enum smbd_capability capability)
806 #if defined(HAVE_POSIX_CAPABILITIES)
807 set_process_capability(capability, False);
808 #endif /* HAVE_POSIX_CAPABILITIES */
811 /**************************************************************************
812 Wrapper for random().
813 ****************************************************************************/
815 long sys_random(void)
817 #if defined(HAVE_RANDOM)
818 return (long)random();
819 #elif defined(HAVE_RAND)
820 return (long)rand();
821 #else
822 DEBUG(0,("Error - no random function available !\n"));
823 exit(1);
824 #endif
827 /**************************************************************************
828 Wrapper for srandom().
829 ****************************************************************************/
831 void sys_srandom(unsigned int seed)
833 #if defined(HAVE_SRANDOM)
834 srandom(seed);
835 #elif defined(HAVE_SRAND)
836 srand(seed);
837 #else
838 DEBUG(0,("Error - no srandom function available !\n"));
839 exit(1);
840 #endif
843 /**************************************************************************
844 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
845 ****************************************************************************/
847 int groups_max(void)
849 #if defined(SYSCONF_SC_NGROUPS_MAX)
850 int ret = sysconf(_SC_NGROUPS_MAX);
851 return (ret == -1) ? NGROUPS_MAX : ret;
852 #else
853 return NGROUPS_MAX;
854 #endif
857 /**************************************************************************
858 Wrapper for getgroups. Deals with broken (int) case.
859 ****************************************************************************/
861 int sys_getgroups(int setlen, gid_t *gidset)
863 #if !defined(HAVE_BROKEN_GETGROUPS)
864 return getgroups(setlen, gidset);
865 #else
867 GID_T gid;
868 GID_T *group_list;
869 int i, ngroups;
871 if(setlen == 0) {
872 return getgroups(setlen, &gid);
876 * Broken case. We need to allocate a
877 * GID_T array of size setlen.
880 if(setlen < 0) {
881 errno = EINVAL;
882 return -1;
885 if (setlen == 0)
886 setlen = groups_max();
888 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
889 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
890 return -1;
893 if((ngroups = getgroups(setlen, group_list)) < 0) {
894 int saved_errno = errno;
895 SAFE_FREE(group_list);
896 errno = saved_errno;
897 return -1;
900 for(i = 0; i < ngroups; i++)
901 gidset[i] = (gid_t)group_list[i];
903 SAFE_FREE(group_list);
904 return ngroups;
905 #endif /* HAVE_BROKEN_GETGROUPS */
909 /**************************************************************************
910 Wrapper for setgroups. Deals with broken (int) case. Automatically used
911 if we have broken getgroups.
912 ****************************************************************************/
914 int sys_setgroups(int setlen, gid_t *gidset)
916 #if !defined(HAVE_SETGROUPS)
917 errno = ENOSYS;
918 return -1;
919 #endif /* HAVE_SETGROUPS */
921 #if !defined(HAVE_BROKEN_GETGROUPS)
922 return setgroups(setlen, gidset);
923 #else
925 GID_T *group_list;
926 int i ;
928 if (setlen == 0)
929 return 0 ;
931 if (setlen < 0 || setlen > groups_max()) {
932 errno = EINVAL;
933 return -1;
937 * Broken case. We need to allocate a
938 * GID_T array of size setlen.
941 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
942 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
943 return -1;
946 for(i = 0; i < setlen; i++)
947 group_list[i] = (GID_T) gidset[i];
949 if(setgroups(setlen, group_list) != 0) {
950 int saved_errno = errno;
951 SAFE_FREE(group_list);
952 errno = saved_errno;
953 return -1;
956 SAFE_FREE(group_list);
957 return 0 ;
958 #endif /* HAVE_BROKEN_GETGROUPS */
961 /**************************************************************************
962 Wrappers for setpwent(), getpwent() and endpwent()
963 ****************************************************************************/
965 void sys_setpwent(void)
967 setpwent();
970 struct passwd *sys_getpwent(void)
972 return getpwent();
975 void sys_endpwent(void)
977 endpwent();
980 /**************************************************************************
981 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
982 ****************************************************************************/
984 #ifdef ENABLE_BUILD_FARM_HACKS
987 * In the build farm we want to be able to join machines to the domain. As we
988 * don't have root access, we need to bypass direct access to /etc/passwd
989 * after a user has been created via samr. Fake those users.
992 static struct passwd *fake_pwd;
993 static int num_fake_pwd;
995 struct passwd *sys_getpwnam(const char *name)
997 int i;
999 for (i=0; i<num_fake_pwd; i++) {
1000 if (strcmp(fake_pwd[i].pw_name, name) == 0) {
1001 DEBUG(10, ("Returning fake user %s\n", name));
1002 return &fake_pwd[i];
1006 return getpwnam(name);
1009 struct passwd *sys_getpwuid(uid_t uid)
1011 int i;
1013 for (i=0; i<num_fake_pwd; i++) {
1014 if (fake_pwd[i].pw_uid == uid) {
1015 DEBUG(10, ("Returning fake user %s\n",
1016 fake_pwd[i].pw_name));
1017 return &fake_pwd[i];
1021 return getpwuid(uid);
1024 void faked_create_user(const char *name)
1026 int i;
1027 uid_t uid;
1028 struct passwd new_pwd;
1030 for (i=0; i<10; i++) {
1031 generate_random_buffer((unsigned char *)&uid,
1032 sizeof(uid));
1033 if (getpwuid(uid) == NULL) {
1034 break;
1038 if (i==10) {
1039 /* Weird. No free uid found... */
1040 return;
1043 new_pwd.pw_name = SMB_STRDUP(name);
1044 new_pwd.pw_passwd = SMB_STRDUP("x");
1045 new_pwd.pw_uid = uid;
1046 new_pwd.pw_gid = 100;
1047 new_pwd.pw_gecos = SMB_STRDUP("faked user");
1048 new_pwd.pw_dir = SMB_STRDUP("/nodir");
1049 new_pwd.pw_shell = SMB_STRDUP("/bin/false");
1051 ADD_TO_ARRAY(NULL, struct passwd, new_pwd, &fake_pwd,
1052 &num_fake_pwd);
1054 DEBUG(10, ("Added fake user %s, have %d fake users\n",
1055 name, num_fake_pwd));
1058 #else
1060 struct passwd *sys_getpwnam(const char *name)
1062 return getpwnam(name);
1065 struct passwd *sys_getpwuid(uid_t uid)
1067 return getpwuid(uid);
1070 #endif
1072 struct group *sys_getgrnam(const char *name)
1074 return getgrnam(name);
1077 struct group *sys_getgrgid(gid_t gid)
1079 return getgrgid(gid);
1082 #if 0 /* NOT CURRENTLY USED - JRA */
1083 /**************************************************************************
1084 The following are the UNICODE versions of *all* system interface functions
1085 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
1086 which currently are left as ascii as they are not used other than in name
1087 resolution.
1088 ****************************************************************************/
1090 /**************************************************************************
1091 Wide stat. Just narrow and call sys_xxx.
1092 ****************************************************************************/
1094 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
1096 pstring fname;
1097 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
1100 /**************************************************************************
1101 Wide lstat. Just narrow and call sys_xxx.
1102 ****************************************************************************/
1104 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
1106 pstring fname;
1107 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
1110 /**************************************************************************
1111 Wide creat. Just narrow and call sys_xxx.
1112 ****************************************************************************/
1114 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
1116 pstring fname;
1117 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
1120 /**************************************************************************
1121 Wide open. Just narrow and call sys_xxx.
1122 ****************************************************************************/
1124 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
1126 pstring fname;
1127 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
1130 /**************************************************************************
1131 Wide fopen. Just narrow and call sys_xxx.
1132 ****************************************************************************/
1134 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
1136 pstring fname;
1137 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
1140 /**************************************************************************
1141 Wide opendir. Just narrow and call sys_xxx.
1142 ****************************************************************************/
1144 SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname)
1146 pstring fname;
1147 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
1150 /**************************************************************************
1151 Wide readdir. Return a structure pointer containing a wide filename.
1152 ****************************************************************************/
1154 SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp)
1156 static SMB_STRUCT_WDIRENT retval;
1157 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
1159 if(!dirval)
1160 return NULL;
1163 * The only POSIX defined member of this struct is d_name.
1166 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
1168 return &retval;
1171 /**************************************************************************
1172 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
1173 ****************************************************************************/
1175 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
1177 pstring fname;
1178 char *p = sys_getwd(fname);
1180 if(!p)
1181 return NULL;
1183 return unix_to_unicode(s, p, sizeof(wpstring));
1186 /**************************************************************************
1187 Wide chown. Just narrow and call sys_xxx.
1188 ****************************************************************************/
1190 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
1192 pstring fname;
1193 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
1196 /**************************************************************************
1197 Wide chroot. Just narrow and call sys_xxx.
1198 ****************************************************************************/
1200 int wsys_chroot(const smb_ucs2_t *wfname)
1202 pstring fname;
1203 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
1206 /**************************************************************************
1207 Wide getpwnam. Return a structure pointer containing wide names.
1208 ****************************************************************************/
1210 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1212 static SMB_STRUCT_WPASSWD retval;
1213 fstring name;
1214 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1216 if(!pwret)
1217 return NULL;
1219 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1220 retval.pw_passwd = pwret->pw_passwd;
1221 retval.pw_uid = pwret->pw_uid;
1222 retval.pw_gid = pwret->pw_gid;
1223 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1224 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1225 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1227 return &retval;
1230 /**************************************************************************
1231 Wide getpwuid. Return a structure pointer containing wide names.
1232 ****************************************************************************/
1234 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1236 static SMB_STRUCT_WPASSWD retval;
1237 struct passwd *pwret = sys_getpwuid(uid);
1239 if(!pwret)
1240 return NULL;
1242 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1243 retval.pw_passwd = pwret->pw_passwd;
1244 retval.pw_uid = pwret->pw_uid;
1245 retval.pw_gid = pwret->pw_gid;
1246 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1247 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1248 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1250 return &retval;
1252 #endif /* NOT CURRENTLY USED - JRA */
1254 /**************************************************************************
1255 Extract a command into an arg list. Uses a static pstring for storage.
1256 Caller frees returned arg list (which contains pointers into the static pstring).
1257 ****************************************************************************/
1259 static char **extract_args(const char *command)
1261 static pstring trunc_cmd;
1262 char *ptr;
1263 int argcl;
1264 char **argl = NULL;
1265 int i;
1267 pstrcpy(trunc_cmd, command);
1269 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1270 errno = EINVAL;
1271 return NULL;
1275 * Count the args.
1278 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1279 argcl++;
1281 if((argl = (char **)SMB_MALLOC((argcl + 1) * sizeof(char *))) == NULL)
1282 return NULL;
1285 * Now do the extraction.
1288 pstrcpy(trunc_cmd, command);
1290 ptr = strtok(trunc_cmd, " \t");
1291 i = 0;
1292 argl[i++] = ptr;
1294 while((ptr = strtok(NULL, " \t")) != NULL)
1295 argl[i++] = ptr;
1297 argl[i++] = NULL;
1298 return argl;
1301 /**************************************************************************
1302 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1303 a sys_getpid() that only does a system call *once*.
1304 ****************************************************************************/
1306 static pid_t mypid = (pid_t)-1;
1308 pid_t sys_fork(void)
1310 pid_t forkret = fork();
1312 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1313 mypid = (pid_t) -1;
1315 return forkret;
1318 /**************************************************************************
1319 Wrapper for getpid. Ensures we only do a system call *once*.
1320 ****************************************************************************/
1322 pid_t sys_getpid(void)
1324 if (mypid == (pid_t)-1)
1325 mypid = getpid();
1327 return mypid;
1330 /**************************************************************************
1331 Wrapper for popen. Safer as it doesn't search a path.
1332 Modified from the glibc sources.
1333 modified by tridge to return a file descriptor. We must kick our FILE* habit
1334 ****************************************************************************/
1336 typedef struct _popen_list
1338 int fd;
1339 pid_t child_pid;
1340 struct _popen_list *next;
1341 } popen_list;
1343 static popen_list *popen_chain;
1345 int sys_popen(const char *command)
1347 int parent_end, child_end;
1348 int pipe_fds[2];
1349 popen_list *entry = NULL;
1350 char **argl = NULL;
1352 if (pipe(pipe_fds) < 0)
1353 return -1;
1355 parent_end = pipe_fds[0];
1356 child_end = pipe_fds[1];
1358 if (!*command) {
1359 errno = EINVAL;
1360 goto err_exit;
1363 if((entry = SMB_MALLOC_P(popen_list)) == NULL)
1364 goto err_exit;
1366 ZERO_STRUCTP(entry);
1369 * Extract the command and args into a NULL terminated array.
1372 if(!(argl = extract_args(command)))
1373 goto err_exit;
1375 entry->child_pid = sys_fork();
1377 if (entry->child_pid == -1) {
1378 goto err_exit;
1381 if (entry->child_pid == 0) {
1384 * Child !
1387 int child_std_end = STDOUT_FILENO;
1388 popen_list *p;
1390 close(parent_end);
1391 if (child_end != child_std_end) {
1392 dup2 (child_end, child_std_end);
1393 close (child_end);
1397 * POSIX.2: "popen() shall ensure that any streams from previous
1398 * popen() calls that remain open in the parent process are closed
1399 * in the new child process."
1402 for (p = popen_chain; p; p = p->next)
1403 close(p->fd);
1405 execv(argl[0], argl);
1406 _exit (127);
1410 * Parent.
1413 close (child_end);
1414 SAFE_FREE(argl);
1416 /* Link into popen_chain. */
1417 entry->next = popen_chain;
1418 popen_chain = entry;
1419 entry->fd = parent_end;
1421 return entry->fd;
1423 err_exit:
1425 SAFE_FREE(entry);
1426 SAFE_FREE(argl);
1427 close(pipe_fds[0]);
1428 close(pipe_fds[1]);
1429 return -1;
1432 /**************************************************************************
1433 Wrapper for pclose. Modified from the glibc sources.
1434 ****************************************************************************/
1436 int sys_pclose(int fd)
1438 int wstatus;
1439 popen_list **ptr = &popen_chain;
1440 popen_list *entry = NULL;
1441 pid_t wait_pid;
1442 int status = -1;
1444 /* Unlink from popen_chain. */
1445 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1446 if ((*ptr)->fd == fd) {
1447 entry = *ptr;
1448 *ptr = (*ptr)->next;
1449 status = 0;
1450 break;
1454 if (status < 0 || close(entry->fd) < 0)
1455 return -1;
1458 * As Samba is catching and eating child process
1459 * exits we don't really care about the child exit
1460 * code, a -1 with errno = ECHILD will do fine for us.
1463 do {
1464 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1465 } while (wait_pid == -1 && errno == EINTR);
1467 SAFE_FREE(entry);
1469 if (wait_pid == -1)
1470 return -1;
1471 return wstatus;
1474 /**************************************************************************
1475 Wrappers for dlopen, dlsym, dlclose.
1476 ****************************************************************************/
1478 void *sys_dlopen(const char *name, int flags)
1480 #if defined(HAVE_DLOPEN)
1481 return dlopen(name, flags);
1482 #else
1483 return NULL;
1484 #endif
1487 void *sys_dlsym(void *handle, const char *symbol)
1489 #if defined(HAVE_DLSYM)
1490 return dlsym(handle, symbol);
1491 #else
1492 return NULL;
1493 #endif
1496 int sys_dlclose (void *handle)
1498 #if defined(HAVE_DLCLOSE)
1499 return dlclose(handle);
1500 #else
1501 return 0;
1502 #endif
1505 const char *sys_dlerror(void)
1507 #if defined(HAVE_DLERROR)
1508 return dlerror();
1509 #else
1510 return NULL;
1511 #endif
1514 int sys_dup2(int oldfd, int newfd)
1516 #if defined(HAVE_DUP2)
1517 return dup2(oldfd, newfd);
1518 #else
1519 errno = ENOSYS;
1520 return -1;
1521 #endif
1524 /**************************************************************************
1525 Wrapper for Admin Logs.
1526 ****************************************************************************/
1528 void sys_adminlog(int priority, const char *format_str, ...)
1530 va_list ap;
1531 int ret;
1532 char *msgbuf = NULL;
1534 va_start( ap, format_str );
1535 ret = vasprintf( &msgbuf, format_str, ap );
1536 va_end( ap );
1538 if (ret == -1)
1539 return;
1541 #if defined(HAVE_SYSLOG)
1542 syslog( priority, "%s", msgbuf );
1543 #else
1544 DEBUG(0,("%s", msgbuf ));
1545 #endif
1546 SAFE_FREE(msgbuf);
1549 /**************************************************************************
1550 Wrappers for extented attribute calls. Based on the Linux package with
1551 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1552 ****************************************************************************/
1554 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1556 #if defined(HAVE_GETXATTR)
1557 #ifndef XATTR_ADD_OPT
1558 return getxattr(path, name, value, size);
1559 #else
1560 int options = 0;
1561 return getxattr(path, name, value, size, 0, options);
1562 #endif
1563 #elif defined(HAVE_GETEA)
1564 return getea(path, name, value, size);
1565 #elif defined(HAVE_EXTATTR_GET_FILE)
1566 char *s;
1567 ssize_t retval;
1568 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1569 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1570 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1572 * The BSD implementation has a nasty habit of silently truncating
1573 * the returned value to the size of the buffer, so we have to check
1574 * that the buffer is large enough to fit the returned value.
1576 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1577 if(retval > size) {
1578 errno = ERANGE;
1579 return -1;
1581 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
1582 return retval;
1585 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
1586 return -1;
1587 #elif defined(HAVE_ATTR_GET)
1588 int retval, flags = 0;
1589 int valuelength = (int)size;
1590 char *attrname = strchr(name,'.') + 1;
1592 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1594 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1596 return retval ? retval : valuelength;
1597 #else
1598 errno = ENOSYS;
1599 return -1;
1600 #endif
1603 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1605 #if defined(HAVE_LGETXATTR)
1606 return lgetxattr(path, name, value, size);
1607 #elif defined(HAVE_GETXATTR) && defined(XATTR_ADD_OPT)
1608 int options = XATTR_NOFOLLOW;
1609 return getxattr(path, name, value, size, 0, options);
1610 #elif defined(HAVE_LGETEA)
1611 return lgetea(path, name, value, size);
1612 #elif defined(HAVE_EXTATTR_GET_LINK)
1613 char *s;
1614 ssize_t retval;
1615 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1616 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1617 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1619 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1620 if(retval > size) {
1621 errno = ERANGE;
1622 return -1;
1624 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
1625 return retval;
1628 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
1629 return -1;
1630 #elif defined(HAVE_ATTR_GET)
1631 int retval, flags = ATTR_DONTFOLLOW;
1632 int valuelength = (int)size;
1633 char *attrname = strchr(name,'.') + 1;
1635 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1637 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1639 return retval ? retval : valuelength;
1640 #else
1641 errno = ENOSYS;
1642 return -1;
1643 #endif
1646 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1648 #if defined(HAVE_FGETXATTR)
1649 #ifndef XATTR_ADD_OPT
1650 return fgetxattr(filedes, name, value, size);
1651 #else
1652 int options = 0;
1653 return fgetxattr(filedes, name, value, size, 0, options);
1654 #endif
1655 #elif defined(HAVE_FGETEA)
1656 return fgetea(filedes, name, value, size);
1657 #elif defined(HAVE_EXTATTR_GET_FD)
1658 char *s;
1659 ssize_t retval;
1660 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1661 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1662 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1664 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
1665 if(retval > size) {
1666 errno = ERANGE;
1667 return -1;
1669 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
1670 return retval;
1673 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
1674 return -1;
1675 #elif defined(HAVE_ATTR_GETF)
1676 int retval, flags = 0;
1677 int valuelength = (int)size;
1678 char *attrname = strchr(name,'.') + 1;
1680 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1682 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1684 return retval ? retval : valuelength;
1685 #else
1686 errno = ENOSYS;
1687 return -1;
1688 #endif
1691 #if defined(HAVE_EXTATTR_LIST_FILE)
1693 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1695 static struct {
1696 int space;
1697 const char *name;
1698 size_t len;
1700 extattr[] = {
1701 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
1702 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
1705 typedef union {
1706 const char *path;
1707 int filedes;
1708 } extattr_arg;
1710 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
1712 ssize_t list_size, total_size = 0;
1713 int i, t, len;
1714 char *buf;
1715 /* Iterate through extattr(2) namespaces */
1716 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
1717 switch(type) {
1718 #if defined(HAVE_EXTATTR_LIST_FILE)
1719 case 0:
1720 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
1721 break;
1722 #endif
1723 #if defined(HAVE_EXTATTR_LIST_LINK)
1724 case 1:
1725 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
1726 break;
1727 #endif
1728 #if defined(HAVE_EXTATTR_LIST_FD)
1729 case 2:
1730 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
1731 break;
1732 #endif
1733 default:
1734 errno = ENOSYS;
1735 return -1;
1737 /* Some error happend. Errno should be set by the previous call */
1738 if(list_size < 0)
1739 return -1;
1740 /* No attributes */
1741 if(list_size == 0)
1742 continue;
1743 /* XXX: Call with an empty buffer may be used to calculate
1744 necessary buffer size. Unfortunately, we can't say, how
1745 many attributes were returned, so here is the potential
1746 problem with the emulation.
1748 if(list == NULL) {
1749 /* Take the worse case of one char attribute names -
1750 two bytes per name plus one more for sanity.
1752 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
1753 continue;
1755 /* Count necessary offset to fit namespace prefixes */
1756 len = 0;
1757 for(i = 0; i < list_size; i += list[i] + 1)
1758 len += extattr[t].len;
1760 total_size += list_size + len;
1761 /* Buffer is too small to fit the results */
1762 if(total_size > size) {
1763 errno = ERANGE;
1764 return -1;
1766 /* Shift results back, so we can prepend prefixes */
1767 buf = memmove(list + len, list, list_size);
1769 for(i = 0; i < list_size; i += len + 1) {
1770 len = buf[i];
1771 strncpy(list, extattr[t].name, extattr[t].len + 1);
1772 list += extattr[t].len;
1773 strncpy(list, buf + i + 1, len);
1774 list[len] = '\0';
1775 list += len + 1;
1777 size -= total_size;
1779 return total_size;
1782 #endif
1784 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1785 static char attr_buffer[ATTR_MAX_VALUELEN];
1787 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1789 int retval = 0, index;
1790 attrlist_cursor_t *cursor = 0;
1791 int total_size = 0;
1792 attrlist_t * al = (attrlist_t *)attr_buffer;
1793 attrlist_ent_t *ae;
1794 size_t ent_size, left = size;
1795 char *bp = list;
1797 while (True) {
1798 if (filedes)
1799 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1800 else
1801 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1802 if (retval) break;
1803 for (index = 0; index < al->al_count; index++) {
1804 ae = ATTR_ENTRY(attr_buffer, index);
1805 ent_size = strlen(ae->a_name) + sizeof("user.");
1806 if (left >= ent_size) {
1807 strncpy(bp, "user.", sizeof("user."));
1808 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1809 bp += ent_size;
1810 left -= ent_size;
1811 } else if (size) {
1812 errno = ERANGE;
1813 retval = -1;
1814 break;
1816 total_size += ent_size;
1818 if (al->al_more == 0) break;
1820 if (retval == 0) {
1821 flags |= ATTR_ROOT;
1822 cursor = 0;
1823 while (True) {
1824 if (filedes)
1825 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1826 else
1827 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1828 if (retval) break;
1829 for (index = 0; index < al->al_count; index++) {
1830 ae = ATTR_ENTRY(attr_buffer, index);
1831 ent_size = strlen(ae->a_name) + sizeof("system.");
1832 if (left >= ent_size) {
1833 strncpy(bp, "system.", sizeof("system."));
1834 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1835 bp += ent_size;
1836 left -= ent_size;
1837 } else if (size) {
1838 errno = ERANGE;
1839 retval = -1;
1840 break;
1842 total_size += ent_size;
1844 if (al->al_more == 0) break;
1847 return (ssize_t)(retval ? retval : total_size);
1850 #endif
1852 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1854 #if defined(HAVE_LISTXATTR)
1855 #ifndef XATTR_ADD_OPT
1856 return listxattr(path, list, size);
1857 #else
1858 int options = 0;
1859 return listxattr(path, list, size, options);
1860 #endif
1861 #elif defined(HAVE_LISTEA)
1862 return listea(path, list, size);
1863 #elif defined(HAVE_EXTATTR_LIST_FILE)
1864 extattr_arg arg;
1865 arg.path = path;
1866 return bsd_attr_list(0, arg, list, size);
1867 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1868 return irix_attr_list(path, 0, list, size, 0);
1869 #else
1870 errno = ENOSYS;
1871 return -1;
1872 #endif
1875 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1877 #if defined(HAVE_LLISTXATTR)
1878 return llistxattr(path, list, size);
1879 #elif defined(HAVE_LISTXATTR) && defined(XATTR_ADD_OPT)
1880 int options = XATTR_NOFOLLOW;
1881 return listxattr(path, list, size, options);
1882 #elif defined(HAVE_LLISTEA)
1883 return llistea(path, list, size);
1884 #elif defined(HAVE_EXTATTR_LIST_LINK)
1885 extattr_arg arg;
1886 arg.path = path;
1887 return bsd_attr_list(1, arg, list, size);
1888 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1889 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1890 #else
1891 errno = ENOSYS;
1892 return -1;
1893 #endif
1896 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1898 #if defined(HAVE_FLISTXATTR)
1899 #ifndef XATTR_ADD_OPT
1900 return flistxattr(filedes, list, size);
1901 #else
1902 int options = 0;
1903 return flistxattr(filedes, list, size, options);
1904 #endif
1905 #elif defined(HAVE_FLISTEA)
1906 return flistea(filedes, list, size);
1907 #elif defined(HAVE_EXTATTR_LIST_FD)
1908 extattr_arg arg;
1909 arg.filedes = filedes;
1910 return bsd_attr_list(2, arg, list, size);
1911 #elif defined(HAVE_ATTR_LISTF)
1912 return irix_attr_list(NULL, filedes, list, size, 0);
1913 #else
1914 errno = ENOSYS;
1915 return -1;
1916 #endif
1919 int sys_removexattr (const char *path, const char *name)
1921 #if defined(HAVE_REMOVEXATTR)
1922 #ifndef XATTR_ADD_OPT
1923 return removexattr(path, name);
1924 #else
1925 int options = 0;
1926 return removexattr(path, name, options);
1927 #endif
1928 #elif defined(HAVE_REMOVEEA)
1929 return removeea(path, name);
1930 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1931 char *s;
1932 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1933 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1934 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1936 return extattr_delete_file(path, attrnamespace, attrname);
1937 #elif defined(HAVE_ATTR_REMOVE)
1938 int flags = 0;
1939 char *attrname = strchr(name,'.') + 1;
1941 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1943 return attr_remove(path, attrname, flags);
1944 #else
1945 errno = ENOSYS;
1946 return -1;
1947 #endif
1950 int sys_lremovexattr (const char *path, const char *name)
1952 #if defined(HAVE_LREMOVEXATTR)
1953 return lremovexattr(path, name);
1954 #elif defined(HAVE_REMOVEXATTR) && defined(XATTR_ADD_OPT)
1955 int options = XATTR_NOFOLLOW;
1956 return removexattr(path, name, options);
1957 #elif defined(HAVE_LREMOVEEA)
1958 return lremoveea(path, name);
1959 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1960 char *s;
1961 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1962 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1963 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1965 return extattr_delete_link(path, attrnamespace, attrname);
1966 #elif defined(HAVE_ATTR_REMOVE)
1967 int flags = ATTR_DONTFOLLOW;
1968 char *attrname = strchr(name,'.') + 1;
1970 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1972 return attr_remove(path, attrname, flags);
1973 #else
1974 errno = ENOSYS;
1975 return -1;
1976 #endif
1979 int sys_fremovexattr (int filedes, const char *name)
1981 #if defined(HAVE_FREMOVEXATTR)
1982 #ifndef XATTR_ADD_OPT
1983 return fremovexattr(filedes, name);
1984 #else
1985 int options = 0;
1986 return fremovexattr(filedes, name, options);
1987 #endif
1988 #elif defined(HAVE_FREMOVEEA)
1989 return fremoveea(filedes, name);
1990 #elif defined(HAVE_EXTATTR_DELETE_FD)
1991 char *s;
1992 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1993 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1994 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1996 return extattr_delete_fd(filedes, attrnamespace, attrname);
1997 #elif defined(HAVE_ATTR_REMOVEF)
1998 int flags = 0;
1999 char *attrname = strchr(name,'.') + 1;
2001 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
2003 return attr_removef(filedes, attrname, flags);
2004 #else
2005 errno = ENOSYS;
2006 return -1;
2007 #endif
2010 #if !defined(HAVE_SETXATTR)
2011 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
2012 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
2013 #endif
2015 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
2017 #if defined(HAVE_SETXATTR)
2018 #ifndef XATTR_ADD_OPT
2019 return setxattr(path, name, value, size, flags);
2020 #else
2021 int options = 0;
2022 return setxattr(path, name, value, size, 0, options);
2023 #endif
2024 #elif defined(HAVE_SETEA)
2025 return setea(path, name, value, size, flags);
2026 #elif defined(HAVE_EXTATTR_SET_FILE)
2027 char *s;
2028 int retval = 0;
2029 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2030 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2031 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2032 if (flags) {
2033 /* Check attribute existence */
2034 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
2035 if (retval < 0) {
2036 /* REPLACE attribute, that doesn't exist */
2037 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2038 errno = ENOATTR;
2039 return -1;
2041 /* Ignore other errors */
2043 else {
2044 /* CREATE attribute, that already exists */
2045 if (flags & XATTR_CREATE) {
2046 errno = EEXIST;
2047 return -1;
2051 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
2052 return (retval < 0) ? -1 : 0;
2053 #elif defined(HAVE_ATTR_SET)
2054 int myflags = 0;
2055 char *attrname = strchr(name,'.') + 1;
2057 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2058 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2059 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2061 return attr_set(path, attrname, (const char *)value, size, myflags);
2062 #else
2063 errno = ENOSYS;
2064 return -1;
2065 #endif
2068 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
2070 #if defined(HAVE_LSETXATTR)
2071 return lsetxattr(path, name, value, size, flags);
2072 #elif defined(HAVE_SETXATTR) && defined(XATTR_ADD_OPT)
2073 int options = XATTR_NOFOLLOW;
2074 return setxattr(path, name, value, size, 0, options);
2075 #elif defined(LSETEA)
2076 return lsetea(path, name, value, size, flags);
2077 #elif defined(HAVE_EXTATTR_SET_LINK)
2078 char *s;
2079 int retval = 0;
2080 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2081 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2082 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2083 if (flags) {
2084 /* Check attribute existence */
2085 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
2086 if (retval < 0) {
2087 /* REPLACE attribute, that doesn't exist */
2088 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2089 errno = ENOATTR;
2090 return -1;
2092 /* Ignore other errors */
2094 else {
2095 /* CREATE attribute, that already exists */
2096 if (flags & XATTR_CREATE) {
2097 errno = EEXIST;
2098 return -1;
2103 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
2104 return (retval < 0) ? -1 : 0;
2105 #elif defined(HAVE_ATTR_SET)
2106 int myflags = ATTR_DONTFOLLOW;
2107 char *attrname = strchr(name,'.') + 1;
2109 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2110 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2111 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2113 return attr_set(path, attrname, (const char *)value, size, myflags);
2114 #else
2115 errno = ENOSYS;
2116 return -1;
2117 #endif
2120 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
2122 #if defined(HAVE_FSETXATTR)
2123 #ifndef XATTR_ADD_OPT
2124 return fsetxattr(filedes, name, value, size, flags);
2125 #else
2126 int options = 0;
2127 return fsetxattr(filedes, name, value, size, 0, options);
2128 #endif
2129 #elif defined(HAVE_FSETEA)
2130 return fsetea(filedes, name, value, size, flags);
2131 #elif defined(HAVE_EXTATTR_SET_FD)
2132 char *s;
2133 int retval = 0;
2134 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
2135 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
2136 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
2137 if (flags) {
2138 /* Check attribute existence */
2139 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
2140 if (retval < 0) {
2141 /* REPLACE attribute, that doesn't exist */
2142 if (flags & XATTR_REPLACE && errno == ENOATTR) {
2143 errno = ENOATTR;
2144 return -1;
2146 /* Ignore other errors */
2148 else {
2149 /* CREATE attribute, that already exists */
2150 if (flags & XATTR_CREATE) {
2151 errno = EEXIST;
2152 return -1;
2156 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
2157 return (retval < 0) ? -1 : 0;
2158 #elif defined(HAVE_ATTR_SETF)
2159 int myflags = 0;
2160 char *attrname = strchr(name,'.') + 1;
2162 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
2163 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
2164 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
2166 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
2167 #else
2168 errno = ENOSYS;
2169 return -1;
2170 #endif
2173 /****************************************************************************
2174 Return the major devicenumber for UNIX extensions.
2175 ****************************************************************************/
2177 uint32 unix_dev_major(SMB_DEV_T dev)
2179 #if defined(HAVE_DEVICE_MAJOR_FN)
2180 return (uint32)major(dev);
2181 #else
2182 return (uint32)(dev >> 8);
2183 #endif
2186 /****************************************************************************
2187 Return the minor devicenumber for UNIX extensions.
2188 ****************************************************************************/
2190 uint32 unix_dev_minor(SMB_DEV_T dev)
2192 #if defined(HAVE_DEVICE_MINOR_FN)
2193 return (uint32)minor(dev);
2194 #else
2195 return (uint32)(dev & 0xff);
2196 #endif
2199 #if defined(WITH_AIO)
2201 /*******************************************************************
2202 An aio_read wrapper that will deal with 64-bit sizes.
2203 ********************************************************************/
2205 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2207 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2208 return aio_read64(aiocb);
2209 #elif defined(HAVE_AIO_READ)
2210 return aio_read(aiocb);
2211 #else
2212 errno = ENOSYS;
2213 return -1;
2214 #endif
2217 /*******************************************************************
2218 An aio_write wrapper that will deal with 64-bit sizes.
2219 ********************************************************************/
2221 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2223 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2224 return aio_write64(aiocb);
2225 #elif defined(HAVE_AIO_WRITE)
2226 return aio_write(aiocb);
2227 #else
2228 errno = ENOSYS;
2229 return -1;
2230 #endif
2233 /*******************************************************************
2234 An aio_return wrapper that will deal with 64-bit sizes.
2235 ********************************************************************/
2237 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2239 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2240 return aio_return64(aiocb);
2241 #elif defined(HAVE_AIO_RETURN)
2242 return aio_return(aiocb);
2243 #else
2244 errno = ENOSYS;
2245 return -1;
2246 #endif
2249 /*******************************************************************
2250 An aio_cancel wrapper that will deal with 64-bit sizes.
2251 ********************************************************************/
2253 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2255 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2256 return aio_cancel64(fd, aiocb);
2257 #elif defined(HAVE_AIO_CANCEL)
2258 return aio_cancel(fd, aiocb);
2259 #else
2260 errno = ENOSYS;
2261 return -1;
2262 #endif
2265 /*******************************************************************
2266 An aio_error wrapper that will deal with 64-bit sizes.
2267 ********************************************************************/
2269 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2271 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2272 return aio_error64(aiocb);
2273 #elif defined(HAVE_AIO_ERROR)
2274 return aio_error(aiocb);
2275 #else
2276 errno = ENOSYS;
2277 return -1;
2278 #endif
2281 /*******************************************************************
2282 An aio_fsync wrapper that will deal with 64-bit sizes.
2283 ********************************************************************/
2285 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2287 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2288 return aio_fsync64(op, aiocb);
2289 #elif defined(HAVE_AIO_FSYNC)
2290 return aio_fsync(op, aiocb);
2291 #else
2292 errno = ENOSYS;
2293 return -1;
2294 #endif
2297 /*******************************************************************
2298 An aio_fsync wrapper that will deal with 64-bit sizes.
2299 ********************************************************************/
2301 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2303 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2304 return aio_suspend64(cblist, n, timeout);
2305 #elif defined(HAVE_AIO_FSYNC)
2306 return aio_suspend(cblist, n, timeout);
2307 #else
2308 errno = ENOSYS;
2309 return -1;
2310 #endif
2312 #else /* !WITH_AIO */
2314 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2316 errno = ENOSYS;
2317 return -1;
2320 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2322 errno = ENOSYS;
2323 return -1;
2326 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2328 errno = ENOSYS;
2329 return -1;
2332 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2334 errno = ENOSYS;
2335 return -1;
2338 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2340 errno = ENOSYS;
2341 return -1;
2344 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2346 errno = ENOSYS;
2347 return -1;
2350 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2352 errno = ENOSYS;
2353 return -1;
2355 #endif /* WITH_AIO */
2357 int sys_getpeereid( int s, uid_t *uid)
2359 #if defined(HAVE_PEERCRED)
2360 struct ucred cred;
2361 socklen_t cred_len = sizeof(struct ucred);
2362 int ret;
2364 ret = getsockopt(s, SOL_SOCKET, SO_PEERCRED, (void *)&cred, &cred_len);
2365 if (ret != 0) {
2366 return -1;
2369 if (cred_len != sizeof(struct ucred)) {
2370 errno = EINVAL;
2371 return -1;
2374 *uid = cred.uid;
2375 return 0;
2376 #else
2377 errno = ENOSYS;
2378 return -1;
2379 #endif