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 stat() wrapper that will deal with 64 bit filesizes.
152 ********************************************************************/
154 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
157 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
158 ret = stat64(fname, sbuf);
160 ret = stat(fname, sbuf);
162 /* we always want directories to appear zero size */
163 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
167 /*******************************************************************
168 An fstat() wrapper that will deal with 64 bit filesizes.
169 ********************************************************************/
171 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
174 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
175 ret = fstat64(fd, sbuf);
177 ret = fstat(fd, sbuf);
179 /* we always want directories to appear zero size */
180 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
184 /*******************************************************************
185 An lstat() wrapper that will deal with 64 bit filesizes.
186 ********************************************************************/
188 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
191 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
192 ret = lstat64(fname, sbuf);
194 ret = lstat(fname, sbuf);
196 /* we always want directories to appear zero size */
197 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
201 /*******************************************************************
202 An ftruncate() wrapper that will deal with 64 bit filesizes.
203 ********************************************************************/
205 int sys_ftruncate(int fd, SMB_OFF_T offset)
207 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
208 return ftruncate64(fd, offset);
210 return ftruncate(fd, offset);
214 /*******************************************************************
215 An lseek() wrapper that will deal with 64 bit filesizes.
216 ********************************************************************/
218 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
220 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
221 return lseek64(fd, offset, whence);
223 return lseek(fd, offset, whence);
227 /*******************************************************************
228 An fseek() wrapper that will deal with 64 bit filesizes.
229 ********************************************************************/
231 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
233 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
234 return fseek64(fp, offset, whence);
235 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
236 return fseeko64(fp, offset, whence);
238 return fseek(fp, offset, whence);
242 /*******************************************************************
243 An ftell() wrapper that will deal with 64 bit filesizes.
244 ********************************************************************/
246 SMB_OFF_T sys_ftell(FILE *fp)
248 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
249 return (SMB_OFF_T)ftell64(fp);
250 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
251 return (SMB_OFF_T)ftello64(fp);
253 return (SMB_OFF_T)ftell(fp);
257 /*******************************************************************
258 A creat() wrapper that will deal with 64 bit filesizes.
259 ********************************************************************/
261 int sys_creat(const char *path, mode_t mode)
263 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
264 return creat64(path, mode);
267 * If creat64 isn't defined then ensure we call a potential open64.
270 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
274 /*******************************************************************
275 An open() wrapper that will deal with 64 bit filesizes.
276 ********************************************************************/
278 int sys_open(const char *path, int oflag, mode_t mode)
280 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
281 return open64(path, oflag, mode);
283 return open(path, oflag, mode);
287 /*******************************************************************
288 An fopen() wrapper that will deal with 64 bit filesizes.
289 ********************************************************************/
291 FILE *sys_fopen(const char *path, const char *type)
293 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
294 return fopen64(path, type);
296 return fopen(path, type);
300 /*******************************************************************
301 A readdir wrapper that will deal with 64 bit filesizes.
302 ********************************************************************/
304 SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
306 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
307 return readdir64(dirp);
309 return readdir(dirp);
313 /*******************************************************************
314 An mknod() wrapper that will deal with 64 bit filesizes.
315 ********************************************************************/
317 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
319 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
320 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
321 return mknod64(path, mode, dev);
323 return mknod(path, mode, dev);
326 /* No mknod system call. */
332 /*******************************************************************
333 Wrapper for realpath.
334 ********************************************************************/
336 char *sys_realpath(const char *path, char *resolved_path)
338 #if defined(HAVE_REALPATH)
339 return realpath(path, resolved_path);
341 /* As realpath is not a system call we can't return ENOSYS. */
347 /*******************************************************************
348 The wait() calls vary between systems
349 ********************************************************************/
351 int sys_waitpid(pid_t pid,int *status,int options)
354 return waitpid(pid,status,options);
355 #else /* HAVE_WAITPID */
356 return wait4(pid, status, options, NULL);
357 #endif /* HAVE_WAITPID */
360 /*******************************************************************
361 System wrapper for getwd
362 ********************************************************************/
364 char *sys_getwd(char *s)
368 wd = (char *)getcwd(s, sizeof (pstring));
370 wd = (char *)getwd(s);
375 /*******************************************************************
376 system wrapper for symlink
377 ********************************************************************/
379 int sys_symlink(const char *oldpath, const char *newpath)
385 return symlink(oldpath, newpath);
389 /*******************************************************************
390 system wrapper for readlink
391 ********************************************************************/
393 int sys_readlink(const char *path, char *buf, size_t bufsiz)
395 #ifndef HAVE_READLINK
399 return readlink(path, buf, bufsiz);
403 /*******************************************************************
404 system wrapper for link
405 ********************************************************************/
407 int sys_link(const char *oldpath, const char *newpath)
413 return link(oldpath, newpath);
417 /*******************************************************************
418 chown isn't used much but OS/2 doesn't have it
419 ********************************************************************/
421 int sys_chown(const char *fname,uid_t uid,gid_t gid)
426 DEBUG(1,("WARNING: no chown!\n"));
430 return(chown(fname,uid,gid));
434 /*******************************************************************
435 os/2 also doesn't have chroot
436 ********************************************************************/
437 int sys_chroot(const char *dname)
442 DEBUG(1,("WARNING: no chroot!\n"));
448 return(chroot(dname));
452 /**************************************************************************
453 A wrapper for gethostbyname() that tries avoids looking up hostnames
454 in the root domain, which can cause dial-on-demand links to come up for no
456 ****************************************************************************/
458 struct hostent *sys_gethostbyname(const char *name)
460 #ifdef REDUCE_ROOT_DNS_LOOKUPS
461 char query[256], hostname[256];
464 /* Does this name have any dots in it? If so, make no change */
466 if (strchr_m(name, '.'))
467 return(gethostbyname(name));
469 /* Get my hostname, which should have domain name
470 attached. If not, just do the gethostname on the
474 gethostname(hostname, sizeof(hostname) - 1);
475 hostname[sizeof(hostname) - 1] = 0;
476 if ((domain = strchr_m(hostname, '.')) == NULL)
477 return(gethostbyname(name));
479 /* Attach domain name to query and do modified query.
480 If names too large, just do gethostname on the
484 if((strlen(name) + strlen(domain)) >= sizeof(query))
485 return(gethostbyname(name));
487 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
488 return(gethostbyname(query));
489 #else /* REDUCE_ROOT_DNS_LOOKUPS */
490 return(gethostbyname(name));
491 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
495 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
496 /**************************************************************************
497 Try and abstract process capabilities (for systems that have them).
498 ****************************************************************************/
499 static BOOL set_process_capability( uint32 cap_flag, BOOL enable )
501 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
502 cap_t cap = cap_get_proc();
505 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
511 cap->cap_effective |= CAP_NETWORK_MGT;
513 cap->cap_effective &= ~CAP_NETWORK_MGT;
515 if (cap_set_proc(cap) == -1) {
516 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
524 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
529 /**************************************************************************
530 Try and abstract inherited process capabilities (for systems that have them).
531 ****************************************************************************/
533 static BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
535 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
536 cap_t cap = cap_get_proc();
539 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
545 cap->cap_inheritable |= CAP_NETWORK_MGT;
547 cap->cap_inheritable &= ~CAP_NETWORK_MGT;
549 if (cap_set_proc(cap) == -1) {
550 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
558 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
564 /****************************************************************************
565 Gain the oplock capability from the kernel if possible.
566 ****************************************************************************/
568 void oplock_set_capability(BOOL this_process, BOOL inherit)
570 #if HAVE_KERNEL_OPLOCKS_IRIX
571 set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process);
572 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit);
576 /**************************************************************************
577 Wrapper for random().
578 ****************************************************************************/
580 long sys_random(void)
582 #if defined(HAVE_RANDOM)
583 return (long)random();
584 #elif defined(HAVE_RAND)
587 DEBUG(0,("Error - no random function available !\n"));
592 /**************************************************************************
593 Wrapper for srandom().
594 ****************************************************************************/
596 void sys_srandom(unsigned int seed)
598 #if defined(HAVE_SRANDOM)
600 #elif defined(HAVE_SRAND)
603 DEBUG(0,("Error - no srandom function available !\n"));
608 /**************************************************************************
609 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
610 ****************************************************************************/
614 #if defined(SYSCONF_SC_NGROUPS_MAX)
615 int ret = sysconf(_SC_NGROUPS_MAX);
616 return (ret == -1) ? NGROUPS_MAX : ret;
622 /**************************************************************************
623 Wrapper for getgroups. Deals with broken (int) case.
624 ****************************************************************************/
626 int sys_getgroups(int setlen, gid_t *gidset)
628 #if !defined(HAVE_BROKEN_GETGROUPS)
629 return getgroups(setlen, gidset);
637 return getgroups(setlen, &gid);
641 * Broken case. We need to allocate a
642 * GID_T array of size setlen.
651 setlen = groups_max();
653 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
654 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
658 if((ngroups = getgroups(setlen, group_list)) < 0) {
659 int saved_errno = errno;
660 SAFE_FREE(group_list);
665 for(i = 0; i < ngroups; i++)
666 gidset[i] = (gid_t)group_list[i];
668 SAFE_FREE(group_list);
670 #endif /* HAVE_BROKEN_GETGROUPS */
673 #ifdef HAVE_SETGROUPS
675 /**************************************************************************
676 Wrapper for setgroups. Deals with broken (int) case. Automatically used
677 if we have broken getgroups.
678 ****************************************************************************/
680 int sys_setgroups(int setlen, gid_t *gidset)
682 #if !defined(HAVE_BROKEN_GETGROUPS)
683 return setgroups(setlen, gidset);
692 if (setlen < 0 || setlen > groups_max()) {
698 * Broken case. We need to allocate a
699 * GID_T array of size setlen.
702 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
703 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
707 for(i = 0; i < setlen; i++)
708 group_list[i] = (GID_T) gidset[i];
710 if(setgroups(setlen, group_list) != 0) {
711 int saved_errno = errno;
712 SAFE_FREE(group_list);
717 SAFE_FREE(group_list);
719 #endif /* HAVE_BROKEN_GETGROUPS */
722 #endif /* HAVE_SETGROUPS */
725 * We only wrap pw_name and pw_passwd for now as these
726 * are the only potentially modified fields.
729 /**************************************************************************
730 Helper function for getpwnam/getpwuid wrappers.
731 ****************************************************************************/
742 static struct saved_pw pw_mod; /* This is the structure returned - can be modified. */
743 static struct saved_pw pw_cache; /* This is the structure saved - used to check cache. */
745 static int num_lookups; /* Counter so we don't always use cache. */
746 #ifndef PW_RET_CACHE_MAX_LOOKUPS
747 #define PW_RET_CACHE_MAX_LOOKUPS 100
750 static void copy_pwent(struct saved_pw *dst, struct passwd *pass)
752 memcpy((char *)&dst->pass, pass, sizeof(struct passwd));
754 fstrcpy(dst->pw_name, pass->pw_name);
755 dst->pass.pw_name = dst->pw_name;
757 fstrcpy(dst->pw_passwd, pass->pw_passwd);
758 dst->pass.pw_passwd = dst->pw_passwd;
760 fstrcpy(dst->pw_gecos, pass->pw_gecos);
761 dst->pass.pw_gecos = dst->pw_gecos;
763 pstrcpy(dst->pw_dir, pass->pw_dir);
764 dst->pass.pw_dir = dst->pw_dir;
766 pstrcpy(dst->pw_shell, pass->pw_shell);
767 dst->pass.pw_shell = dst->pw_shell;
770 static struct passwd *setup_pwret(struct passwd *pass)
773 /* Clear the caches. */
774 memset(&pw_cache, '\0', sizeof(struct saved_pw));
775 memset(&pw_mod, '\0', sizeof(struct saved_pw));
780 copy_pwent( &pw_mod, pass);
782 if (pass != &pw_cache.pass) {
784 /* If it's a cache miss we must also refill the cache. */
786 copy_pwent( &pw_cache, pass);
794 num_lookups = (num_lookups % PW_RET_CACHE_MAX_LOOKUPS);
800 /**************************************************************************
801 Wrappers for setpwent(), getpwent() and endpwent()
802 ****************************************************************************/
804 void sys_setpwent(void)
806 setup_pwret(NULL); /* Clear cache. */
810 struct passwd *sys_getpwent(void)
812 return setup_pwret(getpwent());
815 void sys_endpwent(void)
817 setup_pwret(NULL); /* Clear cache. */
821 /**************************************************************************
822 Wrapper for getpwnam(). Always returns a static that can be modified.
823 ****************************************************************************/
825 struct passwd *sys_getpwnam(const char *name)
827 if (!name || !name[0])
830 /* check for a cache hit first */
831 if (num_lookups && pw_cache.pass.pw_name && !strcmp(name, pw_cache.pass.pw_name)) {
832 return setup_pwret(&pw_cache.pass);
835 return setup_pwret(getpwnam(name));
838 /**************************************************************************
839 Wrapper for getpwuid(). Always returns a static that can be modified.
840 ****************************************************************************/
842 struct passwd *sys_getpwuid(uid_t uid)
844 if (num_lookups && pw_cache.pass.pw_name && (uid == pw_cache.pass.pw_uid)) {
845 return setup_pwret(&pw_cache.pass);
848 return setup_pwret(getpwuid(uid));
851 #if 0 /* NOT CURRENTLY USED - JRA */
852 /**************************************************************************
853 The following are the UNICODE versions of *all* system interface functions
854 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
855 which currently are left as ascii as they are not used other than in name
857 ****************************************************************************/
859 /**************************************************************************
860 Wide stat. Just narrow and call sys_xxx.
861 ****************************************************************************/
863 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
866 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
869 /**************************************************************************
870 Wide lstat. Just narrow and call sys_xxx.
871 ****************************************************************************/
873 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
876 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
879 /**************************************************************************
880 Wide creat. Just narrow and call sys_xxx.
881 ****************************************************************************/
883 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
886 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
889 /**************************************************************************
890 Wide open. Just narrow and call sys_xxx.
891 ****************************************************************************/
893 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
896 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
899 /**************************************************************************
900 Wide fopen. Just narrow and call sys_xxx.
901 ****************************************************************************/
903 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
906 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
909 /**************************************************************************
910 Wide opendir. Just narrow and call sys_xxx.
911 ****************************************************************************/
913 DIR *wsys_opendir(const smb_ucs2_t *wfname)
916 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
919 /**************************************************************************
920 Wide readdir. Return a structure pointer containing a wide filename.
921 ****************************************************************************/
923 SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
925 static SMB_STRUCT_WDIRENT retval;
926 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
932 * The only POSIX defined member of this struct is d_name.
935 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
940 /**************************************************************************
941 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
942 ****************************************************************************/
944 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
947 char *p = sys_getwd(fname);
952 return unix_to_unicode(s, p, sizeof(wpstring));
955 /**************************************************************************
956 Wide chown. Just narrow and call sys_xxx.
957 ****************************************************************************/
959 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
962 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
965 /**************************************************************************
966 Wide chroot. Just narrow and call sys_xxx.
967 ****************************************************************************/
969 int wsys_chroot(const smb_ucs2_t *wfname)
972 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
975 /**************************************************************************
976 Wide getpwnam. Return a structure pointer containing wide names.
977 ****************************************************************************/
979 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
981 static SMB_STRUCT_WPASSWD retval;
983 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
988 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
989 retval.pw_passwd = pwret->pw_passwd;
990 retval.pw_uid = pwret->pw_uid;
991 retval.pw_gid = pwret->pw_gid;
992 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
993 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
994 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
999 /**************************************************************************
1000 Wide getpwuid. Return a structure pointer containing wide names.
1001 ****************************************************************************/
1003 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
1005 static SMB_STRUCT_WPASSWD retval;
1006 struct passwd *pwret = sys_getpwuid(uid);
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));
1021 #endif /* NOT CURRENTLY USED - JRA */
1023 /**************************************************************************
1024 Extract a command into an arg list. Uses a static pstring for storage.
1025 Caller frees returned arg list (which contains pointers into the static pstring).
1026 ****************************************************************************/
1028 static char **extract_args(const char *command)
1030 static pstring trunc_cmd;
1036 pstrcpy(trunc_cmd, command);
1038 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1047 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1050 if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL)
1054 * Now do the extraction.
1057 pstrcpy(trunc_cmd, command);
1059 ptr = strtok(trunc_cmd, " \t");
1063 while((ptr = strtok(NULL, " \t")) != NULL)
1070 /**************************************************************************
1071 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1072 a sys_getpid() that only does a system call *once*.
1073 ****************************************************************************/
1075 static pid_t mypid = (pid_t)-1;
1077 pid_t sys_fork(void)
1079 pid_t forkret = fork();
1081 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1087 /**************************************************************************
1088 Wrapper for getpid. Ensures we only do a system call *once*.
1089 ****************************************************************************/
1091 pid_t sys_getpid(void)
1093 if (mypid == (pid_t)-1)
1099 /**************************************************************************
1100 Wrapper for popen. Safer as it doesn't search a path.
1101 Modified from the glibc sources.
1102 modified by tridge to return a file descriptor. We must kick our FILE* habit
1103 ****************************************************************************/
1105 typedef struct _popen_list
1109 struct _popen_list *next;
1112 static popen_list *popen_chain;
1114 int sys_popen(const char *command)
1116 int parent_end, child_end;
1118 popen_list *entry = NULL;
1121 if (pipe(pipe_fds) < 0)
1124 parent_end = pipe_fds[0];
1125 child_end = pipe_fds[1];
1132 if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL)
1135 ZERO_STRUCTP(entry);
1138 * Extract the command and args into a NULL terminated array.
1141 if(!(argl = extract_args(command)))
1144 entry->child_pid = sys_fork();
1146 if (entry->child_pid == -1) {
1150 if (entry->child_pid == 0) {
1156 int child_std_end = STDOUT_FILENO;
1160 if (child_end != child_std_end) {
1161 dup2 (child_end, child_std_end);
1166 * POSIX.2: "popen() shall ensure that any streams from previous
1167 * popen() calls that remain open in the parent process are closed
1168 * in the new child process."
1171 for (p = popen_chain; p; p = p->next)
1174 execv(argl[0], argl);
1185 /* Link into popen_chain. */
1186 entry->next = popen_chain;
1187 popen_chain = entry;
1188 entry->fd = parent_end;
1201 /**************************************************************************
1202 Wrapper for pclose. Modified from the glibc sources.
1203 ****************************************************************************/
1205 int sys_pclose(int fd)
1208 popen_list **ptr = &popen_chain;
1209 popen_list *entry = NULL;
1213 /* Unlink from popen_chain. */
1214 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1215 if ((*ptr)->fd == fd) {
1217 *ptr = (*ptr)->next;
1223 if (status < 0 || close(entry->fd) < 0)
1227 * As Samba is catching and eating child process
1228 * exits we don't really care about the child exit
1229 * code, a -1 with errno = ECHILD will do fine for us.
1233 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1234 } while (wait_pid == -1 && errno == EINTR);
1243 /**************************************************************************
1244 Wrappers for dlopen, dlsym, dlclose.
1245 ****************************************************************************/
1247 void *sys_dlopen(const char *name, int flags)
1249 #if defined(HAVE_LIBDL) || defined(HAVE_DLOPEN)
1250 return dlopen(name, flags);
1256 void *sys_dlsym(void *handle, char *symbol)
1258 #if defined(HAVE_LIBDL) || defined(HAVE_DLSYM)
1259 return dlsym(handle, symbol);
1265 int sys_dlclose (void *handle)
1267 #if defined(HAVE_LIBDL) || defined(HAVE_DLCLOSE)
1268 return dlclose(handle);
1274 const char *sys_dlerror(void)
1276 #if defined(HAVE_LIBDL) || defined(HAVE_DLERROR)
1283 /**************************************************************************
1284 Wrapper for Admin Logs.
1285 ****************************************************************************/
1287 void sys_adminlog(int priority, const char *format_str, ...)
1291 char **msgbuf = NULL;
1293 if (!lp_admin_log())
1296 va_start( ap, format_str );
1297 ret = vasprintf( msgbuf, format_str, ap );
1303 #if defined(HAVE_SYSLOG)
1304 syslog( priority, "%s", *msgbuf );
1306 DEBUG(0,("%s", *msgbuf ));