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);
104 /*******************************************************************
105 A pread wrapper that will deal with EINTR and 64-bit file offsets.
106 ********************************************************************/
108 #if defined(HAVE_PREAD) || defined(HAVE_PREAD64)
109 ssize_t sys_pread(int fd, void *buf, size_t count, SMB_OFF_T off)
114 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PREAD64)
115 ret = pread64(fd, buf, count, off);
117 ret = pread(fd, buf, count, off);
119 } while (ret == -1 && errno == EINTR);
124 /*******************************************************************
125 A write wrapper that will deal with EINTR and 64-bit file offsets.
126 ********************************************************************/
128 #if defined(HAVE_PWRITE) || defined(HAVE_PWRITE64)
129 ssize_t sys_pwrite(int fd, const void *buf, size_t count, SMB_OFF_T off)
134 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_PWRITE64)
135 ret = pwrite64(fd, buf, count, off);
137 ret = pwrite(fd, buf, count, off);
139 } while (ret == -1 && errno == EINTR);
144 /*******************************************************************
145 A send wrapper that will deal with EINTR.
146 ********************************************************************/
148 ssize_t sys_send(int s, const void *msg, size_t len, int flags)
153 ret = send(s, msg, len, flags);
154 } while (ret == -1 && errno == EINTR);
158 /*******************************************************************
159 A sendto wrapper that will deal with EINTR.
160 ********************************************************************/
162 ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
167 ret = sendto(s, msg, len, flags, to, tolen);
168 } while (ret == -1 && errno == EINTR);
172 /*******************************************************************
173 A recvfrom wrapper that will deal with EINTR.
174 ********************************************************************/
176 ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
181 ret = recvfrom(s, buf, len, flags, from, fromlen);
182 } while (ret == -1 && errno == EINTR);
186 /*******************************************************************
187 A fcntl wrapper that will deal with EINTR.
188 ********************************************************************/
190 int sys_fcntl_ptr(int fd, int cmd, void *arg)
195 ret = fcntl(fd, cmd, arg);
196 } while (ret == -1 && errno == EINTR);
200 /*******************************************************************
201 A fcntl wrapper that will deal with EINTR.
202 ********************************************************************/
204 int sys_fcntl_long(int fd, int cmd, long arg)
209 ret = fcntl(fd, cmd, arg);
210 } while (ret == -1 && errno == EINTR);
214 /*******************************************************************
215 A stat() wrapper that will deal with 64 bit filesizes.
216 ********************************************************************/
218 int sys_stat(const char *fname,SMB_STRUCT_STAT *sbuf)
221 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
222 ret = stat64(fname, sbuf);
224 ret = stat(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 fstat() wrapper that will deal with 64 bit filesizes.
233 ********************************************************************/
235 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
238 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
239 ret = fstat64(fd, sbuf);
241 ret = fstat(fd, sbuf);
243 /* we always want directories to appear zero size */
244 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
248 /*******************************************************************
249 An lstat() wrapper that will deal with 64 bit filesizes.
250 ********************************************************************/
252 int sys_lstat(const char *fname,SMB_STRUCT_STAT *sbuf)
255 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
256 ret = lstat64(fname, sbuf);
258 ret = lstat(fname, sbuf);
260 /* we always want directories to appear zero size */
261 if (ret == 0 && S_ISDIR(sbuf->st_mode)) sbuf->st_size = 0;
265 /*******************************************************************
266 An ftruncate() wrapper that will deal with 64 bit filesizes.
267 ********************************************************************/
269 int sys_ftruncate(int fd, SMB_OFF_T offset)
271 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
272 return ftruncate64(fd, offset);
274 return ftruncate(fd, offset);
278 /*******************************************************************
279 An lseek() wrapper that will deal with 64 bit filesizes.
280 ********************************************************************/
282 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
284 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
285 return lseek64(fd, offset, whence);
287 return lseek(fd, offset, whence);
291 /*******************************************************************
292 An fseek() wrapper that will deal with 64 bit filesizes.
293 ********************************************************************/
295 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
297 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
298 return fseek64(fp, offset, whence);
299 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEKO64)
300 return fseeko64(fp, offset, whence);
302 return fseek(fp, offset, whence);
306 /*******************************************************************
307 An ftell() wrapper that will deal with 64 bit filesizes.
308 ********************************************************************/
310 SMB_OFF_T sys_ftell(FILE *fp)
312 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
313 return (SMB_OFF_T)ftell64(fp);
314 #elif defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELLO64)
315 return (SMB_OFF_T)ftello64(fp);
317 return (SMB_OFF_T)ftell(fp);
321 /*******************************************************************
322 A creat() wrapper that will deal with 64 bit filesizes.
323 ********************************************************************/
325 int sys_creat(const char *path, mode_t mode)
327 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_CREAT64)
328 return creat64(path, mode);
331 * If creat64 isn't defined then ensure we call a potential open64.
334 return sys_open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);
338 /*******************************************************************
339 An open() wrapper that will deal with 64 bit filesizes.
340 ********************************************************************/
342 int sys_open(const char *path, int oflag, mode_t mode)
344 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_OPEN64)
345 return open64(path, oflag, mode);
347 return open(path, oflag, mode);
351 /*******************************************************************
352 An fopen() wrapper that will deal with 64 bit filesizes.
353 ********************************************************************/
355 FILE *sys_fopen(const char *path, const char *type)
357 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_FOPEN64)
358 return fopen64(path, type);
360 return fopen(path, type);
364 /*******************************************************************
365 A readdir wrapper that will deal with 64 bit filesizes.
366 ********************************************************************/
368 SMB_STRUCT_DIRENT *sys_readdir(DIR *dirp)
370 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_READDIR64)
371 return readdir64(dirp);
373 return readdir(dirp);
377 /*******************************************************************
378 An mknod() wrapper that will deal with 64 bit filesizes.
379 ********************************************************************/
381 int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev)
383 #if defined(HAVE_MKNOD) || defined(HAVE_MKNOD64)
384 #if defined(HAVE_EXPLICIT_LARGEFILE_SUPPORT) && defined(HAVE_MKNOD64) && defined(HAVE_DEV64_T)
385 return mknod64(path, mode, dev);
387 return mknod(path, mode, dev);
390 /* No mknod system call. */
396 /*******************************************************************
397 Wrapper for realpath.
398 ********************************************************************/
400 char *sys_realpath(const char *path, char *resolved_path)
402 #if defined(HAVE_REALPATH)
403 return realpath(path, resolved_path);
405 /* As realpath is not a system call we can't return ENOSYS. */
411 /*******************************************************************
412 The wait() calls vary between systems
413 ********************************************************************/
415 int sys_waitpid(pid_t pid,int *status,int options)
418 return waitpid(pid,status,options);
419 #else /* HAVE_WAITPID */
420 return wait4(pid, status, options, NULL);
421 #endif /* HAVE_WAITPID */
424 /*******************************************************************
425 System wrapper for getwd
426 ********************************************************************/
428 char *sys_getwd(char *s)
432 wd = (char *)getcwd(s, sizeof (pstring));
434 wd = (char *)getwd(s);
439 /*******************************************************************
440 system wrapper for symlink
441 ********************************************************************/
443 int sys_symlink(const char *oldpath, const char *newpath)
449 return symlink(oldpath, newpath);
453 /*******************************************************************
454 system wrapper for readlink
455 ********************************************************************/
457 int sys_readlink(const char *path, char *buf, size_t bufsiz)
459 #ifndef HAVE_READLINK
463 return readlink(path, buf, bufsiz);
467 /*******************************************************************
468 system wrapper for link
469 ********************************************************************/
471 int sys_link(const char *oldpath, const char *newpath)
477 return link(oldpath, newpath);
481 /*******************************************************************
482 chown isn't used much but OS/2 doesn't have it
483 ********************************************************************/
485 int sys_chown(const char *fname,uid_t uid,gid_t gid)
490 DEBUG(1,("WARNING: no chown!\n"));
494 return(chown(fname,uid,gid));
498 /*******************************************************************
499 os/2 also doesn't have chroot
500 ********************************************************************/
501 int sys_chroot(const char *dname)
506 DEBUG(1,("WARNING: no chroot!\n"));
512 return(chroot(dname));
516 /**************************************************************************
517 A wrapper for gethostbyname() that tries avoids looking up hostnames
518 in the root domain, which can cause dial-on-demand links to come up for no
520 ****************************************************************************/
522 struct hostent *sys_gethostbyname(const char *name)
524 #ifdef REDUCE_ROOT_DNS_LOOKUPS
525 char query[256], hostname[256];
528 /* Does this name have any dots in it? If so, make no change */
530 if (strchr_m(name, '.'))
531 return(gethostbyname(name));
533 /* Get my hostname, which should have domain name
534 attached. If not, just do the gethostname on the
538 gethostname(hostname, sizeof(hostname) - 1);
539 hostname[sizeof(hostname) - 1] = 0;
540 if ((domain = strchr_m(hostname, '.')) == NULL)
541 return(gethostbyname(name));
543 /* Attach domain name to query and do modified query.
544 If names too large, just do gethostname on the
548 if((strlen(name) + strlen(domain)) >= sizeof(query))
549 return(gethostbyname(name));
551 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
552 return(gethostbyname(query));
553 #else /* REDUCE_ROOT_DNS_LOOKUPS */
554 return(gethostbyname(name));
555 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
559 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
560 /**************************************************************************
561 Try and abstract process capabilities (for systems that have them).
562 ****************************************************************************/
563 static BOOL set_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_process_capability: cap_get_proc failed. Error was %s\n",
575 cap->cap_effective |= CAP_NETWORK_MGT;
577 cap->cap_effective &= ~CAP_NETWORK_MGT;
579 if (cap_set_proc(cap) == -1) {
580 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
588 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
593 /**************************************************************************
594 Try and abstract inherited process capabilities (for systems that have them).
595 ****************************************************************************/
597 static BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
599 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
600 cap_t cap = cap_get_proc();
603 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
609 cap->cap_inheritable |= CAP_NETWORK_MGT;
611 cap->cap_inheritable &= ~CAP_NETWORK_MGT;
613 if (cap_set_proc(cap) == -1) {
614 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
622 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
628 /****************************************************************************
629 Gain the oplock capability from the kernel if possible.
630 ****************************************************************************/
632 void oplock_set_capability(BOOL this_process, BOOL inherit)
634 #if HAVE_KERNEL_OPLOCKS_IRIX
635 set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process);
636 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit);
640 /**************************************************************************
641 Wrapper for random().
642 ****************************************************************************/
644 long sys_random(void)
646 #if defined(HAVE_RANDOM)
647 return (long)random();
648 #elif defined(HAVE_RAND)
651 DEBUG(0,("Error - no random function available !\n"));
656 /**************************************************************************
657 Wrapper for srandom().
658 ****************************************************************************/
660 void sys_srandom(unsigned int seed)
662 #if defined(HAVE_SRANDOM)
664 #elif defined(HAVE_SRAND)
667 DEBUG(0,("Error - no srandom function available !\n"));
672 /**************************************************************************
673 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
674 ****************************************************************************/
678 #if defined(SYSCONF_SC_NGROUPS_MAX)
679 int ret = sysconf(_SC_NGROUPS_MAX);
680 return (ret == -1) ? NGROUPS_MAX : ret;
686 /**************************************************************************
687 Wrapper for getgroups. Deals with broken (int) case.
688 ****************************************************************************/
690 int sys_getgroups(int setlen, gid_t *gidset)
692 #if !defined(HAVE_BROKEN_GETGROUPS)
693 return getgroups(setlen, gidset);
701 return getgroups(setlen, &gid);
705 * Broken case. We need to allocate a
706 * GID_T array of size setlen.
715 setlen = groups_max();
717 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
718 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
722 if((ngroups = getgroups(setlen, group_list)) < 0) {
723 int saved_errno = errno;
724 SAFE_FREE(group_list);
729 for(i = 0; i < ngroups; i++)
730 gidset[i] = (gid_t)group_list[i];
732 SAFE_FREE(group_list);
734 #endif /* HAVE_BROKEN_GETGROUPS */
738 /**************************************************************************
739 Wrapper for setgroups. Deals with broken (int) case. Automatically used
740 if we have broken getgroups.
741 ****************************************************************************/
743 int sys_setgroups(int setlen, gid_t *gidset)
745 #if !defined(HAVE_SETGROUPS)
748 #endif /* HAVE_SETGROUPS */
750 #if !defined(HAVE_BROKEN_GETGROUPS)
751 return setgroups(setlen, gidset);
760 if (setlen < 0 || setlen > groups_max()) {
766 * Broken case. We need to allocate a
767 * GID_T array of size setlen.
770 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
771 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
775 for(i = 0; i < setlen; i++)
776 group_list[i] = (GID_T) gidset[i];
778 if(setgroups(setlen, group_list) != 0) {
779 int saved_errno = errno;
780 SAFE_FREE(group_list);
785 SAFE_FREE(group_list);
787 #endif /* HAVE_BROKEN_GETGROUPS */
790 /**************************************************************************
791 Wrappers for setpwent(), getpwent() and endpwent()
792 ****************************************************************************/
794 void sys_setpwent(void)
799 struct passwd *sys_getpwent(void)
804 void sys_endpwent(void)
809 /**************************************************************************
810 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
811 ****************************************************************************/
813 struct passwd *sys_getpwnam(const char *name)
815 return getpwnam(name);
818 struct passwd *sys_getpwuid(uid_t uid)
820 return getpwuid(uid);
823 struct group *sys_getgrnam(const char *name)
825 return getgrnam(name);
828 struct group *sys_getgrgid(gid_t gid)
830 return getgrgid(gid);
833 #if 0 /* NOT CURRENTLY USED - JRA */
834 /**************************************************************************
835 The following are the UNICODE versions of *all* system interface functions
836 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
837 which currently are left as ascii as they are not used other than in name
839 ****************************************************************************/
841 /**************************************************************************
842 Wide stat. Just narrow and call sys_xxx.
843 ****************************************************************************/
845 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
848 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
851 /**************************************************************************
852 Wide lstat. Just narrow and call sys_xxx.
853 ****************************************************************************/
855 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
858 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
861 /**************************************************************************
862 Wide creat. Just narrow and call sys_xxx.
863 ****************************************************************************/
865 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
868 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
871 /**************************************************************************
872 Wide open. Just narrow and call sys_xxx.
873 ****************************************************************************/
875 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
878 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
881 /**************************************************************************
882 Wide fopen. Just narrow and call sys_xxx.
883 ****************************************************************************/
885 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
888 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
891 /**************************************************************************
892 Wide opendir. Just narrow and call sys_xxx.
893 ****************************************************************************/
895 DIR *wsys_opendir(const smb_ucs2_t *wfname)
898 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
901 /**************************************************************************
902 Wide readdir. Return a structure pointer containing a wide filename.
903 ****************************************************************************/
905 SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
907 static SMB_STRUCT_WDIRENT retval;
908 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
914 * The only POSIX defined member of this struct is d_name.
917 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
922 /**************************************************************************
923 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
924 ****************************************************************************/
926 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
929 char *p = sys_getwd(fname);
934 return unix_to_unicode(s, p, sizeof(wpstring));
937 /**************************************************************************
938 Wide chown. Just narrow and call sys_xxx.
939 ****************************************************************************/
941 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
944 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
947 /**************************************************************************
948 Wide chroot. Just narrow and call sys_xxx.
949 ****************************************************************************/
951 int wsys_chroot(const smb_ucs2_t *wfname)
954 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
957 /**************************************************************************
958 Wide getpwnam. Return a structure pointer containing wide names.
959 ****************************************************************************/
961 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
963 static SMB_STRUCT_WPASSWD retval;
965 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
970 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
971 retval.pw_passwd = pwret->pw_passwd;
972 retval.pw_uid = pwret->pw_uid;
973 retval.pw_gid = pwret->pw_gid;
974 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
975 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
976 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
981 /**************************************************************************
982 Wide getpwuid. Return a structure pointer containing wide names.
983 ****************************************************************************/
985 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
987 static SMB_STRUCT_WPASSWD retval;
988 struct passwd *pwret = sys_getpwuid(uid);
993 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
994 retval.pw_passwd = pwret->pw_passwd;
995 retval.pw_uid = pwret->pw_uid;
996 retval.pw_gid = pwret->pw_gid;
997 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
998 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
999 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1003 #endif /* NOT CURRENTLY USED - JRA */
1005 /**************************************************************************
1006 Extract a command into an arg list. Uses a static pstring for storage.
1007 Caller frees returned arg list (which contains pointers into the static pstring).
1008 ****************************************************************************/
1010 static char **extract_args(const char *command)
1012 static pstring trunc_cmd;
1018 pstrcpy(trunc_cmd, command);
1020 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1029 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1032 if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL)
1036 * Now do the extraction.
1039 pstrcpy(trunc_cmd, command);
1041 ptr = strtok(trunc_cmd, " \t");
1045 while((ptr = strtok(NULL, " \t")) != NULL)
1052 /**************************************************************************
1053 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1054 a sys_getpid() that only does a system call *once*.
1055 ****************************************************************************/
1057 static pid_t mypid = (pid_t)-1;
1059 pid_t sys_fork(void)
1061 pid_t forkret = fork();
1063 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1069 /**************************************************************************
1070 Wrapper for getpid. Ensures we only do a system call *once*.
1071 ****************************************************************************/
1073 pid_t sys_getpid(void)
1075 if (mypid == (pid_t)-1)
1081 /**************************************************************************
1082 Wrapper for popen. Safer as it doesn't search a path.
1083 Modified from the glibc sources.
1084 modified by tridge to return a file descriptor. We must kick our FILE* habit
1085 ****************************************************************************/
1087 typedef struct _popen_list
1091 struct _popen_list *next;
1094 static popen_list *popen_chain;
1096 int sys_popen(const char *command)
1098 int parent_end, child_end;
1100 popen_list *entry = NULL;
1103 if (pipe(pipe_fds) < 0)
1106 parent_end = pipe_fds[0];
1107 child_end = pipe_fds[1];
1114 if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL)
1117 ZERO_STRUCTP(entry);
1120 * Extract the command and args into a NULL terminated array.
1123 if(!(argl = extract_args(command)))
1126 entry->child_pid = sys_fork();
1128 if (entry->child_pid == -1) {
1132 if (entry->child_pid == 0) {
1138 int child_std_end = STDOUT_FILENO;
1142 if (child_end != child_std_end) {
1143 dup2 (child_end, child_std_end);
1148 * POSIX.2: "popen() shall ensure that any streams from previous
1149 * popen() calls that remain open in the parent process are closed
1150 * in the new child process."
1153 for (p = popen_chain; p; p = p->next)
1156 execv(argl[0], argl);
1167 /* Link into popen_chain. */
1168 entry->next = popen_chain;
1169 popen_chain = entry;
1170 entry->fd = parent_end;
1183 /**************************************************************************
1184 Wrapper for pclose. Modified from the glibc sources.
1185 ****************************************************************************/
1187 int sys_pclose(int fd)
1190 popen_list **ptr = &popen_chain;
1191 popen_list *entry = NULL;
1195 /* Unlink from popen_chain. */
1196 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1197 if ((*ptr)->fd == fd) {
1199 *ptr = (*ptr)->next;
1205 if (status < 0 || close(entry->fd) < 0)
1209 * As Samba is catching and eating child process
1210 * exits we don't really care about the child exit
1211 * code, a -1 with errno = ECHILD will do fine for us.
1215 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1216 } while (wait_pid == -1 && errno == EINTR);
1225 /**************************************************************************
1226 Wrappers for dlopen, dlsym, dlclose.
1227 ****************************************************************************/
1229 void *sys_dlopen(const char *name, int flags)
1231 #if defined(HAVE_DLOPEN)
1232 return dlopen(name, flags);
1238 void *sys_dlsym(void *handle, const char *symbol)
1240 #if defined(HAVE_DLSYM)
1241 return dlsym(handle, symbol);
1247 int sys_dlclose (void *handle)
1249 #if defined(HAVE_DLCLOSE)
1250 return dlclose(handle);
1256 const char *sys_dlerror(void)
1258 #if defined(HAVE_DLERROR)
1265 int sys_dup2(int oldfd, int newfd)
1267 #if defined(HAVE_DUP2)
1268 return dup2(oldfd, newfd);
1275 /**************************************************************************
1276 Wrapper for Admin Logs.
1277 ****************************************************************************/
1279 void sys_adminlog(int priority, const char *format_str, ...)
1283 char *msgbuf = NULL;
1285 va_start( ap, format_str );
1286 ret = vasprintf( &msgbuf, format_str, ap );
1292 #if defined(HAVE_SYSLOG)
1293 syslog( priority, "%s", msgbuf );
1295 DEBUG(0,("%s", msgbuf ));
1300 /**************************************************************************
1301 Wrappers for extented attribute calls. Based on the Linux package with
1302 support for IRIX also. Expand as other systems have them.
1303 ****************************************************************************/
1305 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1307 #if defined(HAVE_GETXATTR)
1308 return getxattr(path, name, value, size);
1309 #elif defined(HAVE_ATTR_GET)
1310 int retval, flags = 0;
1311 int valuelength = (int)size;
1312 char *attrname = strchr(name,'.') +1;
1314 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1316 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1318 return retval ? retval : valuelength;
1325 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1327 #if defined(HAVE_LGETXATTR)
1328 return lgetxattr(path, name, value, size);
1329 #elif defined(HAVE_ATTR_GET)
1330 int retval, flags = ATTR_DONTFOLLOW;
1331 int valuelength = (int)size;
1332 char *attrname = strchr(name,'.') +1;
1334 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1336 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1338 return retval ? retval : valuelength;
1345 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1347 #if defined(HAVE_FGETXATTR)
1348 return fgetxattr(filedes, name, value, size);
1349 #elif defined(HAVE_ATTR_GETF)
1350 int retval, flags = 0;
1351 int valuelength = (int)size;
1352 char *attrname = strchr(name,'.') +1;
1354 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1356 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1358 return retval ? retval : valuelength;
1365 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1366 static char attr_buffer[ATTR_MAX_VALUELEN];
1368 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1370 int retval = 0, index;
1371 attrlist_cursor_t *cursor = 0;
1373 attrlist_t * al = (attrlist_t *)attr_buffer;
1375 size_t ent_size, left = size;
1380 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1382 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1384 for (index = 0; index < al->al_count; index++) {
1385 ae = ATTR_ENTRY(attr_buffer, index);
1386 ent_size = strlen(ae->a_name) + sizeof("user.");
1387 if (left >= ent_size) {
1388 strncpy(bp, "user.", sizeof("user."));
1389 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1397 total_size += ent_size;
1399 if (al->al_more == 0) break;
1406 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1408 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1410 for (index = 0; index < al->al_count; index++) {
1411 ae = ATTR_ENTRY(attr_buffer, index);
1412 ent_size = strlen(ae->a_name) + sizeof("system.");
1413 if (left >= ent_size) {
1414 strncpy(bp, "system.", sizeof("system."));
1415 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1423 total_size += ent_size;
1425 if (al->al_more == 0) break;
1428 return (ssize_t)(retval ? retval : total_size);
1433 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1435 #if defined(HAVE_LISTXATTR)
1436 return listxattr(path, list, size);
1437 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1438 return irix_attr_list(path, 0, list, size, 0);
1445 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1447 #if defined(HAVE_LLISTXATTR)
1448 return llistxattr(path, list, size);
1449 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1450 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1457 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1459 #if defined(HAVE_FLISTXATTR)
1460 return flistxattr(filedes, list, size);
1461 #elif defined(HAVE_ATTR_LISTF)
1462 return irix_attr_list(NULL, filedes, list, size, 0);
1469 int sys_removexattr (const char *path, const char *name)
1471 #if defined(HAVE_REMOVEXATTR)
1472 return removexattr(path, name);
1473 #elif defined(HAVE_ATTR_REMOVE)
1475 char *attrname = strchr(name,'.') +1;
1477 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1479 return attr_remove(path, attrname, flags);
1486 int sys_lremovexattr (const char *path, const char *name)
1488 #if defined(HAVE_LREMOVEXATTR)
1489 return lremovexattr(path, name);
1490 #elif defined(HAVE_ATTR_REMOVE)
1491 int flags = ATTR_DONTFOLLOW;
1492 char *attrname = strchr(name,'.') +1;
1494 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1496 return attr_remove(path, attrname, flags);
1503 int sys_fremovexattr (int filedes, const char *name)
1505 #if defined(HAVE_FREMOVEXATTR)
1506 return fremovexattr(filedes, name);
1507 #elif defined(HAVE_ATTR_REMOVEF)
1509 char *attrname = strchr(name,'.') +1;
1511 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1513 return attr_removef(filedes, attrname, flags);
1520 #if !defined(HAVE_SETXATTR)
1521 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1522 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1525 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1527 #if defined(HAVE_SETXATTR)
1528 return setxattr(path, name, value, size, flags);
1529 #elif defined(HAVE_ATTR_SET)
1531 char *attrname = strchr(name,'.') +1;
1533 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1534 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1535 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1537 return attr_set(path, attrname, (const char *)value, size, myflags);
1544 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1546 #if defined(HAVE_LSETXATTR)
1547 return lsetxattr(path, name, value, size, flags);
1548 #elif defined(HAVE_ATTR_SET)
1549 int myflags = ATTR_DONTFOLLOW;
1550 char *attrname = strchr(name,'.') +1;
1552 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1553 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1554 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1556 return attr_set(path, attrname, (const char *)value, size, myflags);
1563 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
1565 #if defined(HAVE_FSETXATTR)
1566 return fsetxattr(filedes, name, value, size, flags);
1567 #elif defined(HAVE_ATTR_SETF)
1569 char *attrname = strchr(name,'.') +1;
1571 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1572 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1573 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1575 return attr_setf(filedes, attrname, (const char *)value, size, myflags);