2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1998-2002
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 The idea is that this file will eventually have wrappers around all
26 important system calls in samba. The aims are:
28 - to enable easier porting by putting OS dependent stuff in here
30 - to allow for hooks into other "pseudo-filesystems"
32 - to allow easier integration of things like the japanese extensions
34 - to support the philosophy of Samba to expose the features of
35 the OS within the SMB model. In general whatever file/printer/variable
36 expansions/etc make sense to the OS should be acceptable to Samba.
41 /*******************************************************************
42 A wrapper for usleep in case we don't have one.
43 ********************************************************************/
45 int sys_usleep(long usecs)
52 * We need this braindamage as the glibc usleep
53 * is not SPEC1170 complient... grumble... JRA.
56 if(usecs < 0 || usecs > 1000000) {
64 #else /* HAVE_USLEEP */
66 * Fake it with select...
69 tval.tv_usec = usecs/1000;
70 select(0,NULL,NULL,NULL,&tval);
72 #endif /* HAVE_USLEEP */
75 /*******************************************************************
76 A read wrapper that will deal with EINTR.
77 ********************************************************************/
79 ssize_t sys_read(int fd, void *buf, size_t count)
84 ret = read(fd, buf, count);
85 } while (ret == -1 && errno == EINTR);
89 /*******************************************************************
90 A write wrapper that will deal with EINTR.
91 ********************************************************************/
93 ssize_t sys_write(int fd, const void *buf, size_t count)
98 ret = write(fd, buf, count);
99 } while (ret == -1 && errno == EINTR);
104 /*******************************************************************
105 A pread wrapper that will deal with EINTR and 64-bit file offsets.
106 ********************************************************************/
108 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
109 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
114 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
115 ret = pread64(fd, buf, count, off);
117 ret = pread(fd, buf, count, off);
119 } while (ret == -1 && errno == EINTR);
124 /*******************************************************************
125 A write wrapper that will deal with EINTR and 64-bit file offsets.
126 ********************************************************************/
128 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
129 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
134 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
135 ret = pwrite64(fd, buf, count, off);
137 ret = pwrite(fd, buf, count, off);
139 } while (ret == -1 && errno == EINTR);
144 /*******************************************************************
145 A send wrapper that will deal with EINTR.
146 ********************************************************************/
148 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
153 ret = send(s, msg, len, flags);
154 } while (ret == -1 && errno == EINTR);
158 /*******************************************************************
159 A sendto wrapper that will deal with EINTR.
160 ********************************************************************/
162 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
167 ret = sendto(s, msg, len, flags, to, tolen);
168 } while (ret == -1 && errno == EINTR);
172 /*******************************************************************
173 A recvfrom wrapper that will deal with EINTR.
174 ********************************************************************/
176 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
181 ret = recvfrom(s, buf, len, flags, from, fromlen);
182 } while (ret == -1 && errno == EINTR);
186 /*******************************************************************
187 A fcntl wrapper that will deal with EINTR.
188 ********************************************************************/
190 int sys_fcntl_ptr(int fd, int cmd, void *arg)
195 ret = fcntl(fd, cmd, arg);
196 } while (ret == -1 && errno == EINTR);
200 /*******************************************************************
201 A fcntl wrapper that will deal with EINTR.
202 ********************************************************************/
204 int sys_fcntl_long(int fd, int cmd, long arg)
209 ret = fcntl(fd, cmd, arg);
210 } while (ret == -1 && errno == EINTR);
214 /*******************************************************************
215 A stat() wrapper that will deal with 64 bit filesizes.
216 ********************************************************************/
218 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
221 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
222 ret = stat64(fname, sbuf);
224 ret = stat(fname, sbuf);
226 /* we always want directories to appear zero size */
227 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
231 /*******************************************************************
232 An fstat() wrapper that will deal with 64 bit filesizes.
233 ********************************************************************/
235 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
238 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
239 ret = fstat64(fd, sbuf);
241 ret = fstat(fd, sbuf);
243 /* we always want directories to appear zero size */
244 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
248 /*******************************************************************
249 An lstat() wrapper that will deal with 64 bit filesizes.
250 ********************************************************************/
252 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
255 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
256 ret = lstat64(fname, sbuf);
258 ret = lstat(fname, sbuf);
260 /* we always want directories to appear zero size */
261 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
265 /*******************************************************************
266 An ftruncate() wrapper that will deal with 64 bit filesizes.
267 ********************************************************************/
269 int sys_ftruncate(int fd, SMB_OFF_T offset)
271 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
272 return ftruncate64(fd, offset);
274 return ftruncate(fd, offset);
278 /*******************************************************************
279 An lseek() wrapper that will deal with 64 bit filesizes.
280 ********************************************************************/
282 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
284 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
285 return lseek64(fd, offset, whence);
287 return lseek(fd, offset, whence);
291 /*******************************************************************
292 An fseek() wrapper that will deal with 64 bit filesizes.
293 ********************************************************************/
295 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
297 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
298 return fseek64(fp, offset, whence);
299 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
300 return fseeko64(fp, offset, whence);
302 return fseek(fp, offset, whence);
306 /*******************************************************************
307 An ftell() wrapper that will deal with 64 bit filesizes.
308 ********************************************************************/
310 SMB_OFF_T sys_ftell(FILE *fp)
312 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
313 return (SMB_OFF_T)ftell64(fp);
314 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
315 return (SMB_OFF_T)ftello64(fp);
317 return (SMB_OFF_T)ftell(fp);
321 /*******************************************************************
322 A creat() wrapper that will deal with 64 bit filesizes.
323 ********************************************************************/
325 int sys_creat(const char *path, mode_t mode)
327 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
328 return creat64(path, mode);
331 * If creat64 isn't defined then ensure we call a potential open64.
334 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
338 /*******************************************************************
339 An open() wrapper that will deal with 64 bit filesizes.
340 ********************************************************************/
342 int sys_open(const char *path, int oflag, mode_t mode)
344 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
345 return open64(path, oflag, mode);
347 return open(path, oflag, mode);
351 /*******************************************************************
352 An fopen() wrapper that will deal with 64 bit filesizes.
353 ********************************************************************/
355 FILE *sys_fopen(const char *path, const char *type)
357 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
358 return fopen64(path, type);
360 return fopen(path, type);
364 /*******************************************************************
365 An opendir wrapper that will deal with 64 bit filesizes.
366 ********************************************************************/
368 DIR *sys_opendir(const char *name)
370 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPENDIR64)
371 return opendir64(name);
373 return opendir(name);
377 /*******************************************************************
378 A readdir wrapper that will deal with 64 bit filesizes.
379 ********************************************************************/
381 SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
383 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
384 return readdir64(dirp);
386 return readdir(dirp);
390 /*******************************************************************
391 A seekdir wrapper that will deal with 64 bit filesizes.
392 ********************************************************************/
394 void sys_seekdir(DIR *dirp, long offset)
396 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_SEEKDIR64)
397 seekdir64(dirp, offset);
399 seekdir(dirp, offset);
403 /*******************************************************************
404 A telldir wrapper that will deal with 64 bit filesizes.
405 ********************************************************************/
407 long sys_telldir(DIR *dirp)
409 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_TELLDIR64)
410 return (long)telldir64(dirp);
412 return (long)telldir(dirp);
416 /*******************************************************************
417 A rewinddir wrapper that will deal with 64 bit filesizes.
418 ********************************************************************/
420 void sys_rewinddir(DIR *dirp)
422 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_REWINDDIR64)
429 /*******************************************************************
430 A close wrapper that will deal with 64 bit filesizes.
431 ********************************************************************/
433 int sys_closedir(DIR *dirp)
435 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CLOSEDIR64)
436 return closedir64(dirp);
438 return closedir(dirp);
442 /*******************************************************************
443 An mknod() wrapper that will deal with 64 bit filesizes.
444 ********************************************************************/
446 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
448 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
449 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
450 return mknod64(path, mode, dev);
452 return mknod(path, mode, dev);
455 /* No mknod system call. */
461 /*******************************************************************
462 Wrapper for realpath.
463 ********************************************************************/
465 char *sys_realpath(const char *path, char *resolved_path)
467 #if defined(HAVE_REALPATH)
468 return realpath(path, resolved_path);
470 /* As realpath is not a system call we can't return ENOSYS. */
476 /*******************************************************************
477 The wait() calls vary between systems
478 ********************************************************************/
480 int sys_waitpid(pid_t pid,int *status,int options)
483 return waitpid(pid,status,options);
484 #else /* HAVE_WAITPID */
485 return wait4(pid, status, options, NULL);
486 #endif /* HAVE_WAITPID */
489 /*******************************************************************
490 System wrapper for getwd
491 ********************************************************************/
493 char *sys_getwd(char *s)
497 wd = (char *)getcwd(s, sizeof (pstring));
499 wd = (char *)getwd(s);
504 /*******************************************************************
505 system wrapper for symlink
506 ********************************************************************/
508 int sys_symlink(const char *oldpath, const char *newpath)
514 return symlink(oldpath, newpath);
518 /*******************************************************************
519 system wrapper for readlink
520 ********************************************************************/
522 int sys_readlink(const char *path, char *buf, size_t bufsiz)
524 #ifndef HAVE_READLINK
528 return readlink(path, buf, bufsiz);
532 /*******************************************************************
533 system wrapper for link
534 ********************************************************************/
536 int sys_link(const char *oldpath, const char *newpath)
542 return link(oldpath, newpath);
546 /*******************************************************************
547 chown isn't used much but OS/2 doesn't have it
548 ********************************************************************/
550 int sys_chown(const char *fname,uid_t uid,gid_t gid)
555 DEBUG(1,("WARNING: no chown!\n"));
561 return(chown(fname,uid,gid));
565 /*******************************************************************
566 os/2 also doesn't have chroot
567 ********************************************************************/
568 int sys_chroot(const char *dname)
573 DEBUG(1,("WARNING: no chroot!\n"));
579 return(chroot(dname));
583 /**************************************************************************
584 A wrapper for gethostbyname() that tries avoids looking up hostnames
585 in the root domain, which can cause dial-on-demand links to come up for no
587 ****************************************************************************/
589 struct hostent *sys_gethostbyname(const char *name)
591 #ifdef REDUCE_ROOT_DNS_LOOKUPS
592 char query[256], hostname[256];
595 /* Does this name have any dots in it? If so, make no change */
597 if (strchr_m(name, '.'))
598 return(gethostbyname(name));
600 /* Get my hostname, which should have domain name
601 attached. If not, just do the gethostname on the
605 gethostname(hostname, sizeof(hostname) - 1);
606 hostname[sizeof(hostname) - 1] = 0;
607 if ((domain = strchr_m(hostname, '.')) == NULL)
608 return(gethostbyname(name));
610 /* Attach domain name to query and do modified query.
611 If names too large, just do gethostname on the
615 if((strlen(name) + strlen(domain)) >= sizeof(query))
616 return(gethostbyname(name));
618 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
619 return(gethostbyname(query));
620 #else /* REDUCE_ROOT_DNS_LOOKUPS */
621 return(gethostbyname(name));
622 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
626 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
627 /**************************************************************************
628 Try and abstract process capabilities (for systems that have them).
629 ****************************************************************************/
630 static BOOL set_process_capability( uint32 cap_flag, BOOL enable )
632 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
633 cap_t cap = cap_get_proc();
636 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
642 cap->cap_effective |= CAP_NETWORK_MGT;
644 cap->cap_effective &= ~CAP_NETWORK_MGT;
646 if (cap_set_proc(cap) == -1) {
647 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
655 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
660 /**************************************************************************
661 Try and abstract inherited process capabilities (for systems that have them).
662 ****************************************************************************/
664 static BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
666 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
667 cap_t cap = cap_get_proc();
670 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
676 cap->cap_inheritable |= CAP_NETWORK_MGT;
678 cap->cap_inheritable &= ~CAP_NETWORK_MGT;
680 if (cap_set_proc(cap) == -1) {
681 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
689 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
695 /****************************************************************************
696 Gain the oplock capability from the kernel if possible.
697 ****************************************************************************/
699 void oplock_set_capability(BOOL this_process, BOOL inherit)
701 #if HAVE_KERNEL_OPLOCKS_IRIX
702 set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process);
703 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit);
707 /**************************************************************************
708 Wrapper for random().
709 ****************************************************************************/
711 long sys_random(void)
713 #if defined(HAVE_RANDOM)
714 return (long)random();
715 #elif defined(HAVE_RAND)
718 DEBUG(0,("Error - no random function available !\n"));
723 /**************************************************************************
724 Wrapper for srandom().
725 ****************************************************************************/
727 void sys_srandom(unsigned int seed)
729 #if defined(HAVE_SRANDOM)
731 #elif defined(HAVE_SRAND)
734 DEBUG(0,("Error - no srandom function available !\n"));
739 /**************************************************************************
740 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
741 ****************************************************************************/
745 #if defined(SYSCONF_SC_NGROUPS_MAX)
746 int ret = sysconf(_SC_NGROUPS_MAX);
747 return (ret == -1) ? NGROUPS_MAX : ret;
753 /**************************************************************************
754 Wrapper for getgroups. Deals with broken (int) case.
755 ****************************************************************************/
757 int sys_getgroups(int setlen, gid_t *gidset)
759 #if !defined(HAVE_BROKEN_GETGROUPS)
760 return getgroups(setlen, gidset);
768 return getgroups(setlen, &gid);
772 * Broken case. We need to allocate a
773 * GID_T array of size setlen.
782 setlen = groups_max();
784 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
785 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
789 if((ngroups = getgroups(setlen, group_list)) < 0) {
790 int saved_errno = errno;
791 SAFE_FREE(group_list);
796 for(i = 0; i < ngroups; i++)
797 gidset[i] = (gid_t)group_list[i];
799 SAFE_FREE(group_list);
801 #endif /* HAVE_BROKEN_GETGROUPS */
805 /**************************************************************************
806 Wrapper for setgroups. Deals with broken (int) case. Automatically used
807 if we have broken getgroups.
808 ****************************************************************************/
810 int sys_setgroups(int setlen, gid_t *gidset)
812 #if !defined(HAVE_SETGROUPS)
815 #endif /* HAVE_SETGROUPS */
817 #if !defined(HAVE_BROKEN_GETGROUPS)
818 return setgroups(setlen, gidset);
827 if (setlen < 0 || setlen > groups_max()) {
833 * Broken case. We need to allocate a
834 * GID_T array of size setlen.
837 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
838 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
842 for(i = 0; i < setlen; i++)
843 group_list[i] = (GID_T) gidset[i];
845 if(setgroups(setlen, group_list) != 0) {
846 int saved_errno = errno;
847 SAFE_FREE(group_list);
852 SAFE_FREE(group_list);
854 #endif /* HAVE_BROKEN_GETGROUPS */
857 /**************************************************************************
858 Wrappers for setpwent(), getpwent() and endpwent()
859 ****************************************************************************/
861 void sys_setpwent(void)
866 struct passwd *sys_getpwent(void)
871 void sys_endpwent(void)
876 /**************************************************************************
877 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
878 ****************************************************************************/
880 struct passwd *sys_getpwnam(const char *name)
882 return getpwnam(name);
885 struct passwd *sys_getpwuid(uid_t uid)
887 return getpwuid(uid);
890 struct group *sys_getgrnam(const char *name)
892 return getgrnam(name);
895 struct group *sys_getgrgid(gid_t gid)
897 return getgrgid(gid);
900 #if 0 /* NOT CURRENTLY USED - JRA */
901 /**************************************************************************
902 The following are the UNICODE versions of *all* system interface functions
903 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
904 which currently are left as ascii as they are not used other than in name
906 ****************************************************************************/
908 /**************************************************************************
909 Wide stat. Just narrow and call sys_xxx.
910 ****************************************************************************/
912 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
915 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
918 /**************************************************************************
919 Wide lstat. Just narrow and call sys_xxx.
920 ****************************************************************************/
922 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
925 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
928 /**************************************************************************
929 Wide creat. Just narrow and call sys_xxx.
930 ****************************************************************************/
932 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
935 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
938 /**************************************************************************
939 Wide open. Just narrow and call sys_xxx.
940 ****************************************************************************/
942 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
945 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
948 /**************************************************************************
949 Wide fopen. Just narrow and call sys_xxx.
950 ****************************************************************************/
952 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
955 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
958 /**************************************************************************
959 Wide opendir. Just narrow and call sys_xxx.
960 ****************************************************************************/
962 DIR *wsys_opendir(const smb_ucs2_t *wfname)
965 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
968 /**************************************************************************
969 Wide readdir. Return a structure pointer containing a wide filename.
970 ****************************************************************************/
972 SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
974 static SMB_STRUCT_WDIRENT retval;
975 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
981 * The only POSIX defined member of this struct is d_name.
984 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
989 /**************************************************************************
990 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
991 ****************************************************************************/
993 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
996 char *p = sys_getwd(fname);
1001 return unix_to_unicode(s, p, sizeof(wpstring));
1004 /**************************************************************************
1005 Wide chown. Just narrow and call sys_xxx.
1006 ****************************************************************************/
1008 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
1011 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
1014 /**************************************************************************
1015 Wide chroot. Just narrow and call sys_xxx.
1016 ****************************************************************************/
1018 int wsys_chroot(const smb_ucs2_t *wfname)
1021 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
1024 /**************************************************************************
1025 Wide getpwnam. Return a structure pointer containing wide names.
1026 ****************************************************************************/
1028 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1030 static SMB_STRUCT_WPASSWD retval;
1032 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1037 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1038 retval.pw_passwd = pwret->pw_passwd;
1039 retval.pw_uid = pwret->pw_uid;
1040 retval.pw_gid = pwret->pw_gid;
1041 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1042 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1043 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1048 /**************************************************************************
1049 Wide getpwuid. Return a structure pointer containing wide names.
1050 ****************************************************************************/
1052 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1054 static SMB_STRUCT_WPASSWD retval;
1055 struct passwd *pwret = sys_getpwuid(uid);
1060 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1061 retval.pw_passwd = pwret->pw_passwd;
1062 retval.pw_uid = pwret->pw_uid;
1063 retval.pw_gid = pwret->pw_gid;
1064 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1065 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1066 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1070 #endif /* NOT CURRENTLY USED - JRA */
1072 /**************************************************************************
1073 Extract a command into an arg list. Uses a static pstring for storage.
1074 Caller frees returned arg list (which contains pointers into the static pstring).
1075 ****************************************************************************/
1077 static char **extract_args(const char *command)
1079 static pstring trunc_cmd;
1085 pstrcpy(trunc_cmd, command);
1087 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1096 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1099 if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL)
1103 * Now do the extraction.
1106 pstrcpy(trunc_cmd, command);
1108 ptr = strtok(trunc_cmd, " \t");
1112 while((ptr = strtok(NULL, " \t")) != NULL)
1119 /**************************************************************************
1120 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1121 a sys_getpid() that only does a system call *once*.
1122 ****************************************************************************/
1124 static pid_t mypid = (pid_t)-1;
1126 pid_t sys_fork(void)
1128 pid_t forkret = fork();
1130 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1136 /**************************************************************************
1137 Wrapper for getpid. Ensures we only do a system call *once*.
1138 ****************************************************************************/
1140 pid_t sys_getpid(void)
1142 if (mypid == (pid_t)-1)
1148 /**************************************************************************
1149 Wrapper for popen. Safer as it doesn't search a path.
1150 Modified from the glibc sources.
1151 modified by tridge to return a file descriptor. We must kick our FILE* habit
1152 ****************************************************************************/
1154 typedef struct _popen_list
1158 struct _popen_list *next;
1161 static popen_list *popen_chain;
1163 int sys_popen(const char *command)
1165 int parent_end, child_end;
1167 popen_list *entry = NULL;
1170 if (pipe(pipe_fds) < 0)
1173 parent_end = pipe_fds[0];
1174 child_end = pipe_fds[1];
1181 if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL)
1184 ZERO_STRUCTP(entry);
1187 * Extract the command and args into a NULL terminated array.
1190 if(!(argl = extract_args(command)))
1193 entry->child_pid = sys_fork();
1195 if (entry->child_pid == -1) {
1199 if (entry->child_pid == 0) {
1205 int child_std_end = STDOUT_FILENO;
1209 if (child_end != child_std_end) {
1210 dup2 (child_end, child_std_end);
1215 * POSIX.2: "popen() shall ensure that any streams from previous
1216 * popen() calls that remain open in the parent process are closed
1217 * in the new child process."
1220 for (p = popen_chain; p; p = p->next)
1223 execv(argl[0], argl);
1234 /* Link into popen_chain. */
1235 entry->next = popen_chain;
1236 popen_chain = entry;
1237 entry->fd = parent_end;
1250 /**************************************************************************
1251 Wrapper for pclose. Modified from the glibc sources.
1252 ****************************************************************************/
1254 int sys_pclose(int fd)
1257 popen_list **ptr = &popen_chain;
1258 popen_list *entry = NULL;
1262 /* Unlink from popen_chain. */
1263 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1264 if ((*ptr)->fd == fd) {
1266 *ptr = (*ptr)->next;
1272 if (status < 0 || close(entry->fd) < 0)
1276 * As Samba is catching and eating child process
1277 * exits we don't really care about the child exit
1278 * code, a -1 with errno = ECHILD will do fine for us.
1282 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1283 } while (wait_pid == -1 && errno == EINTR);
1292 /**************************************************************************
1293 Wrappers for dlopen, dlsym, dlclose.
1294 ****************************************************************************/
1296 void *sys_dlopen(const char *name, int flags)
1298 #if defined(HAVE_DLOPEN)
1299 return dlopen(name, flags);
1305 void *sys_dlsym(void *handle, const char *symbol)
1307 #if defined(HAVE_DLSYM)
1308 return dlsym(handle, symbol);
1314 int sys_dlclose (void *handle)
1316 #if defined(HAVE_DLCLOSE)
1317 return dlclose(handle);
1323 const char *sys_dlerror(void)
1325 #if defined(HAVE_DLERROR)
1332 int sys_dup2(int oldfd, int newfd)
1334 #if defined(HAVE_DUP2)
1335 return dup2(oldfd, newfd);
1342 /**************************************************************************
1343 Wrapper for Admin Logs.
1344 ****************************************************************************/
1346 void sys_adminlog(int priority, const char *format_str, ...)
1350 char *msgbuf = NULL;
1352 va_start( ap, format_str );
1353 ret = vasprintf( &msgbuf, format_str, ap );
1359 #if defined(HAVE_SYSLOG)
1360 syslog( priority, "%s", msgbuf );
1362 DEBUG(0,("%s", msgbuf ));
1367 /**************************************************************************
1368 Wrappers for extented attribute calls. Based on the Linux package with
1369 support for IRIX also. Expand as other systems have them.
1370 ****************************************************************************/
1372 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1374 #if defined(HAVE_GETXATTR)
1375 return getxattr(path, name, value, size);
1376 #elif defined(HAVE_ATTR_GET)
1377 int retval, flags = 0;
1378 int valuelength = (int)size;
1379 char *attrname = strchr(name,'.') +1;
1381 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1383 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1385 return retval ? retval : valuelength;
1392 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1394 #if defined(HAVE_LGETXATTR)
1395 return lgetxattr(path, name, value, size);
1396 #elif defined(HAVE_ATTR_GET)
1397 int retval, flags = ATTR_DONTFOLLOW;
1398 int valuelength = (int)size;
1399 char *attrname = strchr(name,'.') +1;
1401 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1403 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1405 return retval ? retval : valuelength;
1412 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1414 #if defined(HAVE_FGETXATTR)
1415 return fgetxattr(filedes, name, value, size);
1416 #elif defined(HAVE_ATTR_GETF)
1417 int retval, flags = 0;
1418 int valuelength = (int)size;
1419 char *attrname = strchr(name,'.') +1;
1421 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1423 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1425 return retval ? retval : valuelength;
1432 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1433 static char attr_buffer[ATTR_MAX_VALUELEN];
1435 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1437 int retval = 0, index;
1438 attrlist_cursor_t *cursor = 0;
1440 attrlist_t * al = (attrlist_t *)attr_buffer;
1442 size_t ent_size, left = size;
1447 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1449 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1451 for (index = 0; index < al->al_count; index++) {
1452 ae = ATTR_ENTRY(attr_buffer, index);
1453 ent_size = strlen(ae->a_name) + sizeof("user.");
1454 if (left >= ent_size) {
1455 strncpy(bp, "user.", sizeof("user."));
1456 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1464 total_size += ent_size;
1466 if (al->al_more == 0) break;
1473 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1475 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1477 for (index = 0; index < al->al_count; index++) {
1478 ae = ATTR_ENTRY(attr_buffer, index);
1479 ent_size = strlen(ae->a_name) + sizeof("system.");
1480 if (left >= ent_size) {
1481 strncpy(bp, "system.", sizeof("system."));
1482 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1490 total_size += ent_size;
1492 if (al->al_more == 0) break;
1495 return (ssize_t)(retval ? retval : total_size);
1500 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1502 #if defined(HAVE_LISTXATTR)
1503 return listxattr(path, list, size);
1504 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1505 return irix_attr_list(path, 0, list, size, 0);
1512 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1514 #if defined(HAVE_LLISTXATTR)
1515 return llistxattr(path, list, size);
1516 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1517 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1524 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1526 #if defined(HAVE_FLISTXATTR)
1527 return flistxattr(filedes, list, size);
1528 #elif defined(HAVE_ATTR_LISTF)
1529 return irix_attr_list(NULL, filedes, list, size, 0);
1536 int sys_removexattr (const char *path, const char *name)
1538 #if defined(HAVE_REMOVEXATTR)
1539 return removexattr(path, name);
1540 #elif defined(HAVE_ATTR_REMOVE)
1542 char *attrname = strchr(name,'.') +1;
1544 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1546 return attr_remove(path, attrname, flags);
1553 int sys_lremovexattr (const char *path, const char *name)
1555 #if defined(HAVE_LREMOVEXATTR)
1556 return lremovexattr(path, name);
1557 #elif defined(HAVE_ATTR_REMOVE)
1558 int flags = ATTR_DONTFOLLOW;
1559 char *attrname = strchr(name,'.') +1;
1561 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1563 return attr_remove(path, attrname, flags);
1570 int sys_fremovexattr (int filedes, const char *name)
1572 #if defined(HAVE_FREMOVEXATTR)
1573 return fremovexattr(filedes, name);
1574 #elif defined(HAVE_ATTR_REMOVEF)
1576 char *attrname = strchr(name,'.') +1;
1578 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1580 return attr_removef(filedes, attrname, flags);
1587 #if !defined(HAVE_SETXATTR)
1588 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1589 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1592 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1594 #if defined(HAVE_SETXATTR)
1595 return setxattr(path, name, value, size, flags);
1596 #elif defined(HAVE_ATTR_SET)
1598 char *attrname = strchr(name,'.') +1;
1600 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1601 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1602 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1604 return attr_set(path, attrname, (const char *)value, size, myflags);
1611 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1613 #if defined(HAVE_LSETXATTR)
1614 return lsetxattr(path, name, value, size, flags);
1615 #elif defined(HAVE_ATTR_SET)
1616 int myflags = ATTR_DONTFOLLOW;
1617 char *attrname = strchr(name,'.') +1;
1619 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1620 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1621 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1623 return attr_set(path, attrname, (const char *)value, size, myflags);
1630 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
1632 #if defined(HAVE_FSETXATTR)
1633 return fsetxattr(filedes, name, value, size, flags);
1634 #elif defined(HAVE_ATTR_SETF)
1636 char *attrname = strchr(name,'.') +1;
1638 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1639 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1640 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1642 return attr_setf(filedes, attrname, (const char *)value, size, myflags);
1649 /****************************************************************************
1650 Return the major devicenumber for UNIX extensions.
1651 ****************************************************************************/
1653 uint32 unix_dev_major(SMB_DEV_T dev)
1655 #if defined(HAVE_DEVICE_MAJOR_FN)
1656 return (uint32)major(dev);
1658 return (uint32)(dev >> 8);
1662 /****************************************************************************
1663 Return the minor devicenumber for UNIX extensions.
1664 ****************************************************************************/
1666 uint32 unix_dev_minor(SMB_DEV_T dev)
1668 #if defined(HAVE_DEVICE_MINOR_FN)
1669 return (uint32)minor(dev);
1671 return (uint32)(dev & 0xff);