2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
6 Copyright (C) Jeremy Allison 1998-2002
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
);
104 /*******************************************************************
105 A send wrapper that will deal with EINTR.
106 ********************************************************************/
108 ssize_t
sys_send(int s
, const void *msg
, size_t len
, int flags
)
113 ret
= send(s
, msg
, len
, flags
);
114 } while (ret
== -1 && errno
== EINTR
);
118 /*******************************************************************
119 A sendto wrapper that will deal with EINTR.
120 ********************************************************************/
122 ssize_t
sys_sendto(int s
, const void *msg
, size_t len
, int flags
, const struct sockaddr
*to
, socklen_t tolen
)
127 ret
= sendto(s
, msg
, len
, flags
, to
, tolen
);
128 } while (ret
== -1 && errno
== EINTR
);
132 /*******************************************************************
133 A recvfrom wrapper that will deal with EINTR.
134 ********************************************************************/
136 ssize_t
sys_recvfrom(int s
, void *buf
, size_t len
, int flags
, struct sockaddr
*from
, socklen_t
*fromlen
)
141 ret
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
);
142 } while (ret
== -1 && errno
== EINTR
);
146 /*******************************************************************
147 A fcntl wrapper that will deal with EINTR.
148 ********************************************************************/
150 int sys_fcntl_ptr(int fd
, int cmd
, void *arg
)
155 ret
= fcntl(fd
, cmd
, arg
);
156 } while (ret
== -1 && errno
== EINTR
);
160 /*******************************************************************
161 A fcntl wrapper that will deal with EINTR.
162 ********************************************************************/
164 int sys_fcntl_long(int fd
, int cmd
, long arg
)
169 ret
= fcntl(fd
, cmd
, arg
);
170 } while (ret
== -1 && errno
== EINTR
);
174 /*******************************************************************
175 A stat() wrapper that will deal with 64 bit filesizes.
176 ********************************************************************/
178 int sys_stat(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
181 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
182 ret
= stat64(fname
, sbuf
);
184 ret
= stat(fname
, sbuf
);
186 /* we always want directories to appear zero size */
187 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
191 /*******************************************************************
192 An fstat() wrapper that will deal with 64 bit filesizes.
193 ********************************************************************/
195 int sys_fstat(int fd
,SMB_STRUCT_STAT
*sbuf
)
198 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
199 ret
= fstat64(fd
, sbuf
);
201 ret
= fstat(fd
, sbuf
);
203 /* we always want directories to appear zero size */
204 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
208 /*******************************************************************
209 An lstat() wrapper that will deal with 64 bit filesizes.
210 ********************************************************************/
212 int sys_lstat(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
215 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
216 ret
= lstat64(fname
, sbuf
);
218 ret
= lstat(fname
, sbuf
);
220 /* we always want directories to appear zero size */
221 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
225 /*******************************************************************
226 An ftruncate() wrapper that will deal with 64 bit filesizes.
227 ********************************************************************/
229 int sys_ftruncate(int fd
, SMB_OFF_T offset
)
231 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
232 return ftruncate64(fd
, offset
);
234 return ftruncate(fd
, offset
);
238 /*******************************************************************
239 An lseek() wrapper that will deal with 64 bit filesizes.
240 ********************************************************************/
242 SMB_OFF_T
sys_lseek(int fd
, SMB_OFF_T offset
, int whence
)
244 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
245 return lseek64(fd
, offset
, whence
);
247 return lseek(fd
, offset
, whence
);
251 /*******************************************************************
252 An fseek() wrapper that will deal with 64 bit filesizes.
253 ********************************************************************/
255 int sys_fseek(FILE *fp
, SMB_OFF_T offset
, int whence
)
257 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
258 return fseek64(fp
, offset
, whence
);
259 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
260 return fseeko64(fp
, offset
, whence
);
262 return fseek(fp
, offset
, whence
);
266 /*******************************************************************
267 An ftell() wrapper that will deal with 64 bit filesizes.
268 ********************************************************************/
270 SMB_OFF_T
sys_ftell(FILE *fp
)
272 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
273 return (SMB_OFF_T
)ftell64(fp
);
274 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
275 return (SMB_OFF_T
)ftello64(fp
);
277 return (SMB_OFF_T
)ftell(fp
);
281 /*******************************************************************
282 A creat() wrapper that will deal with 64 bit filesizes.
283 ********************************************************************/
285 int sys_creat(const char *path
, mode_t mode
)
287 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
288 return creat64(path
, mode
);
291 * If creat64 isn't defined then ensure we call a potential open64.
294 return sys_open(path
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
298 /*******************************************************************
299 An open() wrapper that will deal with 64 bit filesizes.
300 ********************************************************************/
302 int sys_open(const char *path
, int oflag
, mode_t mode
)
304 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
305 return open64(path
, oflag
, mode
);
307 return open(path
, oflag
, mode
);
311 /*******************************************************************
312 An fopen() wrapper that will deal with 64 bit filesizes.
313 ********************************************************************/
315 FILE *sys_fopen(const char *path
, const char *type
)
317 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
318 return fopen64(path
, type
);
320 return fopen(path
, type
);
324 /*******************************************************************
325 A readdir wrapper that will deal with 64 bit filesizes.
326 ********************************************************************/
328 SMB_STRUCT_DIRENT
*sys_readdir(DIR *dirp
)
330 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
331 return readdir64(dirp
);
333 return readdir(dirp
);
337 /*******************************************************************
338 An mknod() wrapper that will deal with 64 bit filesizes.
339 ********************************************************************/
341 int sys_mknod(const char *path
, mode_t mode
, SMB_DEV_T dev
)
343 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
344 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
345 return mknod64(path
, mode
, dev
);
347 return mknod(path
, mode
, dev
);
350 /* No mknod system call. */
356 /*******************************************************************
357 Wrapper for realpath.
358 ********************************************************************/
360 char *sys_realpath(const char *path
, char *resolved_path
)
362 #if defined(HAVE_REALPATH)
363 return realpath(path
, resolved_path
);
365 /* As realpath is not a system call we can't return ENOSYS. */
371 /*******************************************************************
372 The wait() calls vary between systems
373 ********************************************************************/
375 int sys_waitpid(pid_t pid
,int *status
,int options
)
378 return waitpid(pid
,status
,options
);
379 #else /* HAVE_WAITPID */
380 return wait4(pid
, status
, options
, NULL
);
381 #endif /* HAVE_WAITPID */
384 /*******************************************************************
385 System wrapper for getwd
386 ********************************************************************/
388 char *sys_getwd(char *s
)
392 wd
= (char *)getcwd(s
, sizeof (pstring
));
394 wd
= (char *)getwd(s
);
399 /*******************************************************************
400 system wrapper for symlink
401 ********************************************************************/
403 int sys_symlink(const char *oldpath
, const char *newpath
)
409 return symlink(oldpath
, newpath
);
413 /*******************************************************************
414 system wrapper for readlink
415 ********************************************************************/
417 int sys_readlink(const char *path
, char *buf
, size_t bufsiz
)
419 #ifndef HAVE_READLINK
423 return readlink(path
, buf
, bufsiz
);
427 /*******************************************************************
428 system wrapper for link
429 ********************************************************************/
431 int sys_link(const char *oldpath
, const char *newpath
)
437 return link(oldpath
, newpath
);
441 /*******************************************************************
442 chown isn't used much but OS/2 doesn't have it
443 ********************************************************************/
445 int sys_chown(const char *fname
,uid_t uid
,gid_t gid
)
450 DEBUG(1,("WARNING: no chown!\n"));
454 return(chown(fname
,uid
,gid
));
458 /*******************************************************************
459 os/2 also doesn't have chroot
460 ********************************************************************/
461 int sys_chroot(const char *dname
)
466 DEBUG(1,("WARNING: no chroot!\n"));
472 return(chroot(dname
));
476 /**************************************************************************
477 A wrapper for gethostbyname() that tries avoids looking up hostnames
478 in the root domain, which can cause dial-on-demand links to come up for no
480 ****************************************************************************/
482 struct hostent
*sys_gethostbyname(const char *name
)
484 #ifdef REDUCE_ROOT_DNS_LOOKUPS
485 char query
[256], hostname
[256];
488 /* Does this name have any dots in it? If so, make no change */
490 if (strchr(name
, '.'))
491 return(gethostbyname(name
));
493 /* Get my hostname, which should have domain name
494 attached. If not, just do the gethostname on the
498 gethostname(hostname
, sizeof(hostname
) - 1);
499 hostname
[sizeof(hostname
) - 1] = 0;
500 if ((domain
= strchr(hostname
, '.')) == NULL
)
501 return(gethostbyname(name
));
503 /* Attach domain name to query and do modified query.
504 If names too large, just do gethostname on the
508 if((strlen(name
) + strlen(domain
)) >= sizeof(query
))
509 return(gethostbyname(name
));
511 slprintf(query
, sizeof(query
)-1, "%s%s", name
, domain
);
512 return(gethostbyname(query
));
513 #else /* REDUCE_ROOT_DNS_LOOKUPS */
514 return(gethostbyname(name
));
515 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
519 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
520 /**************************************************************************
521 Try and abstract process capabilities (for systems that have them).
522 ****************************************************************************/
523 static BOOL
set_process_capability( uint32 cap_flag
, BOOL enable
)
525 if(cap_flag
== KERNEL_OPLOCK_CAPABILITY
) {
526 cap_t cap
= cap_get_proc();
529 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
535 cap
->cap_effective
|= CAP_NETWORK_MGT
;
537 cap
->cap_effective
&= ~CAP_NETWORK_MGT
;
539 if (cap_set_proc(cap
) == -1) {
540 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
548 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
553 /**************************************************************************
554 Try and abstract inherited process capabilities (for systems that have them).
555 ****************************************************************************/
557 static BOOL
set_inherited_process_capability( uint32 cap_flag
, BOOL enable
)
559 if(cap_flag
== KERNEL_OPLOCK_CAPABILITY
) {
560 cap_t cap
= cap_get_proc();
563 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
569 cap
->cap_inheritable
|= CAP_NETWORK_MGT
;
571 cap
->cap_inheritable
&= ~CAP_NETWORK_MGT
;
573 if (cap_set_proc(cap
) == -1) {
574 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
582 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
588 /****************************************************************************
589 Gain the oplock capability from the kernel if possible.
590 ****************************************************************************/
592 void oplock_set_capability(BOOL this_process
, BOOL inherit
)
594 #if HAVE_KERNEL_OPLOCKS_IRIX
595 set_process_capability(KERNEL_OPLOCK_CAPABILITY
,this_process
);
596 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY
,inherit
);
600 /**************************************************************************
601 Wrapper for random().
602 ****************************************************************************/
604 long sys_random(void)
606 #if defined(HAVE_RANDOM)
607 return (long)random();
608 #elif defined(HAVE_RAND)
611 DEBUG(0,("Error - no random function available !\n"));
616 /**************************************************************************
617 Wrapper for srandom().
618 ****************************************************************************/
620 void sys_srandom(unsigned int seed
)
622 #if defined(HAVE_SRANDOM)
624 #elif defined(HAVE_SRAND)
627 DEBUG(0,("Error - no srandom function available !\n"));
632 /**************************************************************************
633 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
634 ****************************************************************************/
638 #if defined(SYSCONF_SC_NGROUPS_MAX)
639 int ret
= sysconf(_SC_NGROUPS_MAX
);
640 return (ret
== -1) ? NGROUPS_MAX
: ret
;
646 /**************************************************************************
647 Wrapper for getgroups. Deals with broken (int) case.
648 ****************************************************************************/
650 int sys_getgroups(int setlen
, gid_t
*gidset
)
652 #if !defined(HAVE_BROKEN_GETGROUPS)
653 return getgroups(setlen
, gidset
);
661 return getgroups(setlen
, &gid
);
665 * Broken case. We need to allocate a
666 * GID_T array of size setlen.
675 setlen
= groups_max();
677 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
678 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
682 if((ngroups
= getgroups(setlen
, group_list
)) < 0) {
683 int saved_errno
= errno
;
684 SAFE_FREE(group_list
);
689 for(i
= 0; i
< ngroups
; i
++)
690 gidset
[i
] = (gid_t
)group_list
[i
];
692 SAFE_FREE(group_list
);
694 #endif /* HAVE_BROKEN_GETGROUPS */
697 #ifdef HAVE_SETGROUPS
699 /**************************************************************************
700 Wrapper for setgroups. Deals with broken (int) case. Automatically used
701 if we have broken getgroups.
702 ****************************************************************************/
704 int sys_setgroups(int setlen
, gid_t
*gidset
)
706 #if !defined(HAVE_BROKEN_GETGROUPS)
707 return setgroups(setlen
, gidset
);
716 if (setlen
< 0 || setlen
> groups_max()) {
722 * Broken case. We need to allocate a
723 * GID_T array of size setlen.
726 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
727 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
731 for(i
= 0; i
< setlen
; i
++)
732 group_list
[i
] = (GID_T
) gidset
[i
];
734 if(setgroups(setlen
, group_list
) != 0) {
735 int saved_errno
= errno
;
736 SAFE_FREE(group_list
);
741 SAFE_FREE(group_list
);
743 #endif /* HAVE_BROKEN_GETGROUPS */
746 #endif /* HAVE_SETGROUPS */
749 * We only wrap pw_name and pw_passwd for now as these
750 * are the only potentially modified fields.
753 /**************************************************************************
754 Helper function for getpwnam/getpwuid wrappers.
755 ****************************************************************************/
766 static struct saved_pw pw_mod
; /* This is the structure returned - can be modified. */
767 static struct saved_pw pw_cache
; /* This is the structure saved - used to check cache. */
769 static int num_lookups
; /* Counter so we don't always use cache. */
770 #ifndef PW_RET_CACHE_MAX_LOOKUPS
771 #define PW_RET_CACHE_MAX_LOOKUPS 100
774 static void copy_pwent(struct saved_pw
*dst
, struct passwd
*pass
)
776 memcpy((char *)&dst
->pass
, pass
, sizeof(struct passwd
));
778 fstrcpy(dst
->pw_name
, pass
->pw_name
);
779 dst
->pass
.pw_name
= dst
->pw_name
;
781 fstrcpy(dst
->pw_passwd
, pass
->pw_passwd
);
782 dst
->pass
.pw_passwd
= dst
->pw_passwd
;
784 fstrcpy(dst
->pw_gecos
, pass
->pw_gecos
);
785 dst
->pass
.pw_gecos
= dst
->pw_gecos
;
787 pstrcpy(dst
->pw_dir
, pass
->pw_dir
);
788 dst
->pass
.pw_dir
= dst
->pw_dir
;
790 pstrcpy(dst
->pw_shell
, pass
->pw_shell
);
791 dst
->pass
.pw_shell
= dst
->pw_shell
;
794 static struct passwd
*setup_pwret(struct passwd
*pass
)
797 /* Clear the caches. */
798 memset(&pw_cache
, '\0', sizeof(struct saved_pw
));
799 memset(&pw_mod
, '\0', sizeof(struct saved_pw
));
804 copy_pwent( &pw_mod
, pass
);
806 if (pass
!= &pw_cache
.pass
) {
808 /* If it's a cache miss we must also refill the cache. */
810 copy_pwent( &pw_cache
, pass
);
818 num_lookups
= (num_lookups
% PW_RET_CACHE_MAX_LOOKUPS
);
824 /**************************************************************************
825 Wrappers for setpwent(), getpwent() and endpwent()
826 ****************************************************************************/
828 void sys_setpwent(void)
830 setup_pwret(NULL
); /* Clear cache. */
834 struct passwd
*sys_getpwent(void)
836 return setup_pwret(getpwent());
839 void sys_endpwent(void)
841 setup_pwret(NULL
); /* Clear cache. */
845 /**************************************************************************
846 Wrapper for getpwnam(). Always returns a static that can be modified.
847 ****************************************************************************/
849 struct passwd
*sys_getpwnam(const char *name
)
851 if (!name
|| !name
[0])
854 /* check for a cache hit first */
855 if (num_lookups
&& pw_cache
.pass
.pw_name
&& !strcmp(name
, pw_cache
.pass
.pw_name
)) {
856 return setup_pwret(&pw_cache
.pass
);
859 return setup_pwret(getpwnam(name
));
862 /**************************************************************************
863 Wrapper for getpwuid(). Always returns a static that can be modified.
864 ****************************************************************************/
866 struct passwd
*sys_getpwuid(uid_t uid
)
868 if (num_lookups
&& pw_cache
.pass
.pw_name
&& (uid
== pw_cache
.pass
.pw_uid
)) {
869 return setup_pwret(&pw_cache
.pass
);
872 return setup_pwret(getpwuid(uid
));
875 #if 0 /* NOT CURRENTLY USED - JRA */
876 /**************************************************************************
877 The following are the UNICODE versions of *all* system interface functions
878 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
879 which currently are left as ascii as they are not used other than in name
881 ****************************************************************************/
883 /**************************************************************************
884 Wide stat. Just narrow and call sys_xxx.
885 ****************************************************************************/
887 int wsys_stat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
890 return sys_stat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
893 /**************************************************************************
894 Wide lstat. Just narrow and call sys_xxx.
895 ****************************************************************************/
897 int wsys_lstat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
900 return sys_lstat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
903 /**************************************************************************
904 Wide creat. Just narrow and call sys_xxx.
905 ****************************************************************************/
907 int wsys_creat(const smb_ucs2_t
*wfname
, mode_t mode
)
910 return sys_creat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), mode
);
913 /**************************************************************************
914 Wide open. Just narrow and call sys_xxx.
915 ****************************************************************************/
917 int wsys_open(const smb_ucs2_t
*wfname
, int oflag
, mode_t mode
)
920 return sys_open(unicode_to_unix(fname
,wfname
,sizeof(fname
)), oflag
, mode
);
923 /**************************************************************************
924 Wide fopen. Just narrow and call sys_xxx.
925 ****************************************************************************/
927 FILE *wsys_fopen(const smb_ucs2_t
*wfname
, const char *type
)
930 return sys_fopen(unicode_to_unix(fname
,wfname
,sizeof(fname
)), type
);
933 /**************************************************************************
934 Wide opendir. Just narrow and call sys_xxx.
935 ****************************************************************************/
937 DIR *wsys_opendir(const smb_ucs2_t
*wfname
)
940 return opendir(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
943 /**************************************************************************
944 Wide readdir. Return a structure pointer containing a wide filename.
945 ****************************************************************************/
947 SMB_STRUCT_WDIRENT
*wsys_readdir(DIR *dirp
)
949 static SMB_STRUCT_WDIRENT retval
;
950 SMB_STRUCT_DIRENT
*dirval
= sys_readdir(dirp
);
956 * The only POSIX defined member of this struct is d_name.
959 unix_to_unicode(retval
.d_name
,dirval
->d_name
,sizeof(retval
.d_name
));
964 /**************************************************************************
965 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
966 ****************************************************************************/
968 smb_ucs2_t
*wsys_getwd(smb_ucs2_t
*s
)
971 char *p
= sys_getwd(fname
);
976 return unix_to_unicode(s
, p
, sizeof(wpstring
));
979 /**************************************************************************
980 Wide chown. Just narrow and call sys_xxx.
981 ****************************************************************************/
983 int wsys_chown(const smb_ucs2_t
*wfname
, uid_t uid
, gid_t gid
)
986 return chown(unicode_to_unix(fname
,wfname
,sizeof(fname
)), uid
, gid
);
989 /**************************************************************************
990 Wide chroot. Just narrow and call sys_xxx.
991 ****************************************************************************/
993 int wsys_chroot(const smb_ucs2_t
*wfname
)
996 return chroot(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
999 /**************************************************************************
1000 Wide getpwnam. Return a structure pointer containing wide names.
1001 ****************************************************************************/
1003 SMB_STRUCT_WPASSWD
*wsys_getpwnam(const smb_ucs2_t
*wname
)
1005 static SMB_STRUCT_WPASSWD retval
;
1007 struct passwd
*pwret
= sys_getpwnam(unicode_to_unix(name
,wname
,sizeof(name
)));
1012 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
1013 retval
.pw_passwd
= pwret
->pw_passwd
;
1014 retval
.pw_uid
= pwret
->pw_uid
;
1015 retval
.pw_gid
= pwret
->pw_gid
;
1016 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
1017 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
1018 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
1023 /**************************************************************************
1024 Wide getpwuid. Return a structure pointer containing wide names.
1025 ****************************************************************************/
1027 SMB_STRUCT_WPASSWD
*wsys_getpwuid(uid_t uid
)
1029 static SMB_STRUCT_WPASSWD retval
;
1030 struct passwd
*pwret
= sys_getpwuid(uid
);
1035 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
1036 retval
.pw_passwd
= pwret
->pw_passwd
;
1037 retval
.pw_uid
= pwret
->pw_uid
;
1038 retval
.pw_gid
= pwret
->pw_gid
;
1039 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
1040 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
1041 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
1045 #endif /* NOT CURRENTLY USED - JRA */
1047 /**************************************************************************
1048 Extract a command into an arg list. Uses a static pstring for storage.
1049 Caller frees returned arg list (which contains pointers into the static pstring).
1050 ****************************************************************************/
1052 static char **extract_args(const char *command
)
1054 static pstring trunc_cmd
;
1060 pstrcpy(trunc_cmd
, command
);
1062 if(!(ptr
= strtok(trunc_cmd
, " \t"))) {
1071 for( argcl
= 1; ptr
; ptr
= strtok(NULL
, " \t"))
1074 if((argl
= (char **)malloc((argcl
+ 1) * sizeof(char *))) == NULL
)
1078 * Now do the extraction.
1081 pstrcpy(trunc_cmd
, command
);
1083 ptr
= strtok(trunc_cmd
, " \t");
1087 while((ptr
= strtok(NULL
, " \t")) != NULL
)
1094 /**************************************************************************
1095 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1096 a sys_getpid() that only does a system call *once*.
1097 ****************************************************************************/
1099 static pid_t mypid
= (pid_t
)-1;
1101 pid_t
sys_fork(void)
1103 pid_t forkret
= fork();
1105 if (forkret
== (pid_t
)0) /* Child - reset mypid so sys_getpid does a system call. */
1111 /**************************************************************************
1112 Wrapper for getpid. Ensures we only do a system call *once*.
1113 ****************************************************************************/
1115 pid_t
sys_getpid(void)
1117 if (mypid
== (pid_t
)-1)
1123 /**************************************************************************
1124 Wrapper for popen. Safer as it doesn't search a path.
1125 Modified from the glibc sources.
1126 modified by tridge to return a file descriptor. We must kick our FILE* habit
1127 ****************************************************************************/
1129 typedef struct _popen_list
1133 struct _popen_list
*next
;
1136 static popen_list
*popen_chain
;
1138 int sys_popen(const char *command
)
1140 int parent_end
, child_end
;
1142 popen_list
*entry
= NULL
;
1145 if (pipe(pipe_fds
) < 0)
1148 parent_end
= pipe_fds
[0];
1149 child_end
= pipe_fds
[1];
1156 if((entry
= (popen_list
*)malloc(sizeof(popen_list
))) == NULL
)
1159 ZERO_STRUCTP(entry
);
1162 * Extract the command and args into a NULL terminated array.
1165 if(!(argl
= extract_args(command
)))
1168 entry
->child_pid
= sys_fork();
1170 if (entry
->child_pid
== -1) {
1174 if (entry
->child_pid
== 0) {
1180 int child_std_end
= STDOUT_FILENO
;
1184 if (child_end
!= child_std_end
) {
1185 dup2 (child_end
, child_std_end
);
1190 * POSIX.2: "popen() shall ensure that any streams from previous
1191 * popen() calls that remain open in the parent process are closed
1192 * in the new child process."
1195 for (p
= popen_chain
; p
; p
= p
->next
)
1198 execv(argl
[0], argl
);
1209 /* Link into popen_chain. */
1210 entry
->next
= popen_chain
;
1211 popen_chain
= entry
;
1212 entry
->fd
= parent_end
;
1225 /**************************************************************************
1226 Wrapper for pclose. Modified from the glibc sources.
1227 ****************************************************************************/
1229 int sys_pclose(int fd
)
1232 popen_list
**ptr
= &popen_chain
;
1233 popen_list
*entry
= NULL
;
1237 /* Unlink from popen_chain. */
1238 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
) {
1239 if ((*ptr
)->fd
== fd
) {
1241 *ptr
= (*ptr
)->next
;
1247 if (status
< 0 || close(entry
->fd
) < 0)
1251 * As Samba is catching and eating child process
1252 * exits we don't really care about the child exit
1253 * code, a -1 with errno = ECHILD will do fine for us.
1257 wait_pid
= sys_waitpid (entry
->child_pid
, &wstatus
, 0);
1258 } while (wait_pid
== -1 && errno
== EINTR
);
1267 /**************************************************************************
1268 Wrappers for dlopen, dlsym, dlclose.
1269 ****************************************************************************/
1271 void *sys_dlopen(const char *name
, int flags
)
1273 #if defined(HAVE_DLOPEN)
1274 return dlopen(name
, flags
);
1280 void *sys_dlsym(void *handle
, char *symbol
)
1282 #if defined(HAVE_DLSYM)
1283 return dlsym(handle
, symbol
);
1289 int sys_dlclose (void *handle
)
1291 #if defined(HAVE_DLCLOSE)
1292 return dlclose(handle
);
1298 const char *sys_dlerror(void)
1300 #if defined(HAVE_DLERROR)
1307 /**************************************************************************
1308 Wrapper for Admin Logs.
1309 ****************************************************************************/
1311 void sys_adminlog(int priority
, const char *format_str
, ...)
1315 char **msgbuf
= NULL
;
1317 if (!lp_admin_log())
1320 va_start( ap
, format_str
);
1321 ret
= vasprintf( msgbuf
, format_str
, ap
);
1327 #if defined(HAVE_SYSLOG)
1328 syslog( priority
, "%s", *msgbuf
);
1330 DEBUG(0,("%s", *msgbuf
));