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.
26 The idea is that this file will eventually have wrappers around all
27 important system calls in samba. The aims are:
29 - to enable easier porting by putting OS dependent stuff in here
31 - to allow for hooks into other "pseudo-filesystems"
33 - to allow easier integration of things like the japanese extensions
35 - to support the philosophy of Samba to expose the features of
36 the OS within the SMB model. In general whatever file/printer/variable
37 expansions/etc make sense to the OS should be acceptable to Samba.
42 /*******************************************************************
43 A wrapper for usleep in case we don't have one.
44 ********************************************************************/
46 int sys_usleep(long usecs)
53 * We need this braindamage as the glibc usleep
54 * is not SPEC1170 complient... grumble... JRA.
57 if(usecs < 0 || usecs > 1000000) {
65 #else /* HAVE_USLEEP */
67 * Fake it with select...
70 tval.tv_usec = usecs/1000;
71 select(0,NULL,NULL,NULL,&tval);
73 #endif /* HAVE_USLEEP */
76 /*******************************************************************
77 A read wrapper that will deal with EINTR.
78 ********************************************************************/
80 ssize_t sys_read(int fd, void *buf, size_t count)
85 ret = read(fd, buf, count);
86 } while (ret == -1 && errno == EINTR);
90 /*******************************************************************
91 A write wrapper that will deal with EINTR.
92 ********************************************************************/
94 ssize_t sys_write(int fd, const void *buf, size_t count)
99 ret = write(fd, buf, count);
100 } while (ret == -1 && errno == EINTR);
105 /*******************************************************************
106 A pread wrapper that will deal with EINTR and 64-bit file offsets.
107 ********************************************************************/
109 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
110 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
115 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
116 ret = pread64(fd, buf, count, off);
118 ret = pread(fd, buf, count, off);
120 } while (ret == -1 && errno == EINTR);
125 /*******************************************************************
126 A write wrapper that will deal with EINTR and 64-bit file offsets.
127 ********************************************************************/
129 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
130 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
135 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
136 ret = pwrite64(fd, buf, count, off);
138 ret = pwrite(fd, buf, count, off);
140 } while (ret == -1 && errno == EINTR);
145 /*******************************************************************
146 A send wrapper that will deal with EINTR.
147 ********************************************************************/
149 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
154 ret = send(s, msg, len, flags);
155 } while (ret == -1 && errno == EINTR);
159 /*******************************************************************
160 A sendto wrapper that will deal with EINTR.
161 ********************************************************************/
163 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
168 ret = sendto(s, msg, len, flags, to, tolen);
169 } while (ret == -1 && errno == EINTR);
173 /*******************************************************************
174 A recvfrom wrapper that will deal with EINTR.
175 ********************************************************************/
177 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
182 ret = recvfrom(s, buf, len, flags, from, fromlen);
183 } while (ret == -1 && errno == EINTR);
187 /*******************************************************************
188 A fcntl wrapper that will deal with EINTR.
189 ********************************************************************/
191 int sys_fcntl_ptr(int fd, int cmd, void *arg)
196 ret = fcntl(fd, cmd, arg);
197 } while (ret == -1 && errno == EINTR);
201 /*******************************************************************
202 A fcntl wrapper that will deal with EINTR.
203 ********************************************************************/
205 int sys_fcntl_long(int fd, int cmd, long arg)
210 ret = fcntl(fd, cmd, arg);
211 } while (ret == -1 && errno == EINTR);
215 /*******************************************************************
216 A stat() wrapper that will deal with 64 bit filesizes.
217 ********************************************************************/
219 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
222 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
223 ret = stat64(fname, sbuf);
225 ret = stat(fname, sbuf);
227 /* we always want directories to appear zero size */
228 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
232 /*******************************************************************
233 An fstat() wrapper that will deal with 64 bit filesizes.
234 ********************************************************************/
236 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
239 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
240 ret = fstat64(fd, sbuf);
242 ret = fstat(fd, sbuf);
244 /* we always want directories to appear zero size */
245 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
249 /*******************************************************************
250 An lstat() wrapper that will deal with 64 bit filesizes.
251 ********************************************************************/
253 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
256 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
257 ret = lstat64(fname, sbuf);
259 ret = lstat(fname, sbuf);
261 /* we always want directories to appear zero size */
262 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
266 /*******************************************************************
267 An ftruncate() wrapper that will deal with 64 bit filesizes.
268 ********************************************************************/
270 int sys_ftruncate(int fd, SMB_OFF_T offset)
272 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
273 return ftruncate64(fd, offset);
275 return ftruncate(fd, offset);
279 /*******************************************************************
280 An lseek() wrapper that will deal with 64 bit filesizes.
281 ********************************************************************/
283 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
285 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
286 return lseek64(fd, offset, whence);
288 return lseek(fd, offset, whence);
292 /*******************************************************************
293 An fseek() wrapper that will deal with 64 bit filesizes.
294 ********************************************************************/
296 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
298 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
299 return fseek64(fp, offset, whence);
300 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
301 return fseeko64(fp, offset, whence);
303 return fseek(fp, offset, whence);
307 /*******************************************************************
308 An ftell() wrapper that will deal with 64 bit filesizes.
309 ********************************************************************/
311 SMB_OFF_T sys_ftell(FILE *fp)
313 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
314 return (SMB_OFF_T)ftell64(fp);
315 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
316 return (SMB_OFF_T)ftello64(fp);
318 return (SMB_OFF_T)ftell(fp);
322 /*******************************************************************
323 A creat() wrapper that will deal with 64 bit filesizes.
324 ********************************************************************/
326 int sys_creat(const char *path, mode_t mode)
328 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
329 return creat64(path, mode);
332 * If creat64 isn't defined then ensure we call a potential open64.
335 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
339 /*******************************************************************
340 An open() wrapper that will deal with 64 bit filesizes.
341 ********************************************************************/
343 int sys_open(const char *path, int oflag, mode_t mode)
345 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
346 return open64(path, oflag, mode);
348 return open(path, oflag, mode);
352 /*******************************************************************
353 An fopen() wrapper that will deal with 64 bit filesizes.
354 ********************************************************************/
356 FILE *sys_fopen(const char *path, const char *type)
358 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
359 return fopen64(path, type);
361 return fopen(path, type);
365 /*******************************************************************
366 An opendir wrapper that will deal with 64 bit filesizes.
367 ********************************************************************/
369 SMB_STRUCT_DIR *sys_opendir(const char *name)
371 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
372 return opendir64(name);
374 return opendir(name);
378 /*******************************************************************
379 A readdir wrapper that will deal with 64 bit filesizes.
380 ********************************************************************/
382 SMB_STRUCT_DIRENT *sys_readdir(SMB_STRUCT_DIR *dirp)
384 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
385 return readdir64(dirp);
387 return readdir(dirp);
391 /*******************************************************************
392 A seekdir wrapper that will deal with 64 bit filesizes.
393 ********************************************************************/
395 void sys_seekdir(SMB_STRUCT_DIR *dirp, long offset)
397 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
398 seekdir64(dirp, offset);
400 seekdir(dirp, offset);
404 /*******************************************************************
405 A telldir wrapper that will deal with 64 bit filesizes.
406 ********************************************************************/
408 long sys_telldir(SMB_STRUCT_DIR *dirp)
410 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
411 return (long)telldir64(dirp);
413 return (long)telldir(dirp);
417 /*******************************************************************
418 A rewinddir wrapper that will deal with 64 bit filesizes.
419 ********************************************************************/
421 void sys_rewinddir(SMB_STRUCT_DIR *dirp)
423 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
430 /*******************************************************************
431 A close wrapper that will deal with 64 bit filesizes.
432 ********************************************************************/
434 int sys_closedir(SMB_STRUCT_DIR *dirp)
436 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
437 return closedir64(dirp);
439 return closedir(dirp);
443 /*******************************************************************
444 An mknod() wrapper that will deal with 64 bit filesizes.
445 ********************************************************************/
447 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
449 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
450 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
451 return mknod64(path, mode, dev);
453 return mknod(path, mode, dev);
456 /* No mknod system call. */
462 /*******************************************************************
463 Wrapper for realpath.
464 ********************************************************************/
466 char *sys_realpath(const char *path, char *resolved_path)
468 #if defined(HAVE_REALPATH)
469 return realpath(path, resolved_path);
471 /* As realpath is not a system call we can't return ENOSYS. */
477 /*******************************************************************
478 The wait() calls vary between systems
479 ********************************************************************/
481 int sys_waitpid(pid_t pid,int *status,int options)
484 return waitpid(pid,status,options);
485 #else /* HAVE_WAITPID */
486 return wait4(pid, status, options, NULL);
487 #endif /* HAVE_WAITPID */
490 /*******************************************************************
491 System wrapper for getwd
492 ********************************************************************/
494 char *sys_getwd(char *s)
498 wd = (char *)getcwd(s, sizeof (pstring));
500 wd = (char *)getwd(s);
505 /*******************************************************************
506 system wrapper for symlink
507 ********************************************************************/
509 int sys_symlink(const char *oldpath, const char *newpath)
515 return symlink(oldpath, newpath);
519 /*******************************************************************
520 system wrapper for readlink
521 ********************************************************************/
523 int sys_readlink(const char *path, char *buf, size_t bufsiz)
525 #ifndef HAVE_READLINK
529 return readlink(path, buf, bufsiz);
533 /*******************************************************************
534 system wrapper for link
535 ********************************************************************/
537 int sys_link(const char *oldpath, const char *newpath)
543 return link(oldpath, newpath);
547 /*******************************************************************
548 chown isn't used much but OS/2 doesn't have it
549 ********************************************************************/
551 int sys_chown(const char *fname,uid_t uid,gid_t gid)
556 DEBUG(1,("WARNING: no chown!\n"));
562 return(chown(fname,uid,gid));
566 /*******************************************************************
567 os/2 also doesn't have chroot
568 ********************************************************************/
569 int sys_chroot(const char *dname)
574 DEBUG(1,("WARNING: no chroot!\n"));
580 return(chroot(dname));
584 /**************************************************************************
585 A wrapper for gethostbyname() that tries avoids looking up hostnames
586 in the root domain, which can cause dial-on-demand links to come up for no
588 ****************************************************************************/
590 struct hostent *sys_gethostbyname(const char *name)
592 #ifdef REDUCE_ROOT_DNS_LOOKUPS
593 char query[256], hostname[256];
596 /* Does this name have any dots in it? If so, make no change */
598 if (strchr_m(name, '.'))
599 return(gethostbyname(name));
601 /* Get my hostname, which should have domain name
602 attached. If not, just do the gethostname on the
606 gethostname(hostname, sizeof(hostname) - 1);
607 hostname[sizeof(hostname) - 1] = 0;
608 if ((domain = strchr_m(hostname, '.')) == NULL)
609 return(gethostbyname(name));
611 /* Attach domain name to query and do modified query.
612 If names too large, just do gethostname on the
616 if((strlen(name) + strlen(domain)) >= sizeof(query))
617 return(gethostbyname(name));
619 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
620 return(gethostbyname(query));
621 #else /* REDUCE_ROOT_DNS_LOOKUPS */
622 return(gethostbyname(name));
623 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
627 #if defined(HAVE_POSIX_CAPABILITIES)
629 #ifdef HAVE_SYS_CAPABILITY_H
631 #if defined(BROKEN_REDHAT_7_SYSTEM_HEADERS) && !defined(_I386_STATFS_H) && !defined(_PPC_STATFS_H)
632 #define _I386_STATFS_H
633 #define _PPC_STATFS_H
634 #define BROKEN_REDHAT_7_STATFS_WORKAROUND
637 #include <sys/capability.h>
639 #ifdef BROKEN_REDHAT_7_STATFS_WORKAROUND
640 #undef _I386_STATFS_H
642 #undef BROKEN_REDHAT_7_STATFS_WORKAROUND
645 #endif /* HAVE_SYS_CAPABILITY_H */
647 /**************************************************************************
648 Try and abstract process capabilities (for systems that have them).
649 ****************************************************************************/
651 /* Set the POSIX capabilities needed for the given purpose into the effective
652 * capability set of the current process. Make sure they are always removed
653 * from the inheritable set, because there is no circumstance in which our
654 * children should inherit our elevated privileges.
656 static BOOL set_process_capability(enum smbd_capability capability,
659 cap_value_t cap_vals[2] = {0};
660 int num_cap_vals = 0;
664 cap = cap_get_proc();
666 DEBUG(0,("set_process_capability: cap_get_proc failed: %s\n",
671 switch (capability) {
672 case KERNEL_OPLOCK_CAPABILITY:
673 #ifdef CAP_NETWORK_MGT
674 /* IRIX has CAP_NETWORK_MGT for oplocks. */
675 cap_vals[num_cap_vals++] = CAP_NETWORK_MGT;
680 SMB_ASSERT(num_cap_vals <= ARRAY_SIZE(cap_vals));
682 if (num_cap_vals == 0) {
687 cap_set_flag(cap, CAP_EFFECTIVE, num_cap_vals, cap_vals,
688 enable ? CAP_SET : CAP_CLEAR);
689 cap_set_flag(cap, CAP_INHERITABLE, num_cap_vals, cap_vals, CAP_CLEAR);
691 if (cap_set_proc(cap) == -1) {
692 DEBUG(0, ("set_process_capability: cap_set_proc failed: %s\n",
702 #endif /* HAVE_POSIX_CAPABILITIES */
704 /****************************************************************************
705 Gain the oplock capability from the kernel if possible.
706 ****************************************************************************/
708 void set_effective_capability(enum smbd_capability capability)
710 #if defined(HAVE_POSIX_CAPABILITIES)
711 set_process_capability(capability, True);
712 #endif /* HAVE_POSIX_CAPABILITIES */
715 void drop_effective_capability(enum smbd_capability capability)
717 #if defined(HAVE_POSIX_CAPABILITIES)
718 set_process_capability(capability, False);
719 #endif /* HAVE_POSIX_CAPABILITIES */
722 /**************************************************************************
723 Wrapper for random().
724 ****************************************************************************/
726 long sys_random(void)
728 #if defined(HAVE_RANDOM)
729 return (long)random();
730 #elif defined(HAVE_RAND)
733 DEBUG(0,("Error - no random function available !\n"));
738 /**************************************************************************
739 Wrapper for srandom().
740 ****************************************************************************/
742 void sys_srandom(unsigned int seed)
744 #if defined(HAVE_SRANDOM)
746 #elif defined(HAVE_SRAND)
749 DEBUG(0,("Error - no srandom function available !\n"));
754 /**************************************************************************
755 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
756 ****************************************************************************/
760 #if defined(SYSCONF_SC_NGROUPS_MAX)
761 int ret = sysconf(_SC_NGROUPS_MAX);
762 return (ret == -1) ? NGROUPS_MAX : ret;
768 /**************************************************************************
769 Wrapper for getgroups. Deals with broken (int) case.
770 ****************************************************************************/
772 int sys_getgroups(int setlen, gid_t *gidset)
774 #if !defined(HAVE_BROKEN_GETGROUPS)
775 return getgroups(setlen, gidset);
783 return getgroups(setlen, &gid);
787 * Broken case. We need to allocate a
788 * GID_T array of size setlen.
797 setlen = groups_max();
799 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
800 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
804 if((ngroups = getgroups(setlen, group_list)) < 0) {
805 int saved_errno = errno;
806 SAFE_FREE(group_list);
811 for(i = 0; i < ngroups; i++)
812 gidset[i] = (gid_t)group_list[i];
814 SAFE_FREE(group_list);
816 #endif /* HAVE_BROKEN_GETGROUPS */
820 /**************************************************************************
821 Wrapper for setgroups. Deals with broken (int) case. Automatically used
822 if we have broken getgroups.
823 ****************************************************************************/
825 int sys_setgroups(int setlen, gid_t *gidset)
827 #if !defined(HAVE_SETGROUPS)
830 #endif /* HAVE_SETGROUPS */
832 #if !defined(HAVE_BROKEN_GETGROUPS)
833 return setgroups(setlen, gidset);
842 if (setlen < 0 || setlen > groups_max()) {
848 * Broken case. We need to allocate a
849 * GID_T array of size setlen.
852 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
853 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
857 for(i = 0; i < setlen; i++)
858 group_list[i] = (GID_T) gidset[i];
860 if(setgroups(setlen, group_list) != 0) {
861 int saved_errno = errno;
862 SAFE_FREE(group_list);
867 SAFE_FREE(group_list);
869 #endif /* HAVE_BROKEN_GETGROUPS */
872 /**************************************************************************
873 Wrappers for setpwent(), getpwent() and endpwent()
874 ****************************************************************************/
876 void sys_setpwent(void)
881 struct passwd *sys_getpwent(void)
886 void sys_endpwent(void)
891 /**************************************************************************
892 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
893 ****************************************************************************/
895 struct passwd *sys_getpwnam(const char *name)
897 return getpwnam(name);
900 struct passwd *sys_getpwuid(uid_t uid)
902 return getpwuid(uid);
905 struct group *sys_getgrnam(const char *name)
907 return getgrnam(name);
910 struct group *sys_getgrgid(gid_t gid)
912 return getgrgid(gid);
915 #if 0 /* NOT CURRENTLY USED - JRA */
916 /**************************************************************************
917 The following are the UNICODE versions of *all* system interface functions
918 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
919 which currently are left as ascii as they are not used other than in name
921 ****************************************************************************/
923 /**************************************************************************
924 Wide stat. Just narrow and call sys_xxx.
925 ****************************************************************************/
927 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
930 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
933 /**************************************************************************
934 Wide lstat. Just narrow and call sys_xxx.
935 ****************************************************************************/
937 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
940 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
943 /**************************************************************************
944 Wide creat. Just narrow and call sys_xxx.
945 ****************************************************************************/
947 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
950 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
953 /**************************************************************************
954 Wide open. Just narrow and call sys_xxx.
955 ****************************************************************************/
957 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
960 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
963 /**************************************************************************
964 Wide fopen. Just narrow and call sys_xxx.
965 ****************************************************************************/
967 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
970 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
973 /**************************************************************************
974 Wide opendir. Just narrow and call sys_xxx.
975 ****************************************************************************/
977 SMB_STRUCT_DIR *wsys_opendir(const smb_ucs2_t *wfname)
980 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
983 /**************************************************************************
984 Wide readdir. Return a structure pointer containing a wide filename.
985 ****************************************************************************/
987 SMB_STRUCT_WDIRENT *wsys_readdir(SMB_STRUCT_DIR *dirp)
989 static SMB_STRUCT_WDIRENT retval;
990 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
996 * The only POSIX defined member of this struct is d_name.
999 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
1004 /**************************************************************************
1005 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
1006 ****************************************************************************/
1008 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
1011 char *p = sys_getwd(fname);
1016 return unix_to_unicode(s, p, sizeof(wpstring));
1019 /**************************************************************************
1020 Wide chown. Just narrow and call sys_xxx.
1021 ****************************************************************************/
1023 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
1026 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
1029 /**************************************************************************
1030 Wide chroot. Just narrow and call sys_xxx.
1031 ****************************************************************************/
1033 int wsys_chroot(const smb_ucs2_t *wfname)
1036 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
1039 /**************************************************************************
1040 Wide getpwnam. Return a structure pointer containing wide names.
1041 ****************************************************************************/
1043 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1045 static SMB_STRUCT_WPASSWD retval;
1047 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1052 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1053 retval.pw_passwd = pwret->pw_passwd;
1054 retval.pw_uid = pwret->pw_uid;
1055 retval.pw_gid = pwret->pw_gid;
1056 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1057 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1058 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1063 /**************************************************************************
1064 Wide getpwuid. Return a structure pointer containing wide names.
1065 ****************************************************************************/
1067 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1069 static SMB_STRUCT_WPASSWD retval;
1070 struct passwd *pwret = sys_getpwuid(uid);
1075 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1076 retval.pw_passwd = pwret->pw_passwd;
1077 retval.pw_uid = pwret->pw_uid;
1078 retval.pw_gid = pwret->pw_gid;
1079 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1080 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1081 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1085 #endif /* NOT CURRENTLY USED - JRA */
1087 /**************************************************************************
1088 Extract a command into an arg list. Uses a static pstring for storage.
1089 Caller frees returned arg list (which contains pointers into the static pstring).
1090 ****************************************************************************/
1092 static char **extract_args(const char *command)
1094 static pstring trunc_cmd;
1100 pstrcpy(trunc_cmd, command);
1102 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1111 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1114 if((argl = (char **)SMB_MALLOC((argcl + 1) * sizeof(char *))) == NULL)
1118 * Now do the extraction.
1121 pstrcpy(trunc_cmd, command);
1123 ptr = strtok(trunc_cmd, " \t");
1127 while((ptr = strtok(NULL, " \t")) != NULL)
1134 /**************************************************************************
1135 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1136 a sys_getpid() that only does a system call *once*.
1137 ****************************************************************************/
1139 static pid_t mypid = (pid_t)-1;
1141 pid_t sys_fork(void)
1143 pid_t forkret = fork();
1145 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1151 /**************************************************************************
1152 Wrapper for getpid. Ensures we only do a system call *once*.
1153 ****************************************************************************/
1155 pid_t sys_getpid(void)
1157 if (mypid == (pid_t)-1)
1163 /**************************************************************************
1164 Wrapper for popen. Safer as it doesn't search a path.
1165 Modified from the glibc sources.
1166 modified by tridge to return a file descriptor. We must kick our FILE* habit
1167 ****************************************************************************/
1169 typedef struct _popen_list
1173 struct _popen_list *next;
1176 static popen_list *popen_chain;
1178 int sys_popen(const char *command)
1180 int parent_end, child_end;
1182 popen_list *entry = NULL;
1185 if (pipe(pipe_fds) < 0)
1188 parent_end = pipe_fds[0];
1189 child_end = pipe_fds[1];
1196 if((entry = SMB_MALLOC_P(popen_list)) == NULL)
1199 ZERO_STRUCTP(entry);
1202 * Extract the command and args into a NULL terminated array.
1205 if(!(argl = extract_args(command)))
1208 entry->child_pid = sys_fork();
1210 if (entry->child_pid == -1) {
1214 if (entry->child_pid == 0) {
1220 int child_std_end = STDOUT_FILENO;
1224 if (child_end != child_std_end) {
1225 dup2 (child_end, child_std_end);
1230 * POSIX.2: "popen() shall ensure that any streams from previous
1231 * popen() calls that remain open in the parent process are closed
1232 * in the new child process."
1235 for (p = popen_chain; p; p = p->next)
1238 execv(argl[0], argl);
1249 /* Link into popen_chain. */
1250 entry->next = popen_chain;
1251 popen_chain = entry;
1252 entry->fd = parent_end;
1265 /**************************************************************************
1266 Wrapper for pclose. Modified from the glibc sources.
1267 ****************************************************************************/
1269 int sys_pclose(int fd)
1272 popen_list **ptr = &popen_chain;
1273 popen_list *entry = NULL;
1277 /* Unlink from popen_chain. */
1278 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1279 if ((*ptr)->fd == fd) {
1281 *ptr = (*ptr)->next;
1287 if (status < 0 || close(entry->fd) < 0)
1291 * As Samba is catching and eating child process
1292 * exits we don't really care about the child exit
1293 * code, a -1 with errno = ECHILD will do fine for us.
1297 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1298 } while (wait_pid == -1 && errno == EINTR);
1307 /**************************************************************************
1308 Wrappers for dlopen, dlsym, dlclose.
1309 ****************************************************************************/
1311 void *sys_dlopen(const char *name, int flags)
1313 #if defined(HAVE_DLOPEN)
1314 return dlopen(name, flags);
1320 void *sys_dlsym(void *handle, const char *symbol)
1322 #if defined(HAVE_DLSYM)
1323 return dlsym(handle, symbol);
1329 int sys_dlclose (void *handle)
1331 #if defined(HAVE_DLCLOSE)
1332 return dlclose(handle);
1338 const char *sys_dlerror(void)
1340 #if defined(HAVE_DLERROR)
1347 int sys_dup2(int oldfd, int newfd)
1349 #if defined(HAVE_DUP2)
1350 return dup2(oldfd, newfd);
1357 /**************************************************************************
1358 Wrapper for Admin Logs.
1359 ****************************************************************************/
1361 void sys_adminlog(int priority, const char *format_str, ...)
1365 char *msgbuf = NULL;
1367 va_start( ap, format_str );
1368 ret = vasprintf( &msgbuf, format_str, ap );
1374 #if defined(HAVE_SYSLOG)
1375 syslog( priority, "%s", msgbuf );
1377 DEBUG(0,("%s", msgbuf ));
1382 /**************************************************************************
1383 Wrappers for extented attribute calls. Based on the Linux package with
1384 support for IRIX and (Net|Free)BSD also. Expand as other systems have them.
1385 ****************************************************************************/
1387 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1389 #if defined(HAVE_GETXATTR)
1390 return getxattr(path, name, value, size);
1391 #elif defined(HAVE_GETEA)
1392 return getea(path, name, value, size);
1393 #elif defined(HAVE_EXTATTR_GET_FILE)
1396 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1397 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1398 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1400 * The BSD implementation has a nasty habit of silently truncating
1401 * the returned value to the size of the buffer, so we have to check
1402 * that the buffer is large enough to fit the returned value.
1404 if((retval=extattr_get_file(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1409 if((retval=extattr_get_file(path, attrnamespace, attrname, value, size)) >= 0)
1413 DEBUG(10,("sys_getxattr: extattr_get_file() failed with: %s\n", strerror(errno)));
1415 #elif defined(HAVE_ATTR_GET)
1416 int retval, flags = 0;
1417 int valuelength = (int)size;
1418 char *attrname = strchr(name,'.') + 1;
1420 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1422 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1424 return retval ? retval : valuelength;
1431 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1433 #if defined(HAVE_LGETXATTR)
1434 return lgetxattr(path, name, value, size);
1435 #elif defined(HAVE_LGETEA)
1436 return lgetea(path, name, value, size);
1437 #elif defined(HAVE_EXTATTR_GET_LINK)
1440 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1441 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1442 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1444 if((retval=extattr_get_link(path, attrnamespace, attrname, NULL, 0)) >= 0) {
1449 if((retval=extattr_get_link(path, attrnamespace, attrname, value, size)) >= 0)
1453 DEBUG(10,("sys_lgetxattr: extattr_get_link() failed with: %s\n", strerror(errno)));
1455 #elif defined(HAVE_ATTR_GET)
1456 int retval, flags = ATTR_DONTFOLLOW;
1457 int valuelength = (int)size;
1458 char *attrname = strchr(name,'.') + 1;
1460 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1462 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1464 return retval ? retval : valuelength;
1471 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1473 #if defined(HAVE_FGETXATTR)
1474 return fgetxattr(filedes, name, value, size);
1475 #elif defined(HAVE_FGETEA)
1476 return fgetea(filedes, name, value, size);
1477 #elif defined(HAVE_EXTATTR_GET_FD)
1480 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1481 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1482 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1484 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0)) >= 0) {
1489 if((retval=extattr_get_fd(filedes, attrnamespace, attrname, value, size)) >= 0)
1493 DEBUG(10,("sys_fgetxattr: extattr_get_fd() failed with: %s\n", strerror(errno)));
1495 #elif defined(HAVE_ATTR_GETF)
1496 int retval, flags = 0;
1497 int valuelength = (int)size;
1498 char *attrname = strchr(name,'.') + 1;
1500 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1502 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1504 return retval ? retval : valuelength;
1511 #if defined(HAVE_EXTATTR_LIST_FILE)
1513 #define EXTATTR_PREFIX(s) (s), (sizeof((s))-1)
1521 { EXTATTR_NAMESPACE_SYSTEM, EXTATTR_PREFIX("system.") },
1522 { EXTATTR_NAMESPACE_USER, EXTATTR_PREFIX("user.") },
1530 static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
1532 ssize_t list_size, total_size = 0;
1535 /* Iterate through extattr(2) namespaces */
1536 for(t = 0; t < (sizeof(extattr)/sizeof(extattr[0])); t++) {
1538 #if defined(HAVE_EXTATTR_LIST_FILE)
1540 list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
1543 #if defined(HAVE_EXTATTR_LIST_LINK)
1545 list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
1548 #if defined(HAVE_EXTATTR_LIST_FD)
1550 list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
1557 /* Some error happend. Errno should be set by the previous call */
1563 /* XXX: Call with an empty buffer may be used to calculate
1564 necessary buffer size. Unfortunately, we can't say, how
1565 many attributes were returned, so here is the potential
1566 problem with the emulation.
1569 /* Take the worse case of one char attribute names -
1570 two bytes per name plus one more for sanity.
1572 total_size += list_size + (list_size/2 + 1)*extattr[t].len;
1575 /* Count necessary offset to fit namespace prefixes */
1577 for(i = 0; i < list_size; i += list[i] + 1)
1578 len += extattr[t].len;
1580 total_size += list_size + len;
1581 /* Buffer is too small to fit the results */
1582 if(total_size > size) {
1586 /* Shift results back, so we can prepend prefixes */
1587 buf = memmove(list + len, list, list_size);
1589 for(i = 0; i < list_size; i += len + 1) {
1591 strncpy(list, extattr[t].name, extattr[t].len + 1);
1592 list += extattr[t].len;
1593 strncpy(list, buf + i + 1, len);
1604 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1605 static char attr_buffer[ATTR_MAX_VALUELEN];
1607 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1609 int retval = 0, index;
1610 attrlist_cursor_t *cursor = 0;
1612 attrlist_t * al = (attrlist_t *)attr_buffer;
1614 size_t ent_size, left = size;
1619 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1621 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1623 for (index = 0; index < al->al_count; index++) {
1624 ae = ATTR_ENTRY(attr_buffer, index);
1625 ent_size = strlen(ae->a_name) + sizeof("user.");
1626 if (left >= ent_size) {
1627 strncpy(bp, "user.", sizeof("user."));
1628 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1636 total_size += ent_size;
1638 if (al->al_more == 0) break;
1645 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1647 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1649 for (index = 0; index < al->al_count; index++) {
1650 ae = ATTR_ENTRY(attr_buffer, index);
1651 ent_size = strlen(ae->a_name) + sizeof("system.");
1652 if (left >= ent_size) {
1653 strncpy(bp, "system.", sizeof("system."));
1654 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1662 total_size += ent_size;
1664 if (al->al_more == 0) break;
1667 return (ssize_t)(retval ? retval : total_size);
1672 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1674 #if defined(HAVE_LISTXATTR)
1675 return listxattr(path, list, size);
1676 #elif defined(HAVE_LISTEA)
1677 return listea(path, list, size);
1678 #elif defined(HAVE_EXTATTR_LIST_FILE)
1681 return bsd_attr_list(0, arg, list, size);
1682 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1683 return irix_attr_list(path, 0, list, size, 0);
1690 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1692 #if defined(HAVE_LLISTXATTR)
1693 return llistxattr(path, list, size);
1694 #elif defined(HAVE_LLISTEA)
1695 return llistea(path, list, size);
1696 #elif defined(HAVE_EXTATTR_LIST_LINK)
1699 return bsd_attr_list(1, arg, list, size);
1700 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1701 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1708 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1710 #if defined(HAVE_FLISTXATTR)
1711 return flistxattr(filedes, list, size);
1712 #elif defined(HAVE_FLISTEA)
1713 return flistea(filedes, list, size);
1714 #elif defined(HAVE_EXTATTR_LIST_FD)
1716 arg.filedes = filedes;
1717 return bsd_attr_list(2, arg, list, size);
1718 #elif defined(HAVE_ATTR_LISTF)
1719 return irix_attr_list(NULL, filedes, list, size, 0);
1726 int sys_removexattr (const char *path, const char *name)
1728 #if defined(HAVE_REMOVEXATTR)
1729 return removexattr(path, name);
1730 #elif defined(HAVE_REMOVEEA)
1731 return removeea(path, name);
1732 #elif defined(HAVE_EXTATTR_DELETE_FILE)
1734 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1735 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1736 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1738 return extattr_delete_file(path, attrnamespace, attrname);
1739 #elif defined(HAVE_ATTR_REMOVE)
1741 char *attrname = strchr(name,'.') + 1;
1743 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1745 return attr_remove(path, attrname, flags);
1752 int sys_lremovexattr (const char *path, const char *name)
1754 #if defined(HAVE_LREMOVEXATTR)
1755 return lremovexattr(path, name);
1756 #elif defined(HAVE_LREMOVEEA)
1757 return lremoveea(path, name);
1758 #elif defined(HAVE_EXTATTR_DELETE_LINK)
1760 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1761 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1762 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1764 return extattr_delete_link(path, attrnamespace, attrname);
1765 #elif defined(HAVE_ATTR_REMOVE)
1766 int flags = ATTR_DONTFOLLOW;
1767 char *attrname = strchr(name,'.') + 1;
1769 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1771 return attr_remove(path, attrname, flags);
1778 int sys_fremovexattr (int filedes, const char *name)
1780 #if defined(HAVE_FREMOVEXATTR)
1781 return fremovexattr(filedes, name);
1782 #elif defined(HAVE_FREMOVEEA)
1783 return fremoveea(filedes, name);
1784 #elif defined(HAVE_EXTATTR_DELETE_FD)
1786 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1787 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1788 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1790 return extattr_delete_fd(filedes, attrnamespace, attrname);
1791 #elif defined(HAVE_ATTR_REMOVEF)
1793 char *attrname = strchr(name,'.') + 1;
1795 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1797 return attr_removef(filedes, attrname, flags);
1804 #if !defined(HAVE_SETXATTR)
1805 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1806 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1809 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1811 #if defined(HAVE_SETXATTR)
1812 return setxattr(path, name, value, size, flags);
1813 #elif defined(HAVE_SETEA)
1814 return setea(path, name, value, size, flags);
1815 #elif defined(HAVE_EXTATTR_SET_FILE)
1818 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1819 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1820 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1822 /* Check attribute existence */
1823 retval = extattr_get_file(path, attrnamespace, attrname, NULL, 0);
1825 /* REPLACE attribute, that doesn't exist */
1826 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1830 /* Ignore other errors */
1833 /* CREATE attribute, that already exists */
1834 if (flags & XATTR_CREATE) {
1840 retval = extattr_set_file(path, attrnamespace, attrname, value, size);
1841 return (retval < 0) ? -1 : 0;
1842 #elif defined(HAVE_ATTR_SET)
1844 char *attrname = strchr(name,'.') + 1;
1846 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1847 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1848 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1850 return attr_set(path, attrname, (const char *)value, size, myflags);
1857 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1859 #if defined(HAVE_LSETXATTR)
1860 return lsetxattr(path, name, value, size, flags);
1861 #elif defined(LSETEA)
1862 return lsetea(path, name, value, size, flags);
1863 #elif defined(HAVE_EXTATTR_SET_LINK)
1866 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1867 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1868 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1870 /* Check attribute existence */
1871 retval = extattr_get_link(path, attrnamespace, attrname, NULL, 0);
1873 /* REPLACE attribute, that doesn't exist */
1874 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1878 /* Ignore other errors */
1881 /* CREATE attribute, that already exists */
1882 if (flags & XATTR_CREATE) {
1889 retval = extattr_set_link(path, attrnamespace, attrname, value, size);
1890 return (retval < 0) ? -1 : 0;
1891 #elif defined(HAVE_ATTR_SET)
1892 int myflags = ATTR_DONTFOLLOW;
1893 char *attrname = strchr(name,'.') + 1;
1895 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1896 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1897 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1899 return attr_set(path, attrname, (const char *)value, size, myflags);
1906 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
1908 #if defined(HAVE_FSETXATTR)
1909 return fsetxattr(filedes, name, value, size, flags);
1910 #elif defined(HAVE_FSETEA)
1911 return fsetea(filedes, name, value, size, flags);
1912 #elif defined(HAVE_EXTATTR_SET_FD)
1915 int attrnamespace = (strncmp(name, "system", 6) == 0) ?
1916 EXTATTR_NAMESPACE_SYSTEM : EXTATTR_NAMESPACE_USER;
1917 const char *attrname = ((s=strchr_m(name, '.')) == NULL) ? name : s + 1;
1919 /* Check attribute existence */
1920 retval = extattr_get_fd(filedes, attrnamespace, attrname, NULL, 0);
1922 /* REPLACE attribute, that doesn't exist */
1923 if (flags & XATTR_REPLACE && errno == ENOATTR) {
1927 /* Ignore other errors */
1930 /* CREATE attribute, that already exists */
1931 if (flags & XATTR_CREATE) {
1937 retval = extattr_set_fd(filedes, attrnamespace, attrname, value, size);
1938 return (retval < 0) ? -1 : 0;
1939 #elif defined(HAVE_ATTR_SETF)
1941 char *attrname = strchr(name,'.') + 1;
1943 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1944 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1945 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1947 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
1954 /****************************************************************************
1955 Return the major devicenumber for UNIX extensions.
1956 ****************************************************************************/
1958 uint32 unix_dev_major(SMB_DEV_T dev)
1960 #if defined(HAVE_DEVICE_MAJOR_FN)
1961 return (uint32)major(dev);
1963 return (uint32)(dev >> 8);
1967 /****************************************************************************
1968 Return the minor devicenumber for UNIX extensions.
1969 ****************************************************************************/
1971 uint32 unix_dev_minor(SMB_DEV_T dev)
1973 #if defined(HAVE_DEVICE_MINOR_FN)
1974 return (uint32)minor(dev);
1976 return (uint32)(dev & 0xff);
1980 #if defined(WITH_AIO)
1982 /*******************************************************************
1983 An aio_read wrapper that will deal with 64-bit sizes.
1984 ********************************************************************/
1986 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
1988 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_READ64)
1989 return aio_read64(aiocb);
1990 #elif defined(HAVE_AIO_READ)
1991 return aio_read(aiocb);
1998 /*******************************************************************
1999 An aio_write wrapper that will deal with 64-bit sizes.
2000 ********************************************************************/
2002 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2004 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_WRITE64)
2005 return aio_write64(aiocb);
2006 #elif defined(HAVE_AIO_WRITE)
2007 return aio_write(aiocb);
2014 /*******************************************************************
2015 An aio_return wrapper that will deal with 64-bit sizes.
2016 ********************************************************************/
2018 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2020 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_RETURN64)
2021 return aio_return64(aiocb);
2022 #elif defined(HAVE_AIO_RETURN)
2023 return aio_return(aiocb);
2030 /*******************************************************************
2031 An aio_cancel wrapper that will deal with 64-bit sizes.
2032 ********************************************************************/
2034 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2036 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_CANCEL64)
2037 return aio_cancel64(fd, aiocb);
2038 #elif defined(HAVE_AIO_CANCEL)
2039 return aio_cancel(fd, aiocb);
2046 /*******************************************************************
2047 An aio_error wrapper that will deal with 64-bit sizes.
2048 ********************************************************************/
2050 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2052 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_ERROR64)
2053 return aio_error64(aiocb);
2054 #elif defined(HAVE_AIO_ERROR)
2055 return aio_error(aiocb);
2062 /*******************************************************************
2063 An aio_fsync wrapper that will deal with 64-bit sizes.
2064 ********************************************************************/
2066 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2068 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_FSYNC64)
2069 return aio_fsync64(op, aiocb);
2070 #elif defined(HAVE_AIO_FSYNC)
2071 return aio_fsync(op, aiocb);
2078 /*******************************************************************
2079 An aio_fsync wrapper that will deal with 64-bit sizes.
2080 ********************************************************************/
2082 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2084 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_AIOCB64) && defined(HAVE_AIO_SUSPEND64)
2085 return aio_suspend64(cblist, n, timeout);
2086 #elif defined(HAVE_AIO_FSYNC)
2087 return aio_suspend(cblist, n, timeout);
2093 #else /* !WITH_AIO */
2095 int sys_aio_read(SMB_STRUCT_AIOCB *aiocb)
2101 int sys_aio_write(SMB_STRUCT_AIOCB *aiocb)
2107 ssize_t sys_aio_return(SMB_STRUCT_AIOCB *aiocb)
2113 int sys_aio_cancel(int fd, SMB_STRUCT_AIOCB *aiocb)
2119 int sys_aio_error(const SMB_STRUCT_AIOCB *aiocb)
2125 int sys_aio_fsync(int op, SMB_STRUCT_AIOCB *aiocb)
2131 int sys_aio_suspend(const SMB_STRUCT_AIOCB * const cblist[], int n, const struct timespec *timeout)
2136 #endif /* WITH_AIO */