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 */
697 /**************************************************************************
698 Wrapper for setgroups. Deals with broken (int) case. Automatically used
699 if we have broken getgroups.
700 ****************************************************************************/
702 int sys_setgroups(int setlen
, gid_t
*gidset
)
704 #if !defined(HAVE_SETGROUPS)
707 #endif /* HAVE_SETGROUPS */
709 #if !defined(HAVE_BROKEN_GETGROUPS)
710 return setgroups(setlen
, gidset
);
719 if (setlen
< 0 || setlen
> groups_max()) {
725 * Broken case. We need to allocate a
726 * GID_T array of size setlen.
729 if((group_list
= (GID_T
*)malloc(setlen
* sizeof(GID_T
))) == NULL
) {
730 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
734 for(i
= 0; i
< setlen
; i
++)
735 group_list
[i
] = (GID_T
) gidset
[i
];
737 if(setgroups(setlen
, group_list
) != 0) {
738 int saved_errno
= errno
;
739 SAFE_FREE(group_list
);
744 SAFE_FREE(group_list
);
746 #endif /* HAVE_BROKEN_GETGROUPS */
749 /**************************************************************************
750 Wrappers for setpwent(), getpwent() and endpwent()
751 ****************************************************************************/
753 void sys_setpwent(void)
758 struct passwd
*sys_getpwent(void)
763 void sys_endpwent(void)
768 /**************************************************************************
769 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
770 ****************************************************************************/
772 struct passwd
*sys_getpwnam(const char *name
)
774 return getpwnam(name
);
777 struct passwd
*sys_getpwuid(uid_t uid
)
779 return getpwuid(uid
);
782 struct group
*sys_getgrnam(const char *name
)
784 return getgrnam(name
);
787 struct group
*sys_getgrgid(gid_t gid
)
789 return getgrgid(gid
);
792 #if 0 /* NOT CURRENTLY USED - JRA */
793 /**************************************************************************
794 The following are the UNICODE versions of *all* system interface functions
795 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
796 which currently are left as ascii as they are not used other than in name
798 ****************************************************************************/
800 /**************************************************************************
801 Wide stat. Just narrow and call sys_xxx.
802 ****************************************************************************/
804 int wsys_stat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
807 return sys_stat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
810 /**************************************************************************
811 Wide lstat. Just narrow and call sys_xxx.
812 ****************************************************************************/
814 int wsys_lstat(const smb_ucs2_t
*wfname
,SMB_STRUCT_STAT
*sbuf
)
817 return sys_lstat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), sbuf
);
820 /**************************************************************************
821 Wide creat. Just narrow and call sys_xxx.
822 ****************************************************************************/
824 int wsys_creat(const smb_ucs2_t
*wfname
, mode_t mode
)
827 return sys_creat(unicode_to_unix(fname
,wfname
,sizeof(fname
)), mode
);
830 /**************************************************************************
831 Wide open. Just narrow and call sys_xxx.
832 ****************************************************************************/
834 int wsys_open(const smb_ucs2_t
*wfname
, int oflag
, mode_t mode
)
837 return sys_open(unicode_to_unix(fname
,wfname
,sizeof(fname
)), oflag
, mode
);
840 /**************************************************************************
841 Wide fopen. Just narrow and call sys_xxx.
842 ****************************************************************************/
844 FILE *wsys_fopen(const smb_ucs2_t
*wfname
, const char *type
)
847 return sys_fopen(unicode_to_unix(fname
,wfname
,sizeof(fname
)), type
);
850 /**************************************************************************
851 Wide opendir. Just narrow and call sys_xxx.
852 ****************************************************************************/
854 DIR *wsys_opendir(const smb_ucs2_t
*wfname
)
857 return opendir(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
860 /**************************************************************************
861 Wide readdir. Return a structure pointer containing a wide filename.
862 ****************************************************************************/
864 SMB_STRUCT_WDIRENT
*wsys_readdir(DIR *dirp
)
866 static SMB_STRUCT_WDIRENT retval
;
867 SMB_STRUCT_DIRENT
*dirval
= sys_readdir(dirp
);
873 * The only POSIX defined member of this struct is d_name.
876 unix_to_unicode(retval
.d_name
,dirval
->d_name
,sizeof(retval
.d_name
));
881 /**************************************************************************
882 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
883 ****************************************************************************/
885 smb_ucs2_t
*wsys_getwd(smb_ucs2_t
*s
)
888 char *p
= sys_getwd(fname
);
893 return unix_to_unicode(s
, p
, sizeof(wpstring
));
896 /**************************************************************************
897 Wide chown. Just narrow and call sys_xxx.
898 ****************************************************************************/
900 int wsys_chown(const smb_ucs2_t
*wfname
, uid_t uid
, gid_t gid
)
903 return chown(unicode_to_unix(fname
,wfname
,sizeof(fname
)), uid
, gid
);
906 /**************************************************************************
907 Wide chroot. Just narrow and call sys_xxx.
908 ****************************************************************************/
910 int wsys_chroot(const smb_ucs2_t
*wfname
)
913 return chroot(unicode_to_unix(fname
,wfname
,sizeof(fname
)));
916 /**************************************************************************
917 Wide getpwnam. Return a structure pointer containing wide names.
918 ****************************************************************************/
920 SMB_STRUCT_WPASSWD
*wsys_getpwnam(const smb_ucs2_t
*wname
)
922 static SMB_STRUCT_WPASSWD retval
;
924 struct passwd
*pwret
= sys_getpwnam(unicode_to_unix(name
,wname
,sizeof(name
)));
929 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
930 retval
.pw_passwd
= pwret
->pw_passwd
;
931 retval
.pw_uid
= pwret
->pw_uid
;
932 retval
.pw_gid
= pwret
->pw_gid
;
933 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
934 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
935 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
940 /**************************************************************************
941 Wide getpwuid. Return a structure pointer containing wide names.
942 ****************************************************************************/
944 SMB_STRUCT_WPASSWD
*wsys_getpwuid(uid_t uid
)
946 static SMB_STRUCT_WPASSWD retval
;
947 struct passwd
*pwret
= sys_getpwuid(uid
);
952 unix_to_unicode(retval
.pw_name
, pwret
->pw_name
, sizeof(retval
.pw_name
));
953 retval
.pw_passwd
= pwret
->pw_passwd
;
954 retval
.pw_uid
= pwret
->pw_uid
;
955 retval
.pw_gid
= pwret
->pw_gid
;
956 unix_to_unicode(retval
.pw_gecos
, pwret
->pw_gecos
, sizeof(retval
.pw_gecos
));
957 unix_to_unicode(retval
.pw_dir
, pwret
->pw_dir
, sizeof(retval
.pw_dir
));
958 unix_to_unicode(retval
.pw_shell
, pwret
->pw_shell
, sizeof(retval
.pw_shell
));
962 #endif /* NOT CURRENTLY USED - JRA */
964 /**************************************************************************
965 Extract a command into an arg list. Uses a static pstring for storage.
966 Caller frees returned arg list (which contains pointers into the static pstring).
967 ****************************************************************************/
969 static char **extract_args(const char *command
)
971 static pstring trunc_cmd
;
977 pstrcpy(trunc_cmd
, command
);
979 if(!(ptr
= strtok(trunc_cmd
, " \t"))) {
988 for( argcl
= 1; ptr
; ptr
= strtok(NULL
, " \t"))
991 if((argl
= (char **)malloc((argcl
+ 1) * sizeof(char *))) == NULL
)
995 * Now do the extraction.
998 pstrcpy(trunc_cmd
, command
);
1000 ptr
= strtok(trunc_cmd
, " \t");
1004 while((ptr
= strtok(NULL
, " \t")) != NULL
)
1011 /**************************************************************************
1012 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1013 a sys_getpid() that only does a system call *once*.
1014 ****************************************************************************/
1016 static pid_t mypid
= (pid_t
)-1;
1018 pid_t
sys_fork(void)
1020 pid_t forkret
= fork();
1022 if (forkret
== (pid_t
)0) /* Child - reset mypid so sys_getpid does a system call. */
1028 /**************************************************************************
1029 Wrapper for getpid. Ensures we only do a system call *once*.
1030 ****************************************************************************/
1032 pid_t
sys_getpid(void)
1034 if (mypid
== (pid_t
)-1)
1040 /**************************************************************************
1041 Wrapper for popen. Safer as it doesn't search a path.
1042 Modified from the glibc sources.
1043 modified by tridge to return a file descriptor. We must kick our FILE* habit
1044 ****************************************************************************/
1046 typedef struct _popen_list
1050 struct _popen_list
*next
;
1053 static popen_list
*popen_chain
;
1055 int sys_popen(const char *command
)
1057 int parent_end
, child_end
;
1059 popen_list
*entry
= NULL
;
1062 if (pipe(pipe_fds
) < 0)
1065 parent_end
= pipe_fds
[0];
1066 child_end
= pipe_fds
[1];
1073 if((entry
= (popen_list
*)malloc(sizeof(popen_list
))) == NULL
)
1076 ZERO_STRUCTP(entry
);
1079 * Extract the command and args into a NULL terminated array.
1082 if(!(argl
= extract_args(command
)))
1085 entry
->child_pid
= sys_fork();
1087 if (entry
->child_pid
== -1) {
1091 if (entry
->child_pid
== 0) {
1097 int child_std_end
= STDOUT_FILENO
;
1101 if (child_end
!= child_std_end
) {
1102 dup2 (child_end
, child_std_end
);
1107 * POSIX.2: "popen() shall ensure that any streams from previous
1108 * popen() calls that remain open in the parent process are closed
1109 * in the new child process."
1112 for (p
= popen_chain
; p
; p
= p
->next
)
1115 execv(argl
[0], argl
);
1126 /* Link into popen_chain. */
1127 entry
->next
= popen_chain
;
1128 popen_chain
= entry
;
1129 entry
->fd
= parent_end
;
1142 /**************************************************************************
1143 Wrapper for pclose. Modified from the glibc sources.
1144 ****************************************************************************/
1146 int sys_pclose(int fd
)
1149 popen_list
**ptr
= &popen_chain
;
1150 popen_list
*entry
= NULL
;
1154 /* Unlink from popen_chain. */
1155 for ( ; *ptr
!= NULL
; ptr
= &(*ptr
)->next
) {
1156 if ((*ptr
)->fd
== fd
) {
1158 *ptr
= (*ptr
)->next
;
1164 if (status
< 0 || close(entry
->fd
) < 0)
1168 * As Samba is catching and eating child process
1169 * exits we don't really care about the child exit
1170 * code, a -1 with errno = ECHILD will do fine for us.
1174 wait_pid
= sys_waitpid (entry
->child_pid
, &wstatus
, 0);
1175 } while (wait_pid
== -1 && errno
== EINTR
);
1184 /**************************************************************************
1185 Wrappers for dlopen, dlsym, dlclose.
1186 ****************************************************************************/
1188 void *sys_dlopen(const char *name
, int flags
)
1190 #if defined(HAVE_DLOPEN)
1191 return dlopen(name
, flags
);
1197 void *sys_dlsym(void *handle
, const char *symbol
)
1199 #if defined(HAVE_DLSYM)
1200 return dlsym(handle
, symbol
);
1206 int sys_dlclose (void *handle
)
1208 #if defined(HAVE_DLCLOSE)
1209 return dlclose(handle
);
1215 const char *sys_dlerror(void)
1217 #if defined(HAVE_DLERROR)
1224 int sys_dup2(int oldfd
, int newfd
)
1226 #if defined(HAVE_DUP2)
1227 return dup2(oldfd
, newfd
);
1234 /**************************************************************************
1235 Wrapper for Admin Logs.
1236 ****************************************************************************/
1238 void sys_adminlog(int priority
, const char *format_str
, ...)
1242 char *msgbuf
= NULL
;
1244 va_start( ap
, format_str
);
1245 ret
= vasprintf( &msgbuf
, format_str
, ap
);
1251 #if defined(HAVE_SYSLOG)
1252 syslog( priority
, "%s", msgbuf
);
1254 DEBUG(0,("%s", msgbuf
));
1259 /**************************************************************************
1260 Wrappers for extented attribute calls. Based on the Linux package with
1261 support for IRIX also. Expand as other systems have them.
1262 ****************************************************************************/
1264 ssize_t
sys_getxattr (const char *path
, const char *name
, void *value
, size_t size
)
1266 #if defined(HAVE_GETXATTR)
1267 return getxattr(path
, name
, value
, size
);
1268 #elif defined(HAVE_ATTR_GET)
1269 int retval
, flags
= 0;
1270 int valuelength
= (int)size
;
1271 char *attrname
= strchr(name
,'.') +1;
1273 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1275 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1277 return retval
? retval
: valuelength
;
1284 ssize_t
sys_lgetxattr (const char *path
, const char *name
, void *value
, size_t size
)
1286 #if defined(HAVE_LGETXATTR)
1287 return lgetxattr(path
, name
, value
, size
);
1288 #elif defined(HAVE_ATTR_GET)
1289 int retval
, flags
= ATTR_DONTFOLLOW
;
1290 int valuelength
= (int)size
;
1291 char *attrname
= strchr(name
,'.') +1;
1293 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1295 retval
= attr_get(path
, attrname
, (char *)value
, &valuelength
, flags
);
1297 return retval
? retval
: valuelength
;
1304 ssize_t
sys_fgetxattr (int filedes
, const char *name
, void *value
, size_t size
)
1306 #if defined(HAVE_FGETXATTR)
1307 return fgetxattr(filedes
, name
, value
, size
);
1308 #elif defined(HAVE_ATTR_GETF)
1309 int retval
, flags
= 0;
1310 int valuelength
= (int)size
;
1311 char *attrname
= strchr(name
,'.') +1;
1313 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1315 retval
= attr_getf(filedes
, attrname
, (char *)value
, &valuelength
, flags
);
1317 return retval
? retval
: valuelength
;
1324 #if defined(HAVE_ATTR_LIST)
1325 static char attr_buffer
[ATTR_MAX_VALUELEN
];
1327 static ssize_t
irix_attr_list(const char *path
, int filedes
, char *list
, size_t size
, int flags
)
1329 int retval
= 0, index
;
1330 attrlist_cursor_t
*cursor
= 0;
1332 attrlist_t
* al
= (attrlist_t
*)attr_buffer
;
1334 size_t ent_size
, left
= size
;
1339 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1341 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1343 for (index
= 0; index
< al
->al_count
; index
++) {
1344 ae
= ATTR_ENTRY(attr_buffer
, index
);
1345 ent_size
= strlen(ae
->a_name
) + sizeof("user.");
1346 if (left
>= ent_size
) {
1347 strncpy(bp
, "user.", sizeof("user."));
1348 strncat(bp
, ae
->a_name
, ent_size
- sizeof("user."));
1356 total_size
+= ent_size
;
1358 if (al
->al_more
== 0) break;
1365 retval
= attr_listf(filedes
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1367 retval
= attr_list(path
, attr_buffer
, ATTR_MAX_VALUELEN
, flags
, cursor
);
1369 for (index
= 0; index
< al
->al_count
; index
++) {
1370 ae
= ATTR_ENTRY(attr_buffer
, index
);
1371 ent_size
= strlen(ae
->a_name
) + sizeof("system.");
1372 if (left
>= ent_size
) {
1373 strncpy(bp
, "system.", sizeof("system."));
1374 strncat(bp
, ae
->a_name
, ent_size
- sizeof("system."));
1382 total_size
+= ent_size
;
1384 if (al
->al_more
== 0) break;
1387 return (ssize_t
)(retval
? retval
: total_size
);
1392 ssize_t
sys_listxattr (const char *path
, char *list
, size_t size
)
1394 #if defined(HAVE_LISTXATTR)
1395 return listxattr(path
, list
, size
);
1396 #elif defined(HAVE_ATTR_LIST)
1397 return irix_attr_list(path
, 0, list
, size
, 0);
1404 ssize_t
sys_llistxattr (const char *path
, char *list
, size_t size
)
1406 #if defined(HAVE_LLISTXATTR)
1407 return llistxattr(path
, list
, size
);
1408 #elif defined(HAVE_ATTR_LIST)
1409 return irix_attr_list(path
, 0, list
, size
, ATTR_DONTFOLLOW
);
1416 ssize_t
sys_flistxattr (int filedes
, char *list
, size_t size
)
1418 #if defined(HAVE_FLISTXATTR)
1419 return flistxattr(filedes
, list
, size
);
1420 #elif defined(HAVE_ATTR_LISTF)
1421 return irix_attr_list(NULL
, filedes
, list
, size
, 0);
1428 int sys_removexattr (const char *path
, const char *name
)
1430 #if defined(HAVE_REMOVEXATTR)
1431 return removexattr(path
, name
);
1432 #elif defined(HAVE_ATTR_REMOVE)
1434 char *attrname
= strchr(name
,'.') +1;
1436 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1438 return attr_remove(path
, attrname
, flags
);
1445 int sys_lremovexattr (const char *path
, const char *name
)
1447 #if defined(HAVE_LREMOVEXATTR)
1448 return lremovexattr(path
, name
);
1449 #elif defined(HAVE_ATTR_REMOVE)
1450 int flags
= ATTR_DONTFOLLOW
;
1451 char *attrname
= strchr(name
,'.') +1;
1453 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1455 return attr_remove(path
, attrname
, flags
);
1462 int sys_fremovexattr (int filedes
, const char *name
)
1464 #if defined(HAVE_FREMOVEXATTR)
1465 return fremovexattr(filedes
, name
);
1466 #elif defined(HAVE_ATTR_REMOVEF)
1468 char *attrname
= strchr(name
,'.') +1;
1470 if (strncmp(name
, "system", 6) == 0) flags
|= ATTR_ROOT
;
1472 return attr_removef(filedes
, attrname
, flags
);
1479 #if !defined(HAVE_SETXATTR)
1480 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1481 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1484 int sys_setxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
1486 #if defined(HAVE_SETXATTR)
1487 return setxattr(path
, name
, value
, size
, flags
);
1488 #elif defined(HAVE_ATTR_SET)
1490 char *attrname
= strchr(name
,'.') +1;
1492 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
1493 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
1494 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
1496 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
1503 int sys_lsetxattr (const char *path
, const char *name
, const void *value
, size_t size
, int flags
)
1505 #if defined(HAVE_LSETXATTR)
1506 return lsetxattr(path
, name
, value
, size
, flags
);
1507 #elif defined(HAVE_ATTR_SET)
1508 int myflags
= ATTR_DONTFOLLOW
;
1509 char *attrname
= strchr(name
,'.') +1;
1511 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
1512 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
1513 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
1515 return attr_set(path
, attrname
, (const char *)value
, size
, myflags
);
1522 int sys_fsetxattr (int filedes
, const char *name
, const void *value
, size_t size
, int flags
)
1524 #if defined(HAVE_FSETXATTR)
1525 return fsetxattr(filedes
, name
, value
, size
, flags
);
1526 #elif defined(HAVE_ATTR_SETF)
1528 char *attrname
= strchr(name
,'.') +1;
1530 if (strncmp(name
, "system", 6) == 0) myflags
|= ATTR_ROOT
;
1531 if (flags
& XATTR_CREATE
) myflags
|= ATTR_CREATE
;
1532 if (flags
& XATTR_REPLACE
) myflags
|= ATTR_REPLACE
;
1534 return attr_setf(filedes
, attrname
, (const char *)value
, size
, myflags
);