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"));
496 return(chown(fname,uid,gid));
500 /*******************************************************************
501 os/2 also doesn't have chroot
502 ********************************************************************/
503 int sys_chroot(const char *dname)
508 DEBUG(1,("WARNING: no chroot!\n"));
514 return(chroot(dname));
518 /**************************************************************************
519 A wrapper for gethostbyname() that tries avoids looking up hostnames
520 in the root domain, which can cause dial-on-demand links to come up for no
522 ****************************************************************************/
524 struct hostent *sys_gethostbyname(const char *name)
526 #ifdef REDUCE_ROOT_DNS_LOOKUPS
527 char query[256], hostname[256];
530 /* Does this name have any dots in it? If so, make no change */
532 if (strchr_m(name, '.'))
533 return(gethostbyname(name));
535 /* Get my hostname, which should have domain name
536 attached. If not, just do the gethostname on the
540 gethostname(hostname, sizeof(hostname) - 1);
541 hostname[sizeof(hostname) - 1] = 0;
542 if ((domain = strchr_m(hostname, '.')) == NULL)
543 return(gethostbyname(name));
545 /* Attach domain name to query and do modified query.
546 If names too large, just do gethostname on the
550 if((strlen(name) + strlen(domain)) >= sizeof(query))
551 return(gethostbyname(name));
553 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
554 return(gethostbyname(query));
555 #else /* REDUCE_ROOT_DNS_LOOKUPS */
556 return(gethostbyname(name));
557 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
561 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
562 /**************************************************************************
563 Try and abstract process capabilities (for systems that have them).
564 ****************************************************************************/
565 static BOOL set_process_capability( uint32 cap_flag, BOOL enable )
567 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
568 cap_t cap = cap_get_proc();
571 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
577 cap->cap_effective |= CAP_NETWORK_MGT;
579 cap->cap_effective &= ~CAP_NETWORK_MGT;
581 if (cap_set_proc(cap) == -1) {
582 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
590 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
595 /**************************************************************************
596 Try and abstract inherited process capabilities (for systems that have them).
597 ****************************************************************************/
599 static BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
601 if(cap_flag == KERNEL_OPLOCK_CAPABILITY) {
602 cap_t cap = cap_get_proc();
605 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
611 cap->cap_inheritable |= CAP_NETWORK_MGT;
613 cap->cap_inheritable &= ~CAP_NETWORK_MGT;
615 if (cap_set_proc(cap) == -1) {
616 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
624 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
630 /****************************************************************************
631 Gain the oplock capability from the kernel if possible.
632 ****************************************************************************/
634 void oplock_set_capability(BOOL this_process, BOOL inherit)
636 #if HAVE_KERNEL_OPLOCKS_IRIX
637 set_process_capability(KERNEL_OPLOCK_CAPABILITY,this_process);
638 set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY,inherit);
642 /**************************************************************************
643 Wrapper for random().
644 ****************************************************************************/
646 long sys_random(void)
648 #if defined(HAVE_RANDOM)
649 return (long)random();
650 #elif defined(HAVE_RAND)
653 DEBUG(0,("Error - no random function available !\n"));
658 /**************************************************************************
659 Wrapper for srandom().
660 ****************************************************************************/
662 void sys_srandom(unsigned int seed)
664 #if defined(HAVE_SRANDOM)
666 #elif defined(HAVE_SRAND)
669 DEBUG(0,("Error - no srandom function available !\n"));
674 /**************************************************************************
675 Returns equivalent to NGROUPS_MAX - using sysconf if needed.
676 ****************************************************************************/
680 #if defined(SYSCONF_SC_NGROUPS_MAX)
681 int ret = sysconf(_SC_NGROUPS_MAX);
682 return (ret == -1) ? NGROUPS_MAX : ret;
688 /**************************************************************************
689 Wrapper for getgroups. Deals with broken (int) case.
690 ****************************************************************************/
692 int sys_getgroups(int setlen, gid_t *gidset)
694 #if !defined(HAVE_BROKEN_GETGROUPS)
695 return getgroups(setlen, gidset);
703 return getgroups(setlen, &gid);
707 * Broken case. We need to allocate a
708 * GID_T array of size setlen.
717 setlen = groups_max();
719 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
720 DEBUG(0,("sys_getgroups: Malloc fail.\n"));
724 if((ngroups = getgroups(setlen, group_list)) < 0) {
725 int saved_errno = errno;
726 SAFE_FREE(group_list);
731 for(i = 0; i < ngroups; i++)
732 gidset[i] = (gid_t)group_list[i];
734 SAFE_FREE(group_list);
736 #endif /* HAVE_BROKEN_GETGROUPS */
740 /**************************************************************************
741 Wrapper for setgroups. Deals with broken (int) case. Automatically used
742 if we have broken getgroups.
743 ****************************************************************************/
745 int sys_setgroups(int setlen, gid_t *gidset)
747 #if !defined(HAVE_SETGROUPS)
750 #endif /* HAVE_SETGROUPS */
752 #if !defined(HAVE_BROKEN_GETGROUPS)
753 return setgroups(setlen, gidset);
762 if (setlen < 0 || setlen > groups_max()) {
768 * Broken case. We need to allocate a
769 * GID_T array of size setlen.
772 if((group_list = (GID_T *)malloc(setlen * sizeof(GID_T))) == NULL) {
773 DEBUG(0,("sys_setgroups: Malloc fail.\n"));
777 for(i = 0; i < setlen; i++)
778 group_list[i] = (GID_T) gidset[i];
780 if(setgroups(setlen, group_list) != 0) {
781 int saved_errno = errno;
782 SAFE_FREE(group_list);
787 SAFE_FREE(group_list);
789 #endif /* HAVE_BROKEN_GETGROUPS */
792 /**************************************************************************
793 Wrappers for setpwent(), getpwent() and endpwent()
794 ****************************************************************************/
796 void sys_setpwent(void)
801 struct passwd *sys_getpwent(void)
806 void sys_endpwent(void)
811 /**************************************************************************
812 Wrappers for getpwnam(), getpwuid(), getgrnam(), getgrgid()
813 ****************************************************************************/
815 struct passwd *sys_getpwnam(const char *name)
817 return getpwnam(name);
820 struct passwd *sys_getpwuid(uid_t uid)
822 return getpwuid(uid);
825 struct group *sys_getgrnam(const char *name)
827 return getgrnam(name);
830 struct group *sys_getgrgid(gid_t gid)
832 return getgrgid(gid);
835 #if 0 /* NOT CURRENTLY USED - JRA */
836 /**************************************************************************
837 The following are the UNICODE versions of *all* system interface functions
838 called within Samba. Ok, ok, the exceptions are the gethostbyXX calls,
839 which currently are left as ascii as they are not used other than in name
841 ****************************************************************************/
843 /**************************************************************************
844 Wide stat. Just narrow and call sys_xxx.
845 ****************************************************************************/
847 int wsys_stat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
850 return sys_stat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
853 /**************************************************************************
854 Wide lstat. Just narrow and call sys_xxx.
855 ****************************************************************************/
857 int wsys_lstat(const smb_ucs2_t *wfname,SMB_STRUCT_STAT *sbuf)
860 return sys_lstat(unicode_to_unix(fname,wfname,sizeof(fname)), sbuf);
863 /**************************************************************************
864 Wide creat. Just narrow and call sys_xxx.
865 ****************************************************************************/
867 int wsys_creat(const smb_ucs2_t *wfname, mode_t mode)
870 return sys_creat(unicode_to_unix(fname,wfname,sizeof(fname)), mode);
873 /**************************************************************************
874 Wide open. Just narrow and call sys_xxx.
875 ****************************************************************************/
877 int wsys_open(const smb_ucs2_t *wfname, int oflag, mode_t mode)
880 return sys_open(unicode_to_unix(fname,wfname,sizeof(fname)), oflag, mode);
883 /**************************************************************************
884 Wide fopen. Just narrow and call sys_xxx.
885 ****************************************************************************/
887 FILE *wsys_fopen(const smb_ucs2_t *wfname, const char *type)
890 return sys_fopen(unicode_to_unix(fname,wfname,sizeof(fname)), type);
893 /**************************************************************************
894 Wide opendir. Just narrow and call sys_xxx.
895 ****************************************************************************/
897 DIR *wsys_opendir(const smb_ucs2_t *wfname)
900 return opendir(unicode_to_unix(fname,wfname,sizeof(fname)));
903 /**************************************************************************
904 Wide readdir. Return a structure pointer containing a wide filename.
905 ****************************************************************************/
907 SMB_STRUCT_WDIRENT *wsys_readdir(DIR *dirp)
909 static SMB_STRUCT_WDIRENT retval;
910 SMB_STRUCT_DIRENT *dirval = sys_readdir(dirp);
916 * The only POSIX defined member of this struct is d_name.
919 unix_to_unicode(retval.d_name,dirval->d_name,sizeof(retval.d_name));
924 /**************************************************************************
925 Wide getwd. Call sys_xxx and widen. Assumes s points to a wpstring.
926 ****************************************************************************/
928 smb_ucs2_t *wsys_getwd(smb_ucs2_t *s)
931 char *p = sys_getwd(fname);
936 return unix_to_unicode(s, p, sizeof(wpstring));
939 /**************************************************************************
940 Wide chown. Just narrow and call sys_xxx.
941 ****************************************************************************/
943 int wsys_chown(const smb_ucs2_t *wfname, uid_t uid, gid_t gid)
946 return chown(unicode_to_unix(fname,wfname,sizeof(fname)), uid, gid);
949 /**************************************************************************
950 Wide chroot. Just narrow and call sys_xxx.
951 ****************************************************************************/
953 int wsys_chroot(const smb_ucs2_t *wfname)
956 return chroot(unicode_to_unix(fname,wfname,sizeof(fname)));
959 /**************************************************************************
960 Wide getpwnam. Return a structure pointer containing wide names.
961 ****************************************************************************/
963 SMB_STRUCT_WPASSWD *wsys_getpwnam(const smb_ucs2_t *wname)
965 static SMB_STRUCT_WPASSWD retval;
967 struct passwd *pwret = sys_getpwnam(unicode_to_unix(name,wname,sizeof(name)));
972 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
973 retval.pw_passwd = pwret->pw_passwd;
974 retval.pw_uid = pwret->pw_uid;
975 retval.pw_gid = pwret->pw_gid;
976 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
977 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
978 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
983 /**************************************************************************
984 Wide getpwuid. Return a structure pointer containing wide names.
985 ****************************************************************************/
987 SMB_STRUCT_WPASSWD *wsys_getpwuid(uid_t uid)
989 static SMB_STRUCT_WPASSWD retval;
990 struct passwd *pwret = sys_getpwuid(uid);
995 unix_to_unicode(retval.pw_name, pwret->pw_name, sizeof(retval.pw_name));
996 retval.pw_passwd = pwret->pw_passwd;
997 retval.pw_uid = pwret->pw_uid;
998 retval.pw_gid = pwret->pw_gid;
999 unix_to_unicode(retval.pw_gecos, pwret->pw_gecos, sizeof(retval.pw_gecos));
1000 unix_to_unicode(retval.pw_dir, pwret->pw_dir, sizeof(retval.pw_dir));
1001 unix_to_unicode(retval.pw_shell, pwret->pw_shell, sizeof(retval.pw_shell));
1005 #endif /* NOT CURRENTLY USED - JRA */
1007 /**************************************************************************
1008 Extract a command into an arg list. Uses a static pstring for storage.
1009 Caller frees returned arg list (which contains pointers into the static pstring).
1010 ****************************************************************************/
1012 static char **extract_args(const char *command)
1014 static pstring trunc_cmd;
1020 pstrcpy(trunc_cmd, command);
1022 if(!(ptr = strtok(trunc_cmd, " \t"))) {
1031 for( argcl = 1; ptr; ptr = strtok(NULL, " \t"))
1034 if((argl = (char **)malloc((argcl + 1) * sizeof(char *))) == NULL)
1038 * Now do the extraction.
1041 pstrcpy(trunc_cmd, command);
1043 ptr = strtok(trunc_cmd, " \t");
1047 while((ptr = strtok(NULL, " \t")) != NULL)
1054 /**************************************************************************
1055 Wrapper for fork. Ensures that mypid is reset. Used so we can write
1056 a sys_getpid() that only does a system call *once*.
1057 ****************************************************************************/
1059 static pid_t mypid = (pid_t)-1;
1061 pid_t sys_fork(void)
1063 pid_t forkret = fork();
1065 if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
1071 /**************************************************************************
1072 Wrapper for getpid. Ensures we only do a system call *once*.
1073 ****************************************************************************/
1075 pid_t sys_getpid(void)
1077 if (mypid == (pid_t)-1)
1083 /**************************************************************************
1084 Wrapper for popen. Safer as it doesn't search a path.
1085 Modified from the glibc sources.
1086 modified by tridge to return a file descriptor. We must kick our FILE* habit
1087 ****************************************************************************/
1089 typedef struct _popen_list
1093 struct _popen_list *next;
1096 static popen_list *popen_chain;
1098 int sys_popen(const char *command)
1100 int parent_end, child_end;
1102 popen_list *entry = NULL;
1105 if (pipe(pipe_fds) < 0)
1108 parent_end = pipe_fds[0];
1109 child_end = pipe_fds[1];
1116 if((entry = (popen_list *)malloc(sizeof(popen_list))) == NULL)
1119 ZERO_STRUCTP(entry);
1122 * Extract the command and args into a NULL terminated array.
1125 if(!(argl = extract_args(command)))
1128 entry->child_pid = sys_fork();
1130 if (entry->child_pid == -1) {
1134 if (entry->child_pid == 0) {
1140 int child_std_end = STDOUT_FILENO;
1144 if (child_end != child_std_end) {
1145 dup2 (child_end, child_std_end);
1150 * POSIX.2: "popen() shall ensure that any streams from previous
1151 * popen() calls that remain open in the parent process are closed
1152 * in the new child process."
1155 for (p = popen_chain; p; p = p->next)
1158 execv(argl[0], argl);
1169 /* Link into popen_chain. */
1170 entry->next = popen_chain;
1171 popen_chain = entry;
1172 entry->fd = parent_end;
1185 /**************************************************************************
1186 Wrapper for pclose. Modified from the glibc sources.
1187 ****************************************************************************/
1189 int sys_pclose(int fd)
1192 popen_list **ptr = &popen_chain;
1193 popen_list *entry = NULL;
1197 /* Unlink from popen_chain. */
1198 for ( ; *ptr != NULL; ptr = &(*ptr)->next) {
1199 if ((*ptr)->fd == fd) {
1201 *ptr = (*ptr)->next;
1207 if (status < 0 || close(entry->fd) < 0)
1211 * As Samba is catching and eating child process
1212 * exits we don't really care about the child exit
1213 * code, a -1 with errno = ECHILD will do fine for us.
1217 wait_pid = sys_waitpid (entry->child_pid, &wstatus, 0);
1218 } while (wait_pid == -1 && errno == EINTR);
1227 /**************************************************************************
1228 Wrappers for dlopen, dlsym, dlclose.
1229 ****************************************************************************/
1231 void *sys_dlopen(const char *name, int flags)
1233 #if defined(HAVE_DLOPEN)
1234 return dlopen(name, flags);
1240 void *sys_dlsym(void *handle, const char *symbol)
1242 #if defined(HAVE_DLSYM)
1243 return dlsym(handle, symbol);
1249 int sys_dlclose (void *handle)
1251 #if defined(HAVE_DLCLOSE)
1252 return dlclose(handle);
1258 const char *sys_dlerror(void)
1260 #if defined(HAVE_DLERROR)
1267 int sys_dup2(int oldfd, int newfd)
1269 #if defined(HAVE_DUP2)
1270 return dup2(oldfd, newfd);
1277 /**************************************************************************
1278 Wrapper for Admin Logs.
1279 ****************************************************************************/
1281 void sys_adminlog(int priority, const char *format_str, ...)
1285 char *msgbuf = NULL;
1287 va_start( ap, format_str );
1288 ret = vasprintf( &msgbuf, format_str, ap );
1294 #if defined(HAVE_SYSLOG)
1295 syslog( priority, "%s", msgbuf );
1297 DEBUG(0,("%s", msgbuf ));
1302 /**************************************************************************
1303 Wrappers for extented attribute calls. Based on the Linux package with
1304 support for IRIX also. Expand as other systems have them.
1305 ****************************************************************************/
1307 ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size)
1309 #if defined(HAVE_GETXATTR)
1310 return getxattr(path, name, value, size);
1311 #elif defined(HAVE_ATTR_GET)
1312 int retval, flags = 0;
1313 int valuelength = (int)size;
1314 char *attrname = strchr(name,'.') +1;
1316 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1318 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1320 return retval ? retval : valuelength;
1327 ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size)
1329 #if defined(HAVE_LGETXATTR)
1330 return lgetxattr(path, name, value, size);
1331 #elif defined(HAVE_ATTR_GET)
1332 int retval, flags = ATTR_DONTFOLLOW;
1333 int valuelength = (int)size;
1334 char *attrname = strchr(name,'.') +1;
1336 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1338 retval = attr_get(path, attrname, (char *)value, &valuelength, flags);
1340 return retval ? retval : valuelength;
1347 ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size)
1349 #if defined(HAVE_FGETXATTR)
1350 return fgetxattr(filedes, name, value, size);
1351 #elif defined(HAVE_ATTR_GETF)
1352 int retval, flags = 0;
1353 int valuelength = (int)size;
1354 char *attrname = strchr(name,'.') +1;
1356 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1358 retval = attr_getf(filedes, attrname, (char *)value, &valuelength, flags);
1360 return retval ? retval : valuelength;
1367 #if defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1368 static char attr_buffer[ATTR_MAX_VALUELEN];
1370 static ssize_t irix_attr_list(const char *path, int filedes, char *list, size_t size, int flags)
1372 int retval = 0, index;
1373 attrlist_cursor_t *cursor = 0;
1375 attrlist_t * al = (attrlist_t *)attr_buffer;
1377 size_t ent_size, left = size;
1382 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1384 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1386 for (index = 0; index < al->al_count; index++) {
1387 ae = ATTR_ENTRY(attr_buffer, index);
1388 ent_size = strlen(ae->a_name) + sizeof("user.");
1389 if (left >= ent_size) {
1390 strncpy(bp, "user.", sizeof("user."));
1391 strncat(bp, ae->a_name, ent_size - sizeof("user."));
1399 total_size += ent_size;
1401 if (al->al_more == 0) break;
1408 retval = attr_listf(filedes, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1410 retval = attr_list(path, attr_buffer, ATTR_MAX_VALUELEN, flags, cursor);
1412 for (index = 0; index < al->al_count; index++) {
1413 ae = ATTR_ENTRY(attr_buffer, index);
1414 ent_size = strlen(ae->a_name) + sizeof("system.");
1415 if (left >= ent_size) {
1416 strncpy(bp, "system.", sizeof("system."));
1417 strncat(bp, ae->a_name, ent_size - sizeof("system."));
1425 total_size += ent_size;
1427 if (al->al_more == 0) break;
1430 return (ssize_t)(retval ? retval : total_size);
1435 ssize_t sys_listxattr (const char *path, char *list, size_t size)
1437 #if defined(HAVE_LISTXATTR)
1438 return listxattr(path, list, size);
1439 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1440 return irix_attr_list(path, 0, list, size, 0);
1447 ssize_t sys_llistxattr (const char *path, char *list, size_t size)
1449 #if defined(HAVE_LLISTXATTR)
1450 return llistxattr(path, list, size);
1451 #elif defined(HAVE_ATTR_LIST) && defined(HAVE_SYS_ATTRIBUTES_H)
1452 return irix_attr_list(path, 0, list, size, ATTR_DONTFOLLOW);
1459 ssize_t sys_flistxattr (int filedes, char *list, size_t size)
1461 #if defined(HAVE_FLISTXATTR)
1462 return flistxattr(filedes, list, size);
1463 #elif defined(HAVE_ATTR_LISTF)
1464 return irix_attr_list(NULL, filedes, list, size, 0);
1471 int sys_removexattr (const char *path, const char *name)
1473 #if defined(HAVE_REMOVEXATTR)
1474 return removexattr(path, name);
1475 #elif defined(HAVE_ATTR_REMOVE)
1477 char *attrname = strchr(name,'.') +1;
1479 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1481 return attr_remove(path, attrname, flags);
1488 int sys_lremovexattr (const char *path, const char *name)
1490 #if defined(HAVE_LREMOVEXATTR)
1491 return lremovexattr(path, name);
1492 #elif defined(HAVE_ATTR_REMOVE)
1493 int flags = ATTR_DONTFOLLOW;
1494 char *attrname = strchr(name,'.') +1;
1496 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1498 return attr_remove(path, attrname, flags);
1505 int sys_fremovexattr (int filedes, const char *name)
1507 #if defined(HAVE_FREMOVEXATTR)
1508 return fremovexattr(filedes, name);
1509 #elif defined(HAVE_ATTR_REMOVEF)
1511 char *attrname = strchr(name,'.') +1;
1513 if (strncmp(name, "system", 6) == 0) flags |= ATTR_ROOT;
1515 return attr_removef(filedes, attrname, flags);
1522 #if !defined(HAVE_SETXATTR)
1523 #define XATTR_CREATE 0x1 /* set value, fail if attr already exists */
1524 #define XATTR_REPLACE 0x2 /* set value, fail if attr does not exist */
1527 int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1529 #if defined(HAVE_SETXATTR)
1530 return setxattr(path, name, value, size, flags);
1531 #elif defined(HAVE_ATTR_SET)
1533 char *attrname = strchr(name,'.') +1;
1535 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1536 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1537 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1539 return attr_set(path, attrname, (const char *)value, size, myflags);
1546 int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags)
1548 #if defined(HAVE_LSETXATTR)
1549 return lsetxattr(path, name, value, size, flags);
1550 #elif defined(HAVE_ATTR_SET)
1551 int myflags = ATTR_DONTFOLLOW;
1552 char *attrname = strchr(name,'.') +1;
1554 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1555 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1556 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1558 return attr_set(path, attrname, (const char *)value, size, myflags);
1565 int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags)
1567 #if defined(HAVE_FSETXATTR)
1568 return fsetxattr(filedes, name, value, size, flags);
1569 #elif defined(HAVE_ATTR_SETF)
1571 char *attrname = strchr(name,'.') +1;
1573 if (strncmp(name, "system", 6) == 0) myflags |= ATTR_ROOT;
1574 if (flags & XATTR_CREATE) myflags |= ATTR_CREATE;
1575 if (flags & XATTR_REPLACE) myflags |= ATTR_REPLACE;
1577 return attr_setf(filedes, attrname, (const char *)value, size, myflags);