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
);
103 /*******************************************************************
104 A send wrapper that will deal with EINTR.
105 ********************************************************************/
107 ssize_t
sys_send(int s
, const void *msg
, size_t len
, int flags
)
112 ret
= send(s
, msg
, len
, flags
);
113 } while (ret
== -1 && errno
== EINTR
);
117 /*******************************************************************
118 A sendto wrapper that will deal with EINTR.
119 ********************************************************************/
121 ssize_t
sys_sendto(int s
, const void *msg
, size_t len
, int flags
, const struct sockaddr
*to
, socklen_t tolen
)
126 ret
= sendto(s
, msg
, len
, flags
, to
, tolen
);
127 } while (ret
== -1 && errno
== EINTR
);
131 /*******************************************************************
132 A recvfrom wrapper that will deal with EINTR.
133 ********************************************************************/
135 ssize_t
sys_recvfrom(int s
, void *buf
, size_t len
, int flags
, struct sockaddr
*from
, socklen_t
*fromlen
)
140 ret
= recvfrom(s
, buf
, len
, flags
, from
, fromlen
);
141 } while (ret
== -1 && errno
== EINTR
);
145 /*******************************************************************
146 A fcntl wrapper that will deal with EINTR.
147 ********************************************************************/
149 int sys_fcntl_ptr(int fd
, int cmd
, void *arg
)
154 ret
= fcntl(fd
, cmd
, arg
);
155 } while (ret
== -1 && errno
== EINTR
);
159 /*******************************************************************
160 A fcntl wrapper that will deal with EINTR.
161 ********************************************************************/
163 int sys_fcntl_long(int fd
, int cmd
, long arg
)
168 ret
= fcntl(fd
, cmd
, arg
);
169 } while (ret
== -1 && errno
== EINTR
);
173 /*******************************************************************
174 A stat() wrapper that will deal with 64 bit filesizes.
175 ********************************************************************/
177 int sys_stat(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
180 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
181 ret
= stat64(fname
, sbuf
);
183 ret
= stat(fname
, sbuf
);
185 /* we always want directories to appear zero size */
186 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
190 /*******************************************************************
191 An fstat() wrapper that will deal with 64 bit filesizes.
192 ********************************************************************/
194 int sys_fstat(int fd
,SMB_STRUCT_STAT
*sbuf
)
197 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
198 ret
= fstat64(fd
, sbuf
);
200 ret
= fstat(fd
, sbuf
);
202 /* we always want directories to appear zero size */
203 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
207 /*******************************************************************
208 An lstat() wrapper that will deal with 64 bit filesizes.
209 ********************************************************************/
211 int sys_lstat(const char *fname
,SMB_STRUCT_STAT
*sbuf
)
214 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
215 ret
= lstat64(fname
, sbuf
);
217 ret
= lstat(fname
, sbuf
);
219 /* we always want directories to appear zero size */
220 if (ret
== 0 && S_ISDIR(sbuf
->st_mode
)) sbuf
->st_size
= 0;
224 /*******************************************************************
225 An ftruncate() wrapper that will deal with 64 bit filesizes.
226 ********************************************************************/
228 int sys_ftruncate(int fd
, SMB_OFF_T offset
)
230 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
231 return ftruncate64(fd
, offset
);
233 return ftruncate(fd
, offset
);
237 /*******************************************************************
238 An lseek() wrapper that will deal with 64 bit filesizes.
239 ********************************************************************/
241 SMB_OFF_T
sys_lseek(int fd
, SMB_OFF_T offset
, int whence
)
243 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
244 return lseek64(fd
, offset
, whence
);
246 return lseek(fd
, offset
, whence
);
250 /*******************************************************************
251 An fseek() wrapper that will deal with 64 bit filesizes.
252 ********************************************************************/
254 int sys_fseek(FILE *fp
, SMB_OFF_T offset
, int whence
)
256 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
257 return fseek64(fp
, offset
, whence
);
258 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
259 return fseeko64(fp
, offset
, whence
);
261 return fseek(fp
, offset
, whence
);
265 /*******************************************************************
266 An ftell() wrapper that will deal with 64 bit filesizes.
267 ********************************************************************/
269 SMB_OFF_T
sys_ftell(FILE *fp
)
271 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
272 return (SMB_OFF_T
)ftell64(fp
);
273 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
274 return (SMB_OFF_T
)ftello64(fp
);
276 return (SMB_OFF_T
)ftell(fp
);
280 /*******************************************************************
281 A creat() wrapper that will deal with 64 bit filesizes.
282 ********************************************************************/
284 int sys_creat(const char *path
, mode_t mode
)
286 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
287 return creat64(path
, mode
);
290 * If creat64 isn't defined then ensure we call a potential open64.
293 return sys_open(path
, O_WRONLY
| O_CREAT
| O_TRUNC
, mode
);
297 /*******************************************************************
298 An open() wrapper that will deal with 64 bit filesizes.
299 ********************************************************************/
301 int sys_open(const char *path
, int oflag
, mode_t mode
)
303 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
304 return open64(path
, oflag
, mode
);
306 return open(path
, oflag
, mode
);
310 /*******************************************************************
311 An fopen() wrapper that will deal with 64 bit filesizes.
312 ********************************************************************/
314 FILE *sys_fopen(const char *path
, const char *type
)
316 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
317 return fopen64(path
, type
);
319 return fopen(path
, type
);
323 /*******************************************************************
324 A readdir wrapper that will deal with 64 bit filesizes.
325 ********************************************************************/
327 SMB_STRUCT_DIRENT
*sys_readdir(DIR *dirp
)
329 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
330 return readdir64(dirp
);
332 return readdir(dirp
);
336 /*******************************************************************
337 An mknod() wrapper that will deal with 64 bit filesizes.
338 ********************************************************************/
340 int sys_mknod(const char *path
, mode_t mode
, SMB_DEV_T dev
)
342 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
343 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
344 return mknod64(path
, mode
, dev
);
346 return mknod(path
, mode
, dev
);
349 /* No mknod system call. */
355 /*******************************************************************
356 Wrapper for realpath.
357 ********************************************************************/
359 char *sys_realpath(const char *path
, char *resolved_path
)
361 #if defined(HAVE_REALPATH)
362 return realpath(path
, resolved_path
);
364 /* As realpath is not a system call we can't return ENOSYS. */
370 /*******************************************************************
371 The wait() calls vary between systems
372 ********************************************************************/
374 int sys_waitpid(pid_t pid
,int *status
,int options
)
377 return waitpid(pid
,status
,options
);
378 #else /* HAVE_WAITPID */
379 return wait4(pid
, status
, options
, NULL
);
380 #endif /* HAVE_WAITPID */
383 /*******************************************************************
384 System wrapper for getwd
385 ********************************************************************/
387 char *sys_getwd(char *s
)
391 wd
= (char *)getcwd(s
, sizeof (pstring
));
393 wd
= (char *)getwd(s
);
398 /*******************************************************************
399 system wrapper for symlink
400 ********************************************************************/
402 int sys_symlink(const char *oldpath
, const char *newpath
)
408 return symlink(oldpath
, newpath
);
412 /*******************************************************************
413 system wrapper for readlink
414 ********************************************************************/
416 int sys_readlink(const char *path
, char *buf
, size_t bufsiz
)
418 #ifndef HAVE_READLINK
422 return readlink(path
, buf
, bufsiz
);
426 /*******************************************************************
427 system wrapper for link
428 ********************************************************************/
430 int sys_link(const char *oldpath
, const char *newpath
)
436 return link(oldpath
, newpath
);
440 /*******************************************************************
441 chown isn't used much but OS/2 doesn't have it
442 ********************************************************************/
444 int sys_chown(const char *fname
,uid_t uid
,gid_t gid
)
449 DEBUG(1,("WARNING: no chown!\n"));
453 return(chown(fname
,uid
,gid
));
457 /*******************************************************************
458 os/2 also doesn't have chroot
459 ********************************************************************/
460 int sys_chroot(const char *dname
)
465 DEBUG(1,("WARNING: no chroot!\n"));
471 return(chroot(dname
));
475 /**************************************************************************
476 A wrapper for gethostbyname() that tries avoids looking up hostnames
477 in the root domain, which can cause dial-on-demand links to come up for no
479 ****************************************************************************/
481 struct hostent
*sys_gethostbyname(const char *name
)
483 #ifdef REDUCE_ROOT_DNS_LOOKUPS
484 char query
[256], hostname
[256];
487 /* Does this name have any dots in it? If so, make no change */
489 if (strchr_m(name
, '.'))
490 return(gethostbyname(name
));
492 /* Get my hostname, which should have domain name
493 attached. If not, just do the gethostname on the
497 gethostname(hostname
, sizeof(hostname
) - 1);
498 hostname
[sizeof(hostname
) - 1] = 0;
499 if ((domain
= strchr_m(hostname
, '.')) == NULL
)
500 return(gethostbyname(name
));
502 /* Attach domain name to query and do modified query.
503 If names too large, just do gethostname on the
507 if((strlen(name
) + strlen(domain
)) >= sizeof(query
))
508 return(gethostbyname(name
));
510 slprintf(query
, sizeof(query
)-1, "%s%s", name
, domain
);
511 return(gethostbyname(query
));
512 #else /* REDUCE_ROOT_DNS_LOOKUPS */
513 return(gethostbyname(name
));
514 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
518 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
519 /**************************************************************************
520 Try and abstract process capabilities (for systems that have them).
521 ****************************************************************************/
522 static BOOL
set_process_capability( uint32 cap_flag
, BOOL enable
)
524 if(cap_flag
== KERNEL_OPLOCK_CAPABILITY
) {
525 cap_t cap
= cap_get_proc();
528 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
534 cap
->cap_effective
|= CAP_NETWORK_MGT
;
536 cap
->cap_effective
&= ~CAP_NETWORK_MGT
;
538 if (cap_set_proc(cap
) == -1) {
539 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
547 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
552 /**************************************************************************
553 Try and abstract inherited process capabilities (for systems that have them).
554 ****************************************************************************/
556 static BOOL
set_inherited_process_capability( uint32 cap_flag
, BOOL enable
)
558 if(cap_flag
== KERNEL_OPLOCK_CAPABILITY
) {
559 cap_t cap
= cap_get_proc();
562 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
568 cap
->cap_inheritable
|= CAP_NETWORK_MGT
;
570 cap
->cap_inheritable
&= ~CAP_NETWORK_MGT
;
572 if (cap_set_proc(cap
) == -1) {
573 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
581 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
587 /****************************************************************************
588 Gain the oplock capability from the kernel if possible.
589 ****************************************************************************/
591 void oplock_set_capability(BOOL this_process
, BOOL inherit
)
593 #if HAVE_KERNEL_OPLOCKS_IRIX
594 set_process_capability(KERNEL_OPLOCK_CAPABILITY
,this_process
);
595 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY
,inherit
);
599 /**************************************************************************
600 Wrapper for random().
601 ****************************************************************************/
603 long sys_random(void)
605 #if defined(HAVE_RANDOM)
606 return (long)random();
607 #elif defined(HAVE_RAND)
610 DEBUG(0,("Error - no random function available !\n"));
615 /**************************************************************************
616 Wrapper for srandom().
617 ****************************************************************************/
619 void sys_srandom(unsigned int seed
)
621 #if defined(HAVE_SRANDOM)
623 #elif defined(HAVE_SRAND)
626 DEBUG(0,("Error - no srandom function available !\n"));
631 /**************************************************************************
632 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
633 ****************************************************************************/
637 #if defined(SYSCONF_SC_NGROUPS_MAX)
638 int ret
= sysconf(_SC_NGROUPS_MAX
);
639 return (ret
== -1) ? NGROUPS_MAX
: ret
;
645 /**************************************************************************
646 Wrapper for getgroups. Deals with broken (int) case.
647 ****************************************************************************/
649 int sys_getgroups(int setlen
, gid_t
*gidset
)
651 #if !defined(HAVE_BROKEN_GETGROUPS)
652 return getgroups(setlen
, gidset
);
660 return getgroups(setlen
, &gid
);
664 * Broken case. We need to allocate a
665 * GID_T array of size setlen.
674 setlen
= groups_max();
676 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
677 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
681 if((ngroups
= getgroups(setlen
, group_list
)) < 0) {
682 int saved_errno
= errno
;
683 SAFE_FREE(group_list
);
688 for(i
= 0; i
< ngroups
; i
++)
689 gidset
[i
] = (gid_t
)group_list
[i
];
691 SAFE_FREE(group_list
);
693 #endif /* HAVE_BROKEN_GETGROUPS */
696 #ifdef HAVE_SETGROUPS
698 /**************************************************************************
699 Wrapper for setgroups. Deals with broken (int) case. Automatically used
700 if we have broken getgroups.
701 ****************************************************************************/
703 int sys_setgroups(int setlen
, gid_t
*gidset
)
705 #if !defined(HAVE_BROKEN_GETGROUPS)
706 return setgroups(setlen
, gidset
);
715 if (setlen
< 0 || setlen
> groups_max()) {
721 * Broken case. We need to allocate a
722 * GID_T array of size setlen.
725 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
726 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
730 for(i
= 0; i
< setlen
; i
++)
731 group_list
[i
] = (GID_T
) gidset
[i
];
733 if(setgroups(setlen
, group_list
) != 0) {
734 int saved_errno
= errno
;
735 SAFE_FREE(group_list
);
740 SAFE_FREE(group_list
);
742 #endif /* HAVE_BROKEN_GETGROUPS */
745 #endif /* HAVE_SETGROUPS */
747 /**************************************************************************
748 Wrappers for setpwent(), getpwent() and endpwent()
749 ****************************************************************************/
751 void sys_setpwent(void)
756 struct passwd
*sys_getpwent(void)
761 void sys_endpwent(void)
766 /**************************************************************************
767 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
768 ****************************************************************************/
770 struct passwd
*sys_getpwnam(const char *name
)
772 return getpwnam(name
);
775 struct passwd
*sys_getpwuid(uid_t uid
)
777 return getpwuid(uid
);
780 struct group
*sys_getgrnam(const char *name
)
782 return getgrnam(name
);
785 struct group
*sys_getgrgid(gid_t gid
)
787 return getgrgid(gid
);
790 #if 0 /* NOT CURRENTLY USED - JRA */
791 /**************************************************************************
792 The following are the UNICODE versions of *all* system interface functions
793 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
794 which currently are left as ascii as they are not used other than in name
796 ****************************************************************************/
798 /**************************************************************************
799 Wide stat. Just narrow and call sys_xxx.
800 ****************************************************************************/
802 int wsys_stat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
805 return sys_stat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
808 /**************************************************************************
809 Wide lstat. Just narrow and call sys_xxx.
810 ****************************************************************************/
812 int wsys_lstat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
815 return sys_lstat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
818 /**************************************************************************
819 Wide creat. Just narrow and call sys_xxx.
820 ****************************************************************************/
822 int wsys_creat(const smb_ucs2_t
*wfname
, mode_t mode
)
825 return sys_creat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), mode
);
828 /**************************************************************************
829 Wide open. Just narrow and call sys_xxx.
830 ****************************************************************************/
832 int wsys_open(const smb_ucs2_t
*wfname
, int oflag
, mode_t mode
)
835 return sys_open(unicode_to_unix(fname
,wfname
,sizeof(fname
)), oflag
, mode
);
838 /**************************************************************************
839 Wide fopen. Just narrow and call sys_xxx.
840 ****************************************************************************/
842 FILE *wsys_fopen(const smb_ucs2_t
*wfname
, const char *type
)
845 return sys_fopen(unicode_to_unix(fname
,wfname
,sizeof(fname
)), type
);
848 /**************************************************************************
849 Wide opendir. Just narrow and call sys_xxx.
850 ****************************************************************************/
852 DIR *wsys_opendir(const smb_ucs2_t
*wfname
)
855 return opendir(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
858 /**************************************************************************
859 Wide readdir. Return a structure pointer containing a wide filename.
860 ****************************************************************************/
862 SMB_STRUCT_WDIRENT
*wsys_readdir(DIR *dirp
)
864 static SMB_STRUCT_WDIRENT retval
;
865 SMB_STRUCT_DIRENT
*dirval
= sys_readdir(dirp
);
871 * The only POSIX defined member of this struct is d_name.
874 unix_to_unicode(retval
.d_name
,dirval
->d_name
,sizeof(retval
.d_name
));
879 /**************************************************************************
880 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
881 ****************************************************************************/
883 smb_ucs2_t
*wsys_getwd(smb_ucs2_t
*s
)
886 char *p
= sys_getwd(fname
);
891 return unix_to_unicode(s
, p
, sizeof(wpstring
));
894 /**************************************************************************
895 Wide chown. Just narrow and call sys_xxx.
896 ****************************************************************************/
898 int wsys_chown(const smb_ucs2_t
*wfname
, uid_t uid
, gid_t gid
)
901 return chown(unicode_to_unix(fname
,wfname
,sizeof(fname
)), uid
, gid
);
904 /**************************************************************************
905 Wide chroot. Just narrow and call sys_xxx.
906 ****************************************************************************/
908 int wsys_chroot(const smb_ucs2_t
*wfname
)
911 return chroot(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
914 /**************************************************************************
915 Wide getpwnam. Return a structure pointer containing wide names.
916 ****************************************************************************/
918 SMB_STRUCT_WPASSWD
*wsys_getpwnam(const smb_ucs2_t
*wname
)
920 static SMB_STRUCT_WPASSWD retval
;
922 struct passwd
*pwret
= sys_getpwnam(unicode_to_unix(name
,wname
,sizeof(name
)));
927 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
928 retval
.pw_passwd
= pwret
->pw_passwd
;
929 retval
.pw_uid
= pwret
->pw_uid
;
930 retval
.pw_gid
= pwret
->pw_gid
;
931 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
932 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
933 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
938 /**************************************************************************
939 Wide getpwuid. Return a structure pointer containing wide names.
940 ****************************************************************************/
942 SMB_STRUCT_WPASSWD
*wsys_getpwuid(uid_t uid
)
944 static SMB_STRUCT_WPASSWD retval
;
945 struct passwd
*pwret
= sys_getpwuid(uid
);
950 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
951 retval
.pw_passwd
= pwret
->pw_passwd
;
952 retval
.pw_uid
= pwret
->pw_uid
;
953 retval
.pw_gid
= pwret
->pw_gid
;
954 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
955 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
956 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
960 #endif /* NOT CURRENTLY USED - JRA */
962 /**************************************************************************
963 Extract a command into an arg list. Uses a static pstring for storage.
964 Caller frees returned arg list (which contains pointers into the static pstring).
965 ****************************************************************************/
967 static char **extract_args(const char *command
)
969 static pstring trunc_cmd
;
975 pstrcpy(trunc_cmd
, command
);
977 if(!(ptr
= strtok(trunc_cmd
, " \t"))) {
986 for( argcl
= 1; ptr
; ptr
= strtok(NULL
, " \t"))
989 if((argl
= (char **)malloc((argcl
+ 1) * sizeof(char *))) == NULL
)
993 * Now do the extraction.
996 pstrcpy(trunc_cmd
, command
);
998 ptr
= strtok(trunc_cmd
, " \t");
1002 while((ptr
= strtok(NULL
, " \t")) != NULL
)
1009 /**************************************************************************
1010 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1011 a sys_getpid() that only does a system call *once*.
1012 ****************************************************************************/
1014 static pid_t mypid
= (pid_t
)-1;
1016 pid_t
sys_fork(void)
1018 pid_t forkret
= fork();
1020 if (forkret
== (pid_t
)0) /* Child - reset mypid so sys_getpid does a system call. */
1026 /**************************************************************************
1027 Wrapper for getpid. Ensures we only do a system call *once*.
1028 ****************************************************************************/
1030 pid_t
sys_getpid(void)
1032 if (mypid
== (pid_t
)-1)
1038 /**************************************************************************
1039 Wrapper for popen. Safer as it doesn't search a path.
1040 Modified from the glibc sources.
1041 modified by tridge to return a file descriptor. We must kick our FILE* habit
1042 ****************************************************************************/
1044 typedef struct _popen_list
1048 struct _popen_list
*next
;
1051 static popen_list
*popen_chain
;
1053 int sys_popen(const char *command
)
1055 int parent_end
, child_end
;
1057 popen_list
*entry
= NULL
;
1060 if (pipe(pipe_fds
) < 0)
1063 parent_end
= pipe_fds
[0];
1064 child_end
= pipe_fds
[1];
1071 if((entry
= (popen_list
*)malloc(sizeof(popen_list
))) == NULL
)
1074 ZERO_STRUCTP(entry
);
1077 * Extract the command and args into a NULL terminated array.
1080 if(!(argl
= extract_args(command
)))
1083 entry
->child_pid
= sys_fork();
1085 if (entry
->child_pid
== -1) {
1089 if (entry
->child_pid
== 0) {
1095 int child_std_end
= STDOUT_FILENO
;
1099 if (child_end
!= child_std_end
) {
1100 dup2 (child_end
, child_std_end
);
1105 * POSIX.2: "popen() shall ensure that any streams from previous
1106 * popen() calls that remain open in the parent process are closed
1107 * in the new child process."
1110 for (p
= popen_chain
; p
; p
= p
->next
)
1113 execv(argl
[0], argl
);
1124 /* Link into popen_chain. */
1125 entry
->next
= popen_chain
;
1126 popen_chain
= entry
;
1127 entry
->fd
= parent_end
;
1140 /**************************************************************************
1141 Wrapper for pclose. Modified from the glibc sources.
1142 ****************************************************************************/
1144 int sys_pclose(int fd
)
1147 popen_list
**ptr
= &popen_chain
;
1148 popen_list
*entry
= NULL
;
1152 /* Unlink from popen_chain. */
1153 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
) {
1154 if ((*ptr
)->fd
== fd
) {
1156 *ptr
= (*ptr
)->next
;
1162 if (status
< 0 || close(entry
->fd
) < 0)
1166 * As Samba is catching and eating child process
1167 * exits we don't really care about the child exit
1168 * code, a -1 with errno = ECHILD will do fine for us.
1172 wait_pid
= sys_waitpid (entry
->child_pid
, &wstatus
, 0);
1173 } while (wait_pid
== -1 && errno
== EINTR
);
1182 /**************************************************************************
1183 Wrappers for dlopen, dlsym, dlclose.
1184 ****************************************************************************/
1186 void *sys_dlopen(const char *name
, int flags
)
1188 #if defined(HAVE_DLOPEN)
1189 return dlopen(name
, flags
);
1195 void *sys_dlsym(void *handle
, const char *symbol
)
1197 #if defined(HAVE_DLSYM)
1198 return dlsym(handle
, symbol
);
1204 int sys_dlclose (void *handle
)
1206 #if defined(HAVE_DLCLOSE)
1207 return dlclose(handle
);
1213 const char *sys_dlerror(void)
1215 #if defined(HAVE_DLERROR)
1222 int sys_dup2(int oldfd
, int newfd
)
1224 #if defined(HAVE_DUP2)
1225 return dup2(oldfd
, newfd
);
1232 /**************************************************************************
1233 Wrapper for Admin Logs.
1234 ****************************************************************************/
1236 void sys_adminlog(int priority
, const char *format_str
, ...)
1240 char *msgbuf
= NULL
;
1242 va_start( ap
, format_str
);
1243 ret
= vasprintf( &msgbuf
, format_str
, ap
);
1249 #if defined(HAVE_SYSLOG)
1250 syslog( priority
, "%s", msgbuf
);
1252 DEBUG(0,("%s", msgbuf
));
1257 /**************************************************************************
1258 Wrappers for extented attribute calls. Based on the Linux package with
1259 support for IRIX also. Expand as other systems have them.
1260 ****************************************************************************/
1262 ssize_t
sys_getxattr (const char *path
, const char *name
, void *value
, size_t size
)
1264 #if defined(HAVE_GETXATTR)
1265 return getxattr(path
, name
, value
, size
);
1272 ssize_t
sys_lgetxattr (const char *path
, const char *name
, void *value
, size_t size
)
1274 #if defined(HAVE_LGETXATTR)
1275 return lgetxattr(path
, name
, value
, size
);
1282 ssize_t
sys_fgetxattr (int filedes
, const char *name
, void *value
, size_t size
)
1284 #if defined(HAVE_FGETXATTR)
1285 return fgetxattr(filedes
, name
, value
, size
);
1292 ssize_t
sys_listxattr (const char *path
, char *list
, size_t size
)
1294 #if defined(HAVE_LISTXATTR)
1295 return listxattr(path
, list
, size
);
1302 ssize_t
sys_llistxattr (const char *path
, char *list
, size_t size
)
1304 #if defined(HAVE_GETXATTR)
1305 return llistxattr(path
, list
, size
);
1312 ssize_t
sys_flistxattr (int filedes
, char *list
, size_t size
)
1314 #if defined(HAVE_FLISTXATTR)
1315 return flistxattr(filedes
, list
, size
);
1322 int sys_removexattr (const char *path
, const char *name
)
1324 #if defined(HAVE_REMOVEXATTR)
1325 return removexattr(path
, name
);
1332 int sys_lremovexattr (const char *path
, const char *name
)
1334 #if defined(HAVE_LREMOVEXATTR)
1335 return lremovexattr(path
, name
);
1342 int sys_fremovexattr (int filedes
, const char *name
)
1344 #if defined(HAVE_FREMOVEXATTR)
1345 return fremovexattr(filedes
, name
);
1352 int sys_setxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
1354 #if defined(HAVE_SETXATTR)
1355 return setxattr(path
, name
, value
, size
, flags
);
1362 int sys_lsetxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
1364 #if defined(HAVE_LSETXATTR)
1365 return lsetxattr(path
, name
, value
, size
, flags
);
1372 int sys_fsetxattr (int filedes
, const char *name
, const void *value
, size_t size
, int flags
)
1374 #if defined(HAVE_FSETXATTR)
1375 return fsetxattr(filedes
, name
, value
, size
, flags
);