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)
85 ret = read(fd, buf, count);
86 } while (ret == -1 && errno == EINTR);
90 /*******************************************************************
91 A write wrapper that will deal with EINTR.
92 ********************************************************************/
94 ssize_t sys_write(int fd, const void *buf, size_t count)
100 ret = write(fd, buf, count);
101 } while (ret == -1 && errno == EINTR);
105 /*******************************************************************
106 A send wrapper that will deal with EINTR.
107 ********************************************************************/
109 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
115 ret = send(s, msg, len, flags);
116 } while (ret == -1 && errno == EINTR);
120 /*******************************************************************
121 A sendto wrapper that will deal with EINTR.
122 ********************************************************************/
124 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
130 ret = sendto(s, msg, len, flags, to, tolen);
131 } while (ret == -1 && errno == EINTR);
135 /*******************************************************************
136 A recvfrom wrapper that will deal with EINTR.
137 ********************************************************************/
139 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
145 ret = recvfrom(s, buf, len, flags, from, fromlen);
146 } while (ret == -1 && errno == EINTR);
150 /*******************************************************************
151 A fcntl wrapper that will deal with EINTR.
152 ********************************************************************/
154 int sys_fcntl_ptr(int fd, int cmd, void *arg)
160 ret = fcntl(fd, cmd, arg);
161 } while (ret == -1 && errno == EINTR);
165 /*******************************************************************
166 A fcntl wrapper that will deal with EINTR.
167 ********************************************************************/
169 int sys_fcntl_long(int fd, int cmd, long arg)
175 ret = fcntl(fd, cmd, arg);
176 } while (ret == -1 && errno == EINTR);
180 /*******************************************************************
181 A stat() wrapper that will deal with 64 bit filesizes.
182 ********************************************************************/
184 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
187 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
188 ret = stat64(fname, sbuf);
190 ret = stat(fname, sbuf);
192 /* we always want directories to appear zero size */
193 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
197 /*******************************************************************
198 An fstat() wrapper that will deal with 64 bit filesizes.
199 ********************************************************************/
201 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
204 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
205 ret = fstat64(fd, sbuf);
207 ret = fstat(fd, sbuf);
209 /* we always want directories to appear zero size */
210 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
214 /*******************************************************************
215 An lstat() wrapper that will deal with 64 bit filesizes.
216 ********************************************************************/
218 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
221 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
222 ret = lstat64(fname, sbuf);
224 ret = lstat(fname, sbuf);
226 /* we always want directories to appear zero size */
227 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
231 /*******************************************************************
232 An ftruncate() wrapper that will deal with 64 bit filesizes.
233 ********************************************************************/
235 int sys_ftruncate(int fd, SMB_OFF_T offset)
237 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
238 return ftruncate64(fd, offset);
240 return ftruncate(fd, offset);
244 /*******************************************************************
245 An lseek() wrapper that will deal with 64 bit filesizes.
246 ********************************************************************/
248 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
250 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
251 return lseek64(fd, offset, whence);
253 return lseek(fd, offset, whence);
257 /*******************************************************************
258 An fseek() wrapper that will deal with 64 bit filesizes.
259 ********************************************************************/
261 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
263 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
264 return fseek64(fp, offset, whence);
265 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
266 return fseeko64(fp, offset, whence);
268 return fseek(fp, offset, whence);
272 /*******************************************************************
273 An ftell() wrapper that will deal with 64 bit filesizes.
274 ********************************************************************/
276 SMB_OFF_T sys_ftell(FILE *fp)
278 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
279 return (SMB_OFF_T)ftell64(fp);
280 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
281 return (SMB_OFF_T)ftello64(fp);
283 return (SMB_OFF_T)ftell(fp);
287 /*******************************************************************
288 A creat() wrapper that will deal with 64 bit filesizes.
289 ********************************************************************/
291 int sys_creat(const char *path, mode_t mode)
293 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
294 return creat64(path, mode);
297 * If creat64 isn't defined then ensure we call a potential open64.
300 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
304 /*******************************************************************
305 An open() wrapper that will deal with 64 bit filesizes.
306 ********************************************************************/
308 int sys_open(const char *path, int oflag, mode_t mode)
310 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
311 return open64(path, oflag, mode);
313 return open(path, oflag, mode);
317 /*******************************************************************
318 An fopen() wrapper that will deal with 64 bit filesizes.
319 ********************************************************************/
321 FILE *sys_fopen(const char *path, const char *type)
323 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
324 return fopen64(path, type);
326 return fopen(path, type);
330 /*******************************************************************
331 A readdir wrapper that will deal with 64 bit filesizes.
332 ********************************************************************/
334 SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
336 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
337 return readdir64(dirp);
339 return readdir(dirp);
343 /*******************************************************************
344 An mknod() wrapper that will deal with 64 bit filesizes.
345 ********************************************************************/
347 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
349 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
350 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
351 return mknod64(path, mode, dev);
353 return mknod(path, mode, dev);
356 /* No mknod system call. */
362 /*******************************************************************
363 Wrapper for realpath.
364 ********************************************************************/
366 char *sys_realpath(const char *path, char *resolved_path)
368 #if defined(HAVE_REALPATH)
369 return realpath(path, resolved_path);
371 /* As realpath is not a system call we can't return ENOSYS. */
377 /*******************************************************************
378 The wait() calls vary between systems
379 ********************************************************************/
381 int sys_waitpid(pid_t pid,int *status,int options)
384 return waitpid(pid,status,options);
385 #else /* HAVE_WAITPID */
386 return wait4(pid, status, options, NULL);
387 #endif /* HAVE_WAITPID */
390 /*******************************************************************
391 System wrapper for getwd
392 ********************************************************************/
394 char *sys_getwd(char *s)
398 wd = (char *)getcwd(s, sizeof (pstring));
400 wd = (char *)getwd(s);
405 /*******************************************************************
406 system wrapper for symlink
407 ********************************************************************/
409 int sys_symlink(const char *oldpath, const char *newpath)
415 return symlink(oldpath, newpath);
419 /*******************************************************************
420 system wrapper for readlink
421 ********************************************************************/
423 int sys_readlink(const char *path, char *buf, size_t bufsiz)
425 #ifndef HAVE_READLINK
429 return readlink(path, buf, bufsiz);
433 /*******************************************************************
434 system wrapper for link
435 ********************************************************************/
437 int sys_link(const char *oldpath, const char *newpath)
443 return link(oldpath, newpath);
447 /*******************************************************************
448 chown isn't used much but OS/2 doesn't have it
449 ********************************************************************/
451 int sys_chown(const char *fname,uid_t uid,gid_t gid)
456 DEBUG(1,("WARNING: no chown!\n"));
460 return(chown(fname,uid,gid));
464 /*******************************************************************
465 os/2 also doesn't have chroot
466 ********************************************************************/
467 int sys_chroot(const char *dname)
472 DEBUG(1,("WARNING: no chroot!\n"));
478 return(chroot(dname));
482 /**************************************************************************
483 A wrapper for gethostbyname() that tries avoids looking up hostnames
484 in the root domain, which can cause dial-on-demand links to come up for no
486 ****************************************************************************/
488 struct hostent *sys_gethostbyname(const char *name)
490 #ifdef REDUCE_ROOT_DNS_LOOKUPS
491 char query[256], hostname[256];
494 /* Does this name have any dots in it? If so, make no change */
496 if (strchr_m(name, '.'))
497 return(gethostbyname(name));
499 /* Get my hostname, which should have domain name
500 attached. If not, just do the gethostname on the
504 gethostname(hostname, sizeof(hostname) - 1);
505 hostname[sizeof(hostname) - 1] = 0;
506 if ((domain = strchr_m(hostname, '.')) == NULL)
507 return(gethostbyname(name));
509 /* Attach domain name to query and do modified query.
510 If names too large, just do gethostname on the
514 if((strlen(name) + strlen(domain)) >= sizeof(query))
515 return(gethostbyname(name));
517 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
518 return(gethostbyname(query));
519 #else /* REDUCE_ROOT_DNS_LOOKUPS */
520 return(gethostbyname(name));
521 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
525 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
526 /**************************************************************************
527 Try and abstract process capabilities (for systems that have them).
528 ****************************************************************************/
529 static BOOL set_process_capability( uint32 cap_flag, BOOL enable )
531 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
532 cap_t cap = cap_get_proc();
535 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
541 cap->cap_effective |= CAP_NETWORK_MGT;
543 cap->cap_effective &= ~CAP_NETWORK_MGT;
545 if (cap_set_proc(cap) == -1) {
546 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
554 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
559 /**************************************************************************
560 Try and abstract inherited process capabilities (for systems that have them).
561 ****************************************************************************/
563 static BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
565 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
566 cap_t cap = cap_get_proc();
569 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
575 cap->cap_inheritable |= CAP_NETWORK_MGT;
577 cap->cap_inheritable &= ~CAP_NETWORK_MGT;
579 if (cap_set_proc(cap) == -1) {
580 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
588 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
594 /****************************************************************************
595 Gain the oplock capability from the kernel if possible.
596 ****************************************************************************/
598 void oplock_set_capability(BOOL this_process, BOOL inherit)
600 #if HAVE_KERNEL_OPLOCKS_IRIX
601 set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process);
602 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit);
606 /**************************************************************************
607 Wrapper for random().
608 ****************************************************************************/
610 long sys_random(void)
612 #if defined(HAVE_RANDOM)
613 return (long)random();
614 #elif defined(HAVE_RAND)
617 DEBUG(0,("Error - no random function available !\n"));
622 /**************************************************************************
623 Wrapper for srandom().
624 ****************************************************************************/
626 void sys_srandom(unsigned int seed)
628 #if defined(HAVE_SRANDOM)
630 #elif defined(HAVE_SRAND)
633 DEBUG(0,("Error - no srandom function available !\n"));
638 /**************************************************************************
639 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
640 ****************************************************************************/
644 #if defined(SYSCONF_SC_NGROUPS_MAX)
645 int ret = sysconf(_SC_NGROUPS_MAX);
646 return (ret == -1) ? NGROUPS_MAX : ret;
652 /**************************************************************************
653 Wrapper for getgroups. Deals with broken (int) case.
654 ****************************************************************************/
656 int sys_getgroups(int setlen, gid_t *gidset)
658 #if !defined(HAVE_BROKEN_GETGROUPS)
659 return getgroups(setlen, gidset);
667 return getgroups(setlen, &gid);
671 * Broken case. We need to allocate a
672 * GID_T array of size setlen.
681 setlen = groups_max();
683 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
684 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
688 if((ngroups = getgroups(setlen, group_list)) < 0) {
689 int saved_errno = errno;
690 SAFE_FREE(group_list);
695 for(i = 0; i < ngroups; i++)
696 gidset[i] = (gid_t)group_list[i];
698 SAFE_FREE(group_list);
700 #endif /* HAVE_BROKEN_GETGROUPS */
703 #ifdef HAVE_SETGROUPS
705 /**************************************************************************
706 Wrapper for setgroups. Deals with broken (int) case. Automatically used
707 if we have broken getgroups.
708 ****************************************************************************/
710 int sys_setgroups(int setlen, gid_t *gidset)
712 #if !defined(HAVE_BROKEN_GETGROUPS)
713 return setgroups(setlen, gidset);
722 if (setlen < 0 || setlen > groups_max()) {
728 * Broken case. We need to allocate a
729 * GID_T array of size setlen.
732 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
733 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
737 for(i = 0; i < setlen; i++)
738 group_list[i] = (GID_T) gidset[i];
740 if(setgroups(setlen, group_list) != 0) {
741 int saved_errno = errno;
742 SAFE_FREE(group_list);
747 SAFE_FREE(group_list);
749 #endif /* HAVE_BROKEN_GETGROUPS */
752 #endif /* HAVE_SETGROUPS */
755 * We only wrap pw_name and pw_passwd for now as these
756 * are the only potentially modified fields.
759 /**************************************************************************
760 Helper function for getpwnam/getpwuid wrappers.
761 ****************************************************************************/
772 static struct saved_pw pw_mod; /* This is the structure returned - can be modified. */
773 static struct saved_pw pw_cache; /* This is the structure saved - used to check cache. */
775 static int num_lookups; /* Counter so we don't always use cache. */
776 #ifndef PW_RET_CACHE_MAX_LOOKUPS
777 #define PW_RET_CACHE_MAX_LOOKUPS 100
780 static void copy_pwent(struct saved_pw *dst, struct passwd *pass)
782 memcpy((char *)&dst->pass, pass, sizeof(struct passwd));
784 fstrcpy(dst->pw_name, pass->pw_name);
785 dst->pass.pw_name = dst->pw_name;
787 fstrcpy(dst->pw_passwd, pass->pw_passwd);
788 dst->pass.pw_passwd = dst->pw_passwd;
790 fstrcpy(dst->pw_gecos, pass->pw_gecos);
791 dst->pass.pw_gecos = dst->pw_gecos;
793 pstrcpy(dst->pw_dir, pass->pw_dir);
794 dst->pass.pw_dir = dst->pw_dir;
796 pstrcpy(dst->pw_shell, pass->pw_shell);
797 dst->pass.pw_shell = dst->pw_shell;
800 static struct passwd *setup_pwret(struct passwd *pass)
803 /* Clear the caches. */
804 memset(&pw_cache, '\0', sizeof(struct saved_pw));
805 memset(&pw_mod, '\0', sizeof(struct saved_pw));
810 copy_pwent( &pw_mod, pass);
812 if (pass != &pw_cache.pass) {
814 /* If it's a cache miss we must also refill the cache. */
816 copy_pwent( &pw_cache, pass);
824 num_lookups = (num_lookups % PW_RET_CACHE_MAX_LOOKUPS);
830 /**************************************************************************
831 Wrappers for setpwent(), getpwent() and endpwent()
832 ****************************************************************************/
834 void sys_setpwent(void)
836 setup_pwret(NULL); /* Clear cache. */
840 struct passwd *sys_getpwent(void)
842 return setup_pwret(getpwent());
845 void sys_endpwent(void)
847 setup_pwret(NULL); /* Clear cache. */
851 /**************************************************************************
852 Wrapper for getpwnam(). Always returns a static that can be modified.
853 ****************************************************************************/
855 struct passwd *sys_getpwnam(const char *name)
857 if (!name || !name[0])
860 /* check for a cache hit first */
861 if (num_lookups && pw_cache.pass.pw_name && !strcmp(name, pw_cache.pass.pw_name)) {
862 return setup_pwret(&pw_cache.pass);
865 return setup_pwret(getpwnam(name));
868 /**************************************************************************
869 Wrapper for getpwuid(). Always returns a static that can be modified.
870 ****************************************************************************/
872 struct passwd *sys_getpwuid(uid_t uid)
874 if (num_lookups && pw_cache.pass.pw_name && (uid == pw_cache.pass.pw_uid)) {
875 return setup_pwret(&pw_cache.pass);
878 return setup_pwret(getpwuid(uid));
881 #if 0 /* NOT CURRENTLY USED - JRA */
882 /**************************************************************************
883 The following are the UNICODE versions of *all* system interface functions
884 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
885 which currently are left as ascii as they are not used other than in name
887 ****************************************************************************/
889 /**************************************************************************
890 Wide stat. Just narrow and call sys_xxx.
891 ****************************************************************************/
893 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
896 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
899 /**************************************************************************
900 Wide lstat. Just narrow and call sys_xxx.
901 ****************************************************************************/
903 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
906 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
909 /**************************************************************************
910 Wide creat. Just narrow and call sys_xxx.
911 ****************************************************************************/
913 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
916 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
919 /**************************************************************************
920 Wide open. Just narrow and call sys_xxx.
921 ****************************************************************************/
923 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
926 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
929 /**************************************************************************
930 Wide fopen. Just narrow and call sys_xxx.
931 ****************************************************************************/
933 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
936 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
939 /**************************************************************************
940 Wide opendir. Just narrow and call sys_xxx.
941 ****************************************************************************/
943 DIR *wsys_opendir(const smb_ucs2_t *wfname)
946 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
949 /**************************************************************************
950 Wide readdir. Return a structure pointer containing a wide filename.
951 ****************************************************************************/
953 SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
955 static SMB_STRUCT_WDIRENT retval;
956 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
962 * The only POSIX defined member of this struct is d_name.
965 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
970 /**************************************************************************
971 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
972 ****************************************************************************/
974 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
977 char *p = sys_getwd(fname);
982 return unix_to_unicode(s, p, sizeof(wpstring));
985 /**************************************************************************
986 Wide chown. Just narrow and call sys_xxx.
987 ****************************************************************************/
989 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
992 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
995 /**************************************************************************
996 Wide chroot. Just narrow and call sys_xxx.
997 ****************************************************************************/
999 int wsys_chroot(const smb_ucs2_t *wfname)
1002 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
1005 /**************************************************************************
1006 Wide getpwnam. Return a structure pointer containing wide names.
1007 ****************************************************************************/
1009 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
1011 static SMB_STRUCT_WPASSWD retval;
1013 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
1018 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1019 retval.pw_passwd = pwret->pw_passwd;
1020 retval.pw_uid = pwret->pw_uid;
1021 retval.pw_gid = pwret->pw_gid;
1022 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1023 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1024 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1029 /**************************************************************************
1030 Wide getpwuid. Return a structure pointer containing wide names.
1031 ****************************************************************************/
1033 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1035 static SMB_STRUCT_WPASSWD retval;
1036 struct passwd *pwret = sys_getpwuid(uid);
1041 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
1042 retval.pw_passwd = pwret->pw_passwd;
1043 retval.pw_uid = pwret->pw_uid;
1044 retval.pw_gid = pwret->pw_gid;
1045 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1046 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1047 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1051 #endif /* NOT CURRENTLY USED - JRA */
1053 /**************************************************************************
1054 Extract a command into an arg list. Uses a static pstring for storage.
1055 Caller frees returned arg list (which contains pointers into the static pstring).
1056 ****************************************************************************/
1058 static char **extract_args(const char *command)
1060 static pstring trunc_cmd;
1066 pstrcpy(trunc_cmd, command);
1068 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1077 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1080 if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL)
1084 * Now do the extraction.
1087 pstrcpy(trunc_cmd, command);
1089 ptr = strtok(trunc_cmd, " \t");
1093 while((ptr = strtok(NULL, " \t")) != NULL)
1100 /**************************************************************************
1101 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1102 a sys_getpid() that only does a system call *once*.
1103 ****************************************************************************/
1105 static pid_t mypid = (pid_t)-1;
1107 pid_t sys_fork(void)
1109 pid_t forkret = fork();
1111 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1117 /**************************************************************************
1118 Wrapper for getpid. Ensures we only do a system call *once*.
1119 ****************************************************************************/
1121 pid_t sys_getpid(void)
1123 if (mypid == (pid_t)-1)
1129 /**************************************************************************
1130 Wrapper for popen. Safer as it doesn't search a path.
1131 Modified from the glibc sources.
1132 modified by tridge to return a file descriptor. We must kick our FILE* habit
1133 ****************************************************************************/
1135 typedef struct _popen_list
1139 struct _popen_list *next;
1142 static popen_list *popen_chain;
1144 int sys_popen(const char *command)
1146 int parent_end, child_end;
1148 popen_list *entry = NULL;
1151 if (pipe(pipe_fds) < 0)
1154 parent_end = pipe_fds[0];
1155 child_end = pipe_fds[1];
1162 if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL)
1165 ZERO_STRUCTP(entry);
1168 * Extract the command and args into a NULL terminated array.
1171 if(!(argl = extract_args(command)))
1174 entry->child_pid = sys_fork();
1176 if (entry->child_pid == -1) {
1180 if (entry->child_pid == 0) {
1186 int child_std_end = STDOUT_FILENO;
1190 if (child_end != child_std_end) {
1191 dup2 (child_end, child_std_end);
1196 * POSIX.2: "popen() shall ensure that any streams from previous
1197 * popen() calls that remain open in the parent process are closed
1198 * in the new child process."
1201 for (p = popen_chain; p; p = p->next)
1204 execv(argl[0], argl);
1215 /* Link into popen_chain. */
1216 entry->next = popen_chain;
1217 popen_chain = entry;
1218 entry->fd = parent_end;
1231 /**************************************************************************
1232 Wrapper for pclose. Modified from the glibc sources.
1233 ****************************************************************************/
1235 int sys_pclose(int fd)
1238 popen_list **ptr = &popen_chain;
1239 popen_list *entry = NULL;
1243 /* Unlink from popen_chain. */
1244 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1245 if ((*ptr)->fd == fd) {
1247 *ptr = (*ptr)->next;
1253 if (status < 0 || close(entry->fd) < 0)
1257 * As Samba is catching and eating child process
1258 * exits we don't really care about the child exit
1259 * code, a -1 with errno = ECHILD will do fine for us.
1263 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1264 } while (wait_pid == -1 && errno == EINTR);
1273 /**************************************************************************
1274 Wrappers for dlopen, dlsym, dlclose.
1275 ****************************************************************************/
1277 void *sys_dlopen(const char *name, int flags)
1279 #if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN)
1280 return dlopen(name, flags);
1286 void *sys_dlsym(void *handle, char *symbol)
1288 #if defined(HAVE_LIBDL) || defined(HAVE_DLSYM)
1289 return dlsym(handle, symbol);
1295 int sys_dlclose (void *handle)
1297 #if defined(HAVE_LIBDL) || defined(HAVE_DLCLOSE)
1298 return dlclose(handle);
1304 const char *sys_dlerror(void)
1306 #if defined(HAVE_LIBDL) || defined(HAVE_DLERROR)
1313 /**************************************************************************
1314 Wrapper for Admin Logs.
1315 ****************************************************************************/
1317 void sys_adminlog(int priority, const char *format_str, ...)
1321 char **msgbuf = NULL;
1323 if (!lp_admin_log())
1326 va_start( ap, format_str );
1327 ret = vasprintf( msgbuf, format_str, ap );
1333 #if defined(HAVE_SYSLOG)
1334 syslog( priority, "%s", *msgbuf );
1336 DEBUG(0,("%s", *msgbuf ));