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
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.
25 #ifdef HAVE_SYS_PRCTL_H
26 #include <sys/prctl.h>
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 usleep in case we don't have one.
48 ********************************************************************/
50 int sys_usleep(long usecs)
57 * We need this braindamage as the glibc usleep
58 * is not SPEC1170 complient... grumble... JRA.
61 if(usecs < 0 || usecs > 1000000) {
69 #else /* HAVE_USLEEP */
71 * Fake it with select...
74 tval.tv_usec = usecs/1000;
75 select(0,NULL,NULL,NULL,&tval);
77 #endif /* HAVE_USLEEP */
80 /*******************************************************************
81 A read wrapper that will deal with EINTR.
82 ********************************************************************/
84 ssize_t sys_read(int fd, void *buf, size_t count)
89 ret = read(fd, buf, count);
90 } while (ret == -1 && errno == EINTR);
94 /*******************************************************************
95 A write wrapper that will deal with EINTR.
96 ********************************************************************/
98 ssize_t sys_write(int fd, const void *buf, size_t count)
103 ret = write(fd, buf, count);
104 } while (ret == -1 && errno == EINTR);
109 /*******************************************************************
110 A pread wrapper that will deal with EINTR and 64-bit file offsets.
111 ********************************************************************/
113 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
114 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
119 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
120 ret = pread64(fd, buf, count, off);
122 ret = pread(fd, buf, count, off);
124 } while (ret == -1 && errno == EINTR);
129 /*******************************************************************
130 A write wrapper that will deal with EINTR and 64-bit file offsets.
131 ********************************************************************/
133 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
134 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
139 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
140 ret = pwrite64(fd, buf, count, off);
142 ret = pwrite(fd, buf, count, off);
144 } while (ret == -1 && errno == EINTR);
149 /*******************************************************************
150 A send wrapper that will deal with EINTR.
151 ********************************************************************/
153 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
158 ret = send(s, msg, len, flags);
159 } while (ret == -1 && errno == EINTR);
163 /*******************************************************************
164 A sendto wrapper that will deal with EINTR.
165 ********************************************************************/
167 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
172 ret = sendto(s, msg, len, flags, to, tolen);
173 } while (ret == -1 && errno == EINTR);
177 /*******************************************************************
178 A recvfrom wrapper that will deal with EINTR.
179 ********************************************************************/
181 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
186 ret = recvfrom(s, buf, len, flags, from, fromlen);
187 } while (ret == -1 && errno == EINTR);
191 /*******************************************************************
192 A fcntl wrapper that will deal with EINTR.
193 ********************************************************************/
195 int sys_fcntl_ptr(int fd, int cmd, void *arg)
200 ret = fcntl(fd, cmd, arg);
201 } while (ret == -1 && errno == EINTR);
205 /*******************************************************************
206 A fcntl wrapper that will deal with EINTR.
207 ********************************************************************/
209 int sys_fcntl_long(int fd, int cmd, long arg)
214 ret = fcntl(fd, cmd, arg);
215 } while (ret == -1 && errno == EINTR);
219 /*******************************************************************
220 A stat() wrapper that will deal with 64 bit filesizes.
221 ********************************************************************/
223 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
226 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
227 ret = stat64(fname, sbuf);
229 ret = stat(fname, sbuf);
231 /* we always want directories to appear zero size */
232 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
236 /*******************************************************************
237 An fstat() wrapper that will deal with 64 bit filesizes.
238 ********************************************************************/
240 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
243 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
244 ret = fstat64(fd, sbuf);
246 ret = fstat(fd, sbuf);
248 /* we always want directories to appear zero size */
249 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
253 /*******************************************************************
254 An lstat() wrapper that will deal with 64 bit filesizes.
255 ********************************************************************/
257 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
260 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
261 ret = lstat64(fname, sbuf);
263 ret = lstat(fname, sbuf);
265 /* we always want directories to appear zero size */
266 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
270 /*******************************************************************
271 An ftruncate() wrapper that will deal with 64 bit filesizes.
272 ********************************************************************/
274 int sys_ftruncate(int fd, SMB_OFF_T offset)
276 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
277 return ftruncate64(fd, offset);
279 return ftruncate(fd, offset);
283 /*******************************************************************
284 An lseek() wrapper that will deal with 64 bit filesizes.
285 ********************************************************************/
287 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
289 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
290 return lseek64(fd, offset, whence);
292 return lseek(fd, offset, whence);
296 /*******************************************************************
297 An fseek() wrapper that will deal with 64 bit filesizes.
298 ********************************************************************/
300 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
302 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
303 return fseek64(fp, offset, whence);
304 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
305 return fseeko64(fp, offset, whence);
307 return fseek(fp, offset, whence);
311 /*******************************************************************
312 An ftell() wrapper that will deal with 64 bit filesizes.
313 ********************************************************************/
315 SMB_OFF_T sys_ftell(FILE *fp)
317 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
318 return (SMB_OFF_T)ftell64(fp);
319 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
320 return (SMB_OFF_T)ftello64(fp);
322 return (SMB_OFF_T)ftell(fp);
326 /*******************************************************************
327 A creat() wrapper that will deal with 64 bit filesizes.
328 ********************************************************************/
330 int sys_creat(const char *path, mode_t mode)
332 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
333 return creat64(path, mode);
336 * If creat64 isn't defined then ensure we call a potential open64.
339 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
343 /*******************************************************************
344 An open() wrapper that will deal with 64 bit filesizes.
345 ********************************************************************/
347 int sys_open(const char *path, int oflag, mode_t mode)
349 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
350 return open64(path, oflag, mode);
352 return open(path, oflag, mode);
356 /*******************************************************************
357 An fopen() wrapper that will deal with 64 bit filesizes.
358 ********************************************************************/
360 FILE *sys_fopen(const char *path, const char *type)
362 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
363 return fopen64(path, type);
365 return fopen(path, type);
369 /*******************************************************************
370 An opendir wrapper that will deal with 64 bit filesizes.
371 ********************************************************************/
373 SMB_STRUCT_DIR *sys_opendir(const char *name)
375 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
376 return opendir64(name);
378 return opendir(name);
382 /*******************************************************************
383 A readdir wrapper that will deal with 64 bit filesizes.
384 ********************************************************************/
386 SMB_STRUCT_DIRENT *sys_readdir(SMB_STRUCT_DIR *dirp)
388 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
389 return readdir64(dirp);
391 return readdir(dirp);
395 /*******************************************************************
396 A seekdir wrapper that will deal with 64 bit filesizes.
397 ********************************************************************/
399 void sys_seekdir(SMB_STRUCT_DIR *dirp, long offset)
401 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
402 seekdir64(dirp, offset);
404 seekdir(dirp, offset);
408 /*******************************************************************
409 A telldir wrapper that will deal with 64 bit filesizes.
410 ********************************************************************/
412 long sys_telldir(SMB_STRUCT_DIR *dirp)
414 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
415 return (long)telldir64(dirp);
417 return (long)telldir(dirp);
421 /*******************************************************************
422 A rewinddir wrapper that will deal with 64 bit filesizes.
423 ********************************************************************/
425 void sys_rewinddir(SMB_STRUCT_DIR *dirp)
427 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
434 /*******************************************************************
435 A close wrapper that will deal with 64 bit filesizes.
436 ********************************************************************/
438 int sys_closedir(SMB_STRUCT_DIR *dirp)
440 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
441 return closedir64(dirp);
443 return closedir(dirp);
447 /*******************************************************************
448 An mknod() wrapper that will deal with 64 bit filesizes.
449 ********************************************************************/
451 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
453 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
454 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
455 return mknod64(path, mode, dev);
457 return mknod(path, mode, dev);
460 /* No mknod system call. */
466 /*******************************************************************
467 Wrapper for realpath.
468 ********************************************************************/
470 char *sys_realpath(const char *path, char *resolved_path)
472 #if defined(HAVE_REALPATH)
473 return realpath(path, resolved_path);
475 /* As realpath is not a system call we can't return ENOSYS. */
481 /*******************************************************************
482 The wait() calls vary between systems
483 ********************************************************************/
485 int sys_waitpid(pid_t pid,int *status,int options)
488 return waitpid(pid,status,options);
489 #else /* HAVE_WAITPID */
490 return wait4(pid, status, options, NULL);
491 #endif /* HAVE_WAITPID */
494 /*******************************************************************
495 System wrapper for getwd
496 ********************************************************************/
498 char *sys_getwd(char *s)
502 wd = (char *)getcwd(s, sizeof (pstring));
504 wd = (char *)getwd(s);
509 /*******************************************************************
510 system wrapper for symlink
511 ********************************************************************/
513 int sys_symlink(const char *oldpath, const char *newpath)
519 return symlink(oldpath, newpath);
523 /*******************************************************************
524 system wrapper for readlink
525 ********************************************************************/
527 int sys_readlink(const char *path, char *buf, size_t bufsiz)
529 #ifndef HAVE_READLINK
533 return readlink(path, buf, bufsiz);
537 /*******************************************************************
538 system wrapper for link
539 ********************************************************************/
541 int sys_link(const char *oldpath, const char *newpath)
547 return link(oldpath, newpath);
551 /*******************************************************************
552 chown isn't used much but OS/2 doesn't have it
553 ********************************************************************/
555 int sys_chown(const char *fname,uid_t uid,gid_t gid)
560 DEBUG(1,("WARNING: no chown!\n"));
566 return(chown(fname,uid,gid));
570 /*******************************************************************
571 os/2 also doesn't have chroot
572 ********************************************************************/
573 int sys_chroot(const char *dname)
578 DEBUG(1,("WARNING: no chroot!\n"));
584 return(chroot(dname));
588 /**************************************************************************
589 A wrapper for gethostbyname() that tries avoids looking up hostnames
590 in the root domain, which can cause dial-on-demand links to come up for no
592 ****************************************************************************/
594 struct hostent *sys_gethostbyname(const char *name)
596 #ifdef REDUCE_ROOT_DNS_LOOKUPS
597 char query[256], hostname[256];
600 /* Does this name have any dots in it? If so, make no change */
602 if (strchr_m(name, '.'))
603 return(gethostbyname(name));
605 /* Get my hostname, which should have domain name
606 attached. If not, just do the gethostname on the
610 gethostname(hostname, sizeof(hostname) - 1);
611 hostname[sizeof(hostname) - 1] = 0;
612 if ((domain = strchr_m(hostname, '.')) == NULL)
613 return(gethostbyname(name));
615 /* Attach domain name to query and do modified query.
616 If names too large, just do gethostname on the
620 if((strlen(name) + strlen(domain)) >= sizeof(query))
621 return(gethostbyname(name));
623 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
624 return(gethostbyname(query));
625 #else /* REDUCE_ROOT_DNS_LOOKUPS */
626 return(gethostbyname(name));
627 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
631 #if defined(HAVE_POSIX_CAPABILITIES)
633 #ifdef HAVE_SYS_CAPABILITY_H
635 #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
636 #define _I386_STATFS_H
637 #define _PPC_STATFS_H
638 #define BROKEN_REDHAT_7_STATFS_WORKAROUND
641 #include <sys/capability.h>
643 #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
644 #undef _I386_STATFS_H
646 #undef BROKEN_REDHAT_7_STATFS_WORKAROUND
649 #endif /* HAVE_SYS_CAPABILITY_H */
651 /**************************************************************************
652 Try and abstract process capabilities (for systems that have them).
653 ****************************************************************************/
655 /* Set the POSIX capabilities needed for the given purpose into the effective
656 * capability set of the current process. Make sure they are always removed
657 * from the inheritable set, because there is no circumstance in which our
658 * children should inherit our elevated privileges.
660 static BOOL set_process_capability(enum smbd_capability capability,
663 cap_value_t cap_vals[2] = {0};
664 int num_cap_vals = 0;
668 #if defined(HAVE_PRCTL) && defined(PR_GET_KEEPCAPS) && defined(PR_SET_KEEPCAPS)
669 /* On Linux, make sure that any capabilities we grab are sticky
670 * across UID changes. We expect that this would allow us to keep both
671 * the effective and permitted capability sets, but as of circa 2.6.16,
672 * only the permitted set is kept. It is a bug (which we work around)
673 * that the effective set is lost, but we still require the effective
676 if (!prctl(PR_GET_KEEPCAPS)) {
677 prctl(PR_SET_KEEPCAPS, 1);
681 cap = cap_get_proc();
683 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
688 switch (capability) {
689 case KERNEL_OPLOCK_CAPABILITY:
690 #ifdef CAP_NETWORK_MGT
691 /* IRIX has CAP_NETWORK_MGT for oplocks. */
692 cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
695 case DMAPI_ACCESS_CAPABILITY:
696 #ifdef CAP_DEVICE_MGT
697 /* IRIX has CAP_DEVICE_MGT for DMAPI access. */
698 cap_vals[num_cap_vals++] = CAP_DEVICE_MGT;
700 /* Linux has CAP_MKNOD for DMAPI access. */
701 cap_vals[num_cap_vals++] = CAP_MKNOD;
706 SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
708 if (num_cap_vals == 0) {
713 cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
714 enable ? CAP_SET : CAP_CLEAR);
716 /* We never want to pass capabilities down to our children, so make
717 * sure they are not inherited.
719 cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
721 if (cap_set_proc(cap) == -1) {
722 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
732 #endif /* HAVE_POSIX_CAPABILITIES */
734 /****************************************************************************
735 Gain the oplock capability from the kernel if possible.
736 ****************************************************************************/
738 void set_effective_capability(enum smbd_capability capability)
740 #if defined(HAVE_POSIX_CAPABILITIES)
741 set_process_capability(capability, True);
742 #endif /* HAVE_POSIX_CAPABILITIES */
745 void drop_effective_capability(enum smbd_capability capability)
747 #if defined(HAVE_POSIX_CAPABILITIES)
748 set_process_capability(capability, False);
749 #endif /* HAVE_POSIX_CAPABILITIES */
752 /**************************************************************************
753 Wrapper for random().
754 ****************************************************************************/
756 long sys_random(void)
758 #if defined(HAVE_RANDOM)
759 return (long)random();
760 #elif defined(HAVE_RAND)
763 DEBUG(0,("Error - no random function available !\n"));
768 /**************************************************************************
769 Wrapper for srandom().
770 ****************************************************************************/
772 void sys_srandom(unsigned int seed)
774 #if defined(HAVE_SRANDOM)
776 #elif defined(HAVE_SRAND)
779 DEBUG(0,("Error - no srandom function available !\n"));
784 /**************************************************************************
785 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
786 ****************************************************************************/
790 #if defined(SYSCONF_SC_NGROUPS_MAX)
791 int ret = sysconf(_SC_NGROUPS_MAX);
792 return (ret == -1) ? NGROUPS_MAX : ret;
798 /**************************************************************************
799 Wrapper for getgroups. Deals with broken (int) case.
800 ****************************************************************************/
802 int sys_getgroups(int setlen, gid_t *gidset)
804 #if !defined(HAVE_BROKEN_GETGROUPS)
805 return getgroups(setlen, gidset);
813 return getgroups(setlen, &gid);
817 * Broken case. We need to allocate a
818 * GID_T array of size setlen.
827 setlen = groups_max();
829 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
830 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
834 if((ngroups = getgroups(setlen, group_list)) < 0) {
835 int saved_errno = errno;
836 SAFE_FREE(group_list);
841 for(i = 0; i < ngroups; i++)
842 gidset[i] = (gid_t)group_list[i];
844 SAFE_FREE(group_list);
846 #endif /* HAVE_BROKEN_GETGROUPS */
850 /**************************************************************************
851 Wrapper for setgroups. Deals with broken (int) case. Automatically used
852 if we have broken getgroups.
853 ****************************************************************************/
855 int sys_setgroups(int setlen, gid_t *gidset)
857 #if !defined(HAVE_SETGROUPS)
860 #endif /* HAVE_SETGROUPS */
862 #if !defined(HAVE_BROKEN_GETGROUPS)
863 return setgroups(setlen, gidset);
872 if (setlen < 0 || setlen > groups_max()) {
878 * Broken case. We need to allocate a
879 * GID_T array of size setlen.
882 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
883 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
887 for(i = 0; i < setlen; i++)
888 group_list[i] = (GID_T) gidset[i];
890 if(setgroups(setlen, group_list) != 0) {
891 int saved_errno = errno;
892 SAFE_FREE(group_list);
897 SAFE_FREE(group_list);
899 #endif /* HAVE_BROKEN_GETGROUPS */
902 /**************************************************************************
903 Wrappers for setpwent(), getpwent() and endpwent()
904 ****************************************************************************/
906 void sys_setpwent(void)
911 struct passwd *sys_getpwent(void)
916 void sys_endpwent(void)
921 /**************************************************************************
922 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
923 ****************************************************************************/
925 struct passwd *sys_getpwnam(const char *name)
927 return getpwnam(name);
930 struct passwd *sys_getpwuid(uid_t uid)
932 return getpwuid(uid);
935 struct group *sys_getgrnam(const char *name)
937 return getgrnam(name);
940 struct group *sys_getgrgid(gid_t gid)
942 return getgrgid(gid);
945 #if 0 /* NOT CURRENTLY USED - JRA */
946 /**************************************************************************
947 The following are the UNICODE versions of *all* system interface functions
948 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
949 which currently are left as ascii as they are not used other than in name
951 ****************************************************************************/
953 /**************************************************************************
954 Wide stat. Just narrow and call sys_xxx.
955 ****************************************************************************/
957 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
960 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
963 /**************************************************************************
964 Wide lstat. Just narrow and call sys_xxx.
965 ****************************************************************************/
967 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
970 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
973 /**************************************************************************
974 Wide creat. Just narrow and call sys_xxx.
975 ****************************************************************************/
977 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
980 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
983 /**************************************************************************
984 Wide open. Just narrow and call sys_xxx.
985 ****************************************************************************/
987 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
990 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
993 /**************************************************************************
994 Wide fopen. Just narrow and call sys_xxx.
995 ****************************************************************************/
997 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
1000 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
1003 /**************************************************************************
1004 Wide opendir. Just narrow and call sys_xxx.
1005 ****************************************************************************/
1007 SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname)
1010 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
1013 /**************************************************************************
1014 Wide readdir. Return a structure pointer containing a wide filename.
1015 ****************************************************************************/
1017 SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp)
1019 static SMB_STRUCT_WDIRENT retval;
1020 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
1026 * The only POSIX defined member of this struct is d_name.
1029 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
1034 /**************************************************************************
1035 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
1036 ****************************************************************************/
1038 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
1041 char *p = sys_getwd(fname);
1046 return unix_to_unicode(s, p, sizeof(wpstring));
1049 /**************************************************************************
1050 Wide chown. Just narrow and call sys_xxx.
1051 ****************************************************************************/
1053 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
1056 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
1059 /**************************************************************************
1060 Wide chroot. Just narrow and call sys_xxx.
1061 ****************************************************************************/
1063 int wsys_chroot(const smb_ucs2_t *wfname)
1066 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
1069 /**************************************************************************
1070 Wide getpwnam. Return a structure pointer containing wide names.
1071 ****************************************************************************/
1073 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1075 static SMB_STRUCT_WPASSWD retval;
1077 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1082 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1083 retval.pw_passwd = pwret->pw_passwd;
1084 retval.pw_uid = pwret->pw_uid;
1085 retval.pw_gid = pwret->pw_gid;
1086 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1087 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1088 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1093 /**************************************************************************
1094 Wide getpwuid. Return a structure pointer containing wide names.
1095 ****************************************************************************/
1097 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1099 static SMB_STRUCT_WPASSWD retval;
1100 struct passwd *pwret = sys_getpwuid(uid);
1105 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1106 retval.pw_passwd = pwret->pw_passwd;
1107 retval.pw_uid = pwret->pw_uid;
1108 retval.pw_gid = pwret->pw_gid;
1109 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1110 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1111 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1115 #endif /* NOT CURRENTLY USED - JRA */
1117 /**************************************************************************
1118 Extract a command into an arg list. Uses a static pstring for storage.
1119 Caller frees returned arg list (which contains pointers into the static pstring).
1120 ****************************************************************************/
1122 static char **extract_args(const char *command)
1124 static pstring trunc_cmd;
1130 pstrcpy(trunc_cmd, command);
1132 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1141 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1144 if((argl = (char **)SMB_MALLOC((argcl + 1) * sizeof(char *))) == NULL)
1148 * Now do the extraction.
1151 pstrcpy(trunc_cmd, command);
1153 ptr = strtok(trunc_cmd, " \t");
1157 while((ptr = strtok(NULL, " \t")) != NULL)
1164 /**************************************************************************
1165 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1166 a sys_getpid() that only does a system call *once*.
1167 ****************************************************************************/
1169 static pid_t mypid = (pid_t)-1;
1171 pid_t sys_fork(void)
1173 pid_t forkret = fork();
1175 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1181 /**************************************************************************
1182 Wrapper for getpid. Ensures we only do a system call *once*.
1183 ****************************************************************************/
1185 pid_t sys_getpid(void)
1187 if (mypid == (pid_t)-1)
1193 /**************************************************************************
1194 Wrapper for popen. Safer as it doesn't search a path.
1195 Modified from the glibc sources.
1196 modified by tridge to return a file descriptor. We must kick our FILE* habit
1197 ****************************************************************************/
1199 typedef struct _popen_list
1203 struct _popen_list *next;
1206 static popen_list *popen_chain;
1208 int sys_popen(const char *command)
1210 int parent_end, child_end;
1212 popen_list *entry = NULL;
1215 if (pipe(pipe_fds) < 0)
1218 parent_end = pipe_fds[0];
1219 child_end = pipe_fds[1];
1226 if((entry = SMB_MALLOC_P(popen_list)) == NULL)
1229 ZERO_STRUCTP(entry);
1232 * Extract the command and args into a NULL terminated array.
1235 if(!(argl = extract_args(command)))
1238 entry->child_pid = sys_fork();
1240 if (entry->child_pid == -1) {
1244 if (entry->child_pid == 0) {
1250 int child_std_end = STDOUT_FILENO;
1254 if (child_end != child_std_end) {
1255 dup2 (child_end, child_std_end);
1260 * POSIX.2: "popen() shall ensure that any streams from previous
1261 * popen() calls that remain open in the parent process are closed
1262 * in the new child process."
1265 for (p = popen_chain; p; p = p->next)
1268 execv(argl[0], argl);
1279 /* Link into popen_chain. */
1280 entry->next = popen_chain;
1281 popen_chain = entry;
1282 entry->fd = parent_end;
1295 /**************************************************************************
1296 Wrapper for pclose. Modified from the glibc sources.
1297 ****************************************************************************/
1299 int sys_pclose(int fd)
1302 popen_list **ptr = &popen_chain;
1303 popen_list *entry = NULL;
1307 /* Unlink from popen_chain. */
1308 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1309 if ((*ptr)->fd == fd) {
1311 *ptr = (*ptr)->next;
1317 if (status < 0 || close(entry->fd) < 0)
1321 * As Samba is catching and eating child process
1322 * exits we don't really care about the child exit
1323 * code, a -1 with errno = ECHILD will do fine for us.
1327 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1328 } while (wait_pid == -1 && errno == EINTR);
1337 /**************************************************************************
1338 Wrappers for dlopen, dlsym, dlclose.
1339 ****************************************************************************/
1341 void *sys_dlopen(const char *name, int flags)
1343 #if defined(HAVE_DLOPEN)
1344 return dlopen(name, flags);
1350 void *sys_dlsym(void *handle, const char *symbol)
1352 #if defined(HAVE_DLSYM)
1353 return dlsym(handle, symbol);
1359 int sys_dlclose (void *handle)
1361 #if defined(HAVE_DLCLOSE)
1362 return dlclose(handle);
1368 const char *sys_dlerror(void)
1370 #if defined(HAVE_DLERROR)
1377 int sys_dup2(int oldfd, int newfd)
1379 #if defined(HAVE_DUP2)
1380 return dup2(oldfd, newfd);
1387 /**************************************************************************
1388 Wrapper for Admin Logs.
1389 ****************************************************************************/
1391 void sys_adminlog(int priority, const char *format_str, ...)
1395 char *msgbuf = NULL;
1397 va_start( ap, format_str );
1398 ret = vasprintf( &msgbuf, format_str, ap );
1404 #if defined(HAVE_SYSLOG)
1405 syslog( priority, "%s", msgbuf );
1407 DEBUG(0,("%s", msgbuf ));
1412 /**************************************************************************
1413 Wrappers for extented attribute calls. Based on the Linux package with
1414 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1415 ****************************************************************************/
1417 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1419 #if defined(HAVE_GETXATTR)
1420 return getxattr(path, name, value, size);
1421 #elif defined(HAVE_GETEA)
1422 return getea(path, name, value, size);
1423 #elif defined(HAVE_EXTATTR_GET_FILE)
1426 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1427 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1428 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1430 * The BSD implementation has a nasty habit of silently truncating
1431 * the returned value to the size of the buffer, so we have to check
1432 * that the buffer is large enough to fit the returned value.
1434 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1439 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
1443 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
1445 #elif defined(HAVE_ATTR_GET)
1446 int retval, flags = 0;
1447 int valuelength = (int)size;
1448 char *attrname = strchr(name,'.') + 1;
1450 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1452 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1454 return retval ? retval : valuelength;
1461 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1463 #if defined(HAVE_LGETXATTR)
1464 return lgetxattr(path, name, value, size);
1465 #elif defined(HAVE_LGETEA)
1466 return lgetea(path, name, value, size);
1467 #elif defined(HAVE_EXTATTR_GET_LINK)
1470 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1471 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1472 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1474 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1479 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
1483 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
1485 #elif defined(HAVE_ATTR_GET)
1486 int retval, flags = ATTR_DONTFOLLOW;
1487 int valuelength = (int)size;
1488 char *attrname = strchr(name,'.') + 1;
1490 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1492 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1494 return retval ? retval : valuelength;
1501 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1503 #if defined(HAVE_FGETXATTR)
1504 return fgetxattr(filedes, name, value, size);
1505 #elif defined(HAVE_FGETEA)
1506 return fgetea(filedes, name, value, size);
1507 #elif defined(HAVE_EXTATTR_GET_FD)
1510 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1511 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1512 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1514 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
1519 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
1523 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
1525 #elif defined(HAVE_ATTR_GETF)
1526 int retval, flags = 0;
1527 int valuelength = (int)size;
1528 char *attrname = strchr(name,'.') + 1;
1530 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1532 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1534 return retval ? retval : valuelength;
1541 #if defined(HAVE_EXTATTR_LIST_FILE)
1543 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1551 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
1552 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
1560 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
1562 ssize_t list_size, total_size = 0;
1565 /* Iterate through extattr(2) namespaces */
1566 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
1568 #if defined(HAVE_EXTATTR_LIST_FILE)
1570 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
1573 #if defined(HAVE_EXTATTR_LIST_LINK)
1575 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
1578 #if defined(HAVE_EXTATTR_LIST_FD)
1580 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
1587 /* Some error happend. Errno should be set by the previous call */
1593 /* XXX: Call with an empty buffer may be used to calculate
1594 necessary buffer size. Unfortunately, we can't say, how
1595 many attributes were returned, so here is the potential
1596 problem with the emulation.
1599 /* Take the worse case of one char attribute names -
1600 two bytes per name plus one more for sanity.
1602 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
1605 /* Count necessary offset to fit namespace prefixes */
1607 for(i = 0; i < list_size; i += list[i] + 1)
1608 len += extattr[t].len;
1610 total_size += list_size + len;
1611 /* Buffer is too small to fit the results */
1612 if(total_size > size) {
1616 /* Shift results back, so we can prepend prefixes */
1617 buf = memmove(list + len, list, list_size);
1619 for(i = 0; i < list_size; i += len + 1) {
1621 strncpy(list, extattr[t].name, extattr[t].len + 1);
1622 list += extattr[t].len;
1623 strncpy(list, buf + i + 1, len);
1634 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1635 static char attr_buffer[ATTR_MAX_VALUELEN];
1637 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1639 int retval = 0, index;
1640 attrlist_cursor_t *cursor = 0;
1642 attrlist_t * al = (attrlist_t *)attr_buffer;
1644 size_t ent_size, left = size;
1649 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1651 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1653 for (index = 0; index < al->al_count; index++) {
1654 ae = ATTR_ENTRY(attr_buffer, index);
1655 ent_size = strlen(ae->a_name) + sizeof("user.");
1656 if (left >= ent_size) {
1657 strncpy(bp, "user.", sizeof("user."));
1658 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1666 total_size += ent_size;
1668 if (al->al_more == 0) break;
1675 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1677 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1679 for (index = 0; index < al->al_count; index++) {
1680 ae = ATTR_ENTRY(attr_buffer, index);
1681 ent_size = strlen(ae->a_name) + sizeof("system.");
1682 if (left >= ent_size) {
1683 strncpy(bp, "system.", sizeof("system."));
1684 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1692 total_size += ent_size;
1694 if (al->al_more == 0) break;
1697 return (ssize_t)(retval ? retval : total_size);
1702 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1704 #if defined(HAVE_LISTXATTR)
1705 return listxattr(path, list, size);
1706 #elif defined(HAVE_LISTEA)
1707 return listea(path, list, size);
1708 #elif defined(HAVE_EXTATTR_LIST_FILE)
1711 return bsd_attr_list(0, arg, list, size);
1712 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1713 return irix_attr_list(path, 0, list, size, 0);
1720 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1722 #if defined(HAVE_LLISTXATTR)
1723 return llistxattr(path, list, size);
1724 #elif defined(HAVE_LLISTEA)
1725 return llistea(path, list, size);
1726 #elif defined(HAVE_EXTATTR_LIST_LINK)
1729 return bsd_attr_list(1, arg, list, size);
1730 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1731 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1738 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1740 #if defined(HAVE_FLISTXATTR)
1741 return flistxattr(filedes, list, size);
1742 #elif defined(HAVE_FLISTEA)
1743 return flistea(filedes, list, size);
1744 #elif defined(HAVE_EXTATTR_LIST_FD)
1746 arg.filedes = filedes;
1747 return bsd_attr_list(2, arg, list, size);
1748 #elif defined(HAVE_ATTR_LISTF)
1749 return irix_attr_list(NULL, filedes, list, size, 0);
1756 int sys_removexattr (const char *path, const char *name)
1758 #if defined(HAVE_REMOVEXATTR)
1759 return removexattr(path, name);
1760 #elif defined(HAVE_REMOVEEA)
1761 return removeea(path, name);
1762 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1764 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1765 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1766 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1768 return extattr_delete_file(path, attrnamespace, attrname);
1769 #elif defined(HAVE_ATTR_REMOVE)
1771 char *attrname = strchr(name,'.') + 1;
1773 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1775 return attr_remove(path, attrname, flags);
1782 int sys_lremovexattr (const char *path, const char *name)
1784 #if defined(HAVE_LREMOVEXATTR)
1785 return lremovexattr(path, name);
1786 #elif defined(HAVE_LREMOVEEA)
1787 return lremoveea(path, name);
1788 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1790 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1791 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1792 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1794 return extattr_delete_link(path, attrnamespace, attrname);
1795 #elif defined(HAVE_ATTR_REMOVE)
1796 int flags = ATTR_DONTFOLLOW;
1797 char *attrname = strchr(name,'.') + 1;
1799 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1801 return attr_remove(path, attrname, flags);
1808 int sys_fremovexattr (int filedes, const char *name)
1810 #if defined(HAVE_FREMOVEXATTR)
1811 return fremovexattr(filedes, name);
1812 #elif defined(HAVE_FREMOVEEA)
1813 return fremoveea(filedes, name);
1814 #elif defined(HAVE_EXTATTR_DELETE_FD)
1816 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1817 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1818 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1820 return extattr_delete_fd(filedes, attrnamespace, attrname);
1821 #elif defined(HAVE_ATTR_REMOVEF)
1823 char *attrname = strchr(name,'.') + 1;
1825 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1827 return attr_removef(filedes, attrname, flags);
1834 #if !defined(HAVE_SETXATTR)
1835 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1836 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1839 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1841 #if defined(HAVE_SETXATTR)
1842 return setxattr(path, name, value, size, flags);
1843 #elif defined(HAVE_SETEA)
1844 return setea(path, name, value, size, flags);
1845 #elif defined(HAVE_EXTATTR_SET_FILE)
1848 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1849 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1850 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1852 /* Check attribute existence */
1853 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
1855 /* REPLACE attribute, that doesn't exist */
1856 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1860 /* Ignore other errors */
1863 /* CREATE attribute, that already exists */
1864 if (flags & XATTR_CREATE) {
1870 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
1871 return (retval < 0) ? -1 : 0;
1872 #elif defined(HAVE_ATTR_SET)
1874 char *attrname = strchr(name,'.') + 1;
1876 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1877 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1878 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1880 return attr_set(path, attrname, (const char *)value, size, myflags);
1887 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1889 #if defined(HAVE_LSETXATTR)
1890 return lsetxattr(path, name, value, size, flags);
1891 #elif defined(LSETEA)
1892 return lsetea(path, name, value, size, flags);
1893 #elif defined(HAVE_EXTATTR_SET_LINK)
1896 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1897 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1898 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1900 /* Check attribute existence */
1901 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
1903 /* REPLACE attribute, that doesn't exist */
1904 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1908 /* Ignore other errors */
1911 /* CREATE attribute, that already exists */
1912 if (flags & XATTR_CREATE) {
1919 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
1920 return (retval < 0) ? -1 : 0;
1921 #elif defined(HAVE_ATTR_SET)
1922 int myflags = ATTR_DONTFOLLOW;
1923 char *attrname = strchr(name,'.') + 1;
1925 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1926 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1927 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1929 return attr_set(path, attrname, (const char *)value, size, myflags);
1936 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
1938 #if defined(HAVE_FSETXATTR)
1939 return fsetxattr(filedes, name, value, size, flags);
1940 #elif defined(HAVE_FSETEA)
1941 return fsetea(filedes, name, value, size, flags);
1942 #elif defined(HAVE_EXTATTR_SET_FD)
1945 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1946 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1947 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1949 /* Check attribute existence */
1950 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
1952 /* REPLACE attribute, that doesn't exist */
1953 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1957 /* Ignore other errors */
1960 /* CREATE attribute, that already exists */
1961 if (flags & XATTR_CREATE) {
1967 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
1968 return (retval < 0) ? -1 : 0;
1969 #elif defined(HAVE_ATTR_SETF)
1971 char *attrname = strchr(name,'.') + 1;
1973 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1974 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1975 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1977 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
1984 /****************************************************************************
1985 Return the major devicenumber for UNIX extensions.
1986 ****************************************************************************/
1988 uint32 unix_dev_major(SMB_DEV_T dev)
1990 #if defined(HAVE_DEVICE_MAJOR_FN)
1991 return (uint32)major(dev);
1993 return (uint32)(dev >> 8);
1997 /****************************************************************************
1998 Return the minor devicenumber for UNIX extensions.
1999 ****************************************************************************/
2001 uint32 unix_dev_minor(SMB_DEV_T dev)
2003 #if defined(HAVE_DEVICE_MINOR_FN)
2004 return (uint32)minor(dev);
2006 return (uint32)(dev & 0xff);
2010 #if defined(WITH_AIO)
2012 /*******************************************************************
2013 An aio_read wrapper that will deal with 64-bit sizes.
2014 ********************************************************************/
2016 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2018 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
2019 return aio_read64(aiocb);
2020 #elif defined(HAVE_AIO_READ)
2021 return aio_read(aiocb);
2028 /*******************************************************************
2029 An aio_write wrapper that will deal with 64-bit sizes.
2030 ********************************************************************/
2032 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2034 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2035 return aio_write64(aiocb);
2036 #elif defined(HAVE_AIO_WRITE)
2037 return aio_write(aiocb);
2044 /*******************************************************************
2045 An aio_return wrapper that will deal with 64-bit sizes.
2046 ********************************************************************/
2048 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2050 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2051 return aio_return64(aiocb);
2052 #elif defined(HAVE_AIO_RETURN)
2053 return aio_return(aiocb);
2060 /*******************************************************************
2061 An aio_cancel wrapper that will deal with 64-bit sizes.
2062 ********************************************************************/
2064 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2066 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2067 return aio_cancel64(fd, aiocb);
2068 #elif defined(HAVE_AIO_CANCEL)
2069 return aio_cancel(fd, aiocb);
2076 /*******************************************************************
2077 An aio_error wrapper that will deal with 64-bit sizes.
2078 ********************************************************************/
2080 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2082 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2083 return aio_error64(aiocb);
2084 #elif defined(HAVE_AIO_ERROR)
2085 return aio_error(aiocb);
2092 /*******************************************************************
2093 An aio_fsync wrapper that will deal with 64-bit sizes.
2094 ********************************************************************/
2096 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2098 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2099 return aio_fsync64(op, aiocb);
2100 #elif defined(HAVE_AIO_FSYNC)
2101 return aio_fsync(op, aiocb);
2108 /*******************************************************************
2109 An aio_fsync wrapper that will deal with 64-bit sizes.
2110 ********************************************************************/
2112 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2114 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2115 return aio_suspend64(cblist, n, timeout);
2116 #elif defined(HAVE_AIO_FSYNC)
2117 return aio_suspend(cblist, n, timeout);
2123 #else /* !WITH_AIO */
2125 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2131 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2137 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2143 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2149 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2155 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2161 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2166 #endif /* WITH_AIO */