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 */
748 * We only wrap pw_name and pw_passwd for now as these
749 * are the only potentially modified fields.
752 /**************************************************************************
753 Helper function for getpwnam/getpwuid wrappers.
754 ****************************************************************************/
765 static struct saved_pw pw_mod; /* This is the structure returned - can be modified. */
766 static struct saved_pw pw_cache; /* This is the structure saved - used to check cache. */
768 static int num_lookups; /* Counter so we don't always use cache. */
769 #ifndef PW_RET_CACHE_MAX_LOOKUPS
770 #define PW_RET_CACHE_MAX_LOOKUPS 100
773 static void copy_pwent(struct saved_pw *dst, struct passwd *pass)
775 memcpy((char *)&dst->pass, pass, sizeof(struct passwd));
777 fstrcpy(dst->pw_name, pass->pw_name);
778 dst->pass.pw_name = dst->pw_name;
780 fstrcpy(dst->pw_passwd, pass->pw_passwd);
781 dst->pass.pw_passwd = dst->pw_passwd;
783 fstrcpy(dst->pw_gecos, pass->pw_gecos);
784 dst->pass.pw_gecos = dst->pw_gecos;
786 pstrcpy(dst->pw_dir, pass->pw_dir);
787 dst->pass.pw_dir = dst->pw_dir;
789 pstrcpy(dst->pw_shell, pass->pw_shell);
790 dst->pass.pw_shell = dst->pw_shell;
793 static struct passwd *setup_pwret(struct passwd *pass)
796 /* Clear the caches. */
797 memset(&pw_cache, '\0', sizeof(struct saved_pw));
798 memset(&pw_mod, '\0', sizeof(struct saved_pw));
803 copy_pwent( &pw_mod, pass);
805 if (pass != &pw_cache.pass) {
807 /* If it's a cache miss we must also refill the cache. */
809 copy_pwent( &pw_cache, pass);
817 num_lookups = (num_lookups % PW_RET_CACHE_MAX_LOOKUPS);
823 /**************************************************************************
824 Wrappers for setpwent(), getpwent() and endpwent()
825 ****************************************************************************/
827 void sys_setpwent(void)
829 setup_pwret(NULL); /* Clear cache. */
833 struct passwd *sys_getpwent(void)
835 return setup_pwret(getpwent());
838 void sys_endpwent(void)
840 setup_pwret(NULL); /* Clear cache. */
844 /**************************************************************************
845 Wrapper for getpwnam(). Always returns a static that can be modified.
846 ****************************************************************************/
848 struct passwd *sys_getpwnam(const char *name)
850 if (!name || !name[0])
853 /* check for a cache hit first */
854 if (num_lookups && pw_cache.pass.pw_name && !strcmp(name, pw_cache.pass.pw_name)) {
855 return setup_pwret(&pw_cache.pass);
858 return setup_pwret(getpwnam(name));
861 /**************************************************************************
862 Wrapper for getpwuid(). Always returns a static that can be modified.
863 ****************************************************************************/
865 struct passwd *sys_getpwuid(uid_t uid)
867 if (num_lookups && pw_cache.pass.pw_name && (uid == pw_cache.pass.pw_uid)) {
868 return setup_pwret(&pw_cache.pass);
871 return setup_pwret(getpwuid(uid));
874 #if 0 /* NOT CURRENTLY USED - JRA */
875 /**************************************************************************
876 The following are the UNICODE versions of *all* system interface functions
877 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
878 which currently are left as ascii as they are not used other than in name
880 ****************************************************************************/
882 /**************************************************************************
883 Wide stat. Just narrow and call sys_xxx.
884 ****************************************************************************/
886 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
889 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
892 /**************************************************************************
893 Wide lstat. Just narrow and call sys_xxx.
894 ****************************************************************************/
896 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
899 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
902 /**************************************************************************
903 Wide creat. Just narrow and call sys_xxx.
904 ****************************************************************************/
906 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
909 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
912 /**************************************************************************
913 Wide open. Just narrow and call sys_xxx.
914 ****************************************************************************/
916 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
919 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
922 /**************************************************************************
923 Wide fopen. Just narrow and call sys_xxx.
924 ****************************************************************************/
926 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
929 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
932 /**************************************************************************
933 Wide opendir. Just narrow and call sys_xxx.
934 ****************************************************************************/
936 DIR *wsys_opendir(const smb_ucs2_t *wfname)
939 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
942 /**************************************************************************
943 Wide readdir. Return a structure pointer containing a wide filename.
944 ****************************************************************************/
946 SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
948 static SMB_STRUCT_WDIRENT retval;
949 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
955 * The only POSIX defined member of this struct is d_name.
958 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
963 /**************************************************************************
964 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
965 ****************************************************************************/
967 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
970 char *p = sys_getwd(fname);
975 return unix_to_unicode(s, p, sizeof(wpstring));
978 /**************************************************************************
979 Wide chown. Just narrow and call sys_xxx.
980 ****************************************************************************/
982 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
985 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
988 /**************************************************************************
989 Wide chroot. Just narrow and call sys_xxx.
990 ****************************************************************************/
992 int wsys_chroot(const smb_ucs2_t *wfname)
995 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
998 /**************************************************************************
999 Wide getpwnam. Return a structure pointer containing wide names.
1000 ****************************************************************************/
1002 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1004 static SMB_STRUCT_WPASSWD retval;
1006 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1011 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1012 retval.pw_passwd = pwret->pw_passwd;
1013 retval.pw_uid = pwret->pw_uid;
1014 retval.pw_gid = pwret->pw_gid;
1015 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1016 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1017 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1022 /**************************************************************************
1023 Wide getpwuid. Return a structure pointer containing wide names.
1024 ****************************************************************************/
1026 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1028 static SMB_STRUCT_WPASSWD retval;
1029 struct passwd *pwret = sys_getpwuid(uid);
1034 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1035 retval.pw_passwd = pwret->pw_passwd;
1036 retval.pw_uid = pwret->pw_uid;
1037 retval.pw_gid = pwret->pw_gid;
1038 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1039 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1040 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1044 #endif /* NOT CURRENTLY USED - JRA */
1046 /**************************************************************************
1047 Extract a command into an arg list. Uses a static pstring for storage.
1048 Caller frees returned arg list (which contains pointers into the static pstring).
1049 ****************************************************************************/
1051 static char **extract_args(const char *command)
1053 static pstring trunc_cmd;
1059 pstrcpy(trunc_cmd, command);
1061 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1070 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1073 if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL)
1077 * Now do the extraction.
1080 pstrcpy(trunc_cmd, command);
1082 ptr = strtok(trunc_cmd, " \t");
1086 while((ptr = strtok(NULL, " \t")) != NULL)
1093 /**************************************************************************
1094 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1095 a sys_getpid() that only does a system call *once*.
1096 ****************************************************************************/
1098 static pid_t mypid = (pid_t)-1;
1100 pid_t sys_fork(void)
1102 pid_t forkret = fork();
1104 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1110 /**************************************************************************
1111 Wrapper for getpid. Ensures we only do a system call *once*.
1112 ****************************************************************************/
1114 pid_t sys_getpid(void)
1116 if (mypid == (pid_t)-1)
1122 /**************************************************************************
1123 Wrapper for popen. Safer as it doesn't search a path.
1124 Modified from the glibc sources.
1125 modified by tridge to return a file descriptor. We must kick our FILE* habit
1126 ****************************************************************************/
1128 typedef struct _popen_list
1132 struct _popen_list *next;
1135 static popen_list *popen_chain;
1137 int sys_popen(const char *command)
1139 int parent_end, child_end;
1141 popen_list *entry = NULL;
1144 if (pipe(pipe_fds) < 0)
1147 parent_end = pipe_fds[0];
1148 child_end = pipe_fds[1];
1155 if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL)
1158 ZERO_STRUCTP(entry);
1161 * Extract the command and args into a NULL terminated array.
1164 if(!(argl = extract_args(command)))
1167 entry->child_pid = sys_fork();
1169 if (entry->child_pid == -1) {
1173 if (entry->child_pid == 0) {
1179 int child_std_end = STDOUT_FILENO;
1183 if (child_end != child_std_end) {
1184 dup2 (child_end, child_std_end);
1189 * POSIX.2: "popen() shall ensure that any streams from previous
1190 * popen() calls that remain open in the parent process are closed
1191 * in the new child process."
1194 for (p = popen_chain; p; p = p->next)
1197 execv(argl[0], argl);
1208 /* Link into popen_chain. */
1209 entry->next = popen_chain;
1210 popen_chain = entry;
1211 entry->fd = parent_end;
1224 /**************************************************************************
1225 Wrapper for pclose. Modified from the glibc sources.
1226 ****************************************************************************/
1228 int sys_pclose(int fd)
1231 popen_list **ptr = &popen_chain;
1232 popen_list *entry = NULL;
1236 /* Unlink from popen_chain. */
1237 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1238 if ((*ptr)->fd == fd) {
1240 *ptr = (*ptr)->next;
1246 if (status < 0 || close(entry->fd) < 0)
1250 * As Samba is catching and eating child process
1251 * exits we don't really care about the child exit
1252 * code, a -1 with errno = ECHILD will do fine for us.
1256 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1257 } while (wait_pid == -1 && errno == EINTR);
1266 /**************************************************************************
1267 Wrappers for dlopen, dlsym, dlclose.
1268 ****************************************************************************/
1270 void *sys_dlopen(const char *name, int flags)
1272 #if defined(HAVE_DLOPEN)
1273 return dlopen(name, flags);
1279 void *sys_dlsym(void *handle, char *symbol)
1281 #if defined(HAVE_DLSYM)
1282 return dlsym(handle, symbol);
1288 int sys_dlclose (void *handle)
1290 #if defined(HAVE_DLCLOSE)
1291 return dlclose(handle);
1297 const char *sys_dlerror(void)
1299 #if defined(HAVE_DLERROR)
1306 /**************************************************************************
1307 Wrapper for Admin Logs.
1308 ****************************************************************************/
1310 void sys_adminlog(int priority, const char *format_str, ...)
1314 char **msgbuf = NULL;
1316 if (!lp_admin_log())
1319 va_start( ap, format_str );
1320 ret = vasprintf( msgbuf, format_str, ap );
1326 #if defined(HAVE_SYSLOG)
1327 syslog( priority, "%s", *msgbuf );
1329 DEBUG(0,("%s", *msgbuf ));