2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
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.
24 extern int DEBUGLEVEL
;
27 The idea is that this file will eventually have wrappers around all
28 important system calls in samba. The aims are:
30 - to enable easier porting by putting OS dependent stuff in here
32 - to allow for hooks into other "pseudo-filesystems"
34 - to allow easier integration of things like the japanese extensions
36 - to support the philosophy of Samba to expose the features of
37 the OS within the SMB model. In general whatever file/printer/variable
38 expansions/etc make sense to the OS should be acceptable to Samba.
42 /*******************************************************************
43 this replaces the normal select() system call
44 return if some data has arrived on one of the file descriptors
46 ********************************************************************/
48 static int pollfd(int fd
)
54 #elif defined(TCRDCHK)
55 (void)ioctl(fd
, TCRDCHK
, &r
);
57 (void)ioctl(fd
, FIONREAD
, &r
);
63 int sys_select(int maxfd
, fd_set
*fds
,struct timeval
*tval
)
74 for (i
=0;i
<maxfd
;i
++) {
75 if (FD_ISSET(i
,fds
) && pollfd(i
)>0) {
82 memcpy((void *)fds
,(void *)&fds2
,sizeof(fds2
));
86 if (tval
&& tval
->tv_sec
< counter
) return(0);
92 #else /* !NO_SELECT */
93 int sys_select(int maxfd
, fd_set
*fds
,struct timeval
*tval
)
96 struct pollfd pfd
[256];
103 for( i
= 0; i
< maxfd
; i
++) {
104 if(FD_ISSET(i
,fds
)) {
105 struct pollfd
*pfdp
= &pfd
[maxpoll
++];
107 pfdp
->events
= POLLIN
;
112 timeout
= (tval
!= NULL
) ? (tval
->tv_sec
* 1000) + (tval
->tv_usec
/1000) :
116 pollrtn
= poll( &pfd
[0], maxpoll
, timeout
);
117 } while (pollrtn
<0 && errno
== EINTR
);
121 for( i
= 0; i
< maxpoll
; i
++)
122 if( pfd
[i
].revents
& POLLIN
)
123 FD_SET(pfd
[i
].fd
,fds
);
132 if (tval
) memcpy((void *)&t2
,(void *)tval
,sizeof(t2
));
134 selrtn
= select(maxfd
,SELECT_CAST fds
,NULL
,NULL
,tval
?&t2
:NULL
);
135 } while (selrtn
<0 && errno
== EINTR
);
139 #endif /* USE_POLL */
140 #endif /* NO_SELECT */
142 /*******************************************************************
143 A stat() wrapper that will deal with 64 bit filesizes.
144 ********************************************************************/
146 int sys_stat(char *fname
,SMB_STRUCT_STAT
*sbuf
)
148 #if defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
149 return stat64(fname
, sbuf
);
151 return stat(fname
, sbuf
);
155 /*******************************************************************
156 An fstat() wrapper that will deal with 64 bit filesizes.
157 ********************************************************************/
159 int sys_fstat(int fd
,SMB_STRUCT_STAT
*sbuf
)
161 #if defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
162 return fstat64(fd
, sbuf
);
164 return fstat(fd
, sbuf
);
168 /*******************************************************************
169 An lstat() wrapper that will deal with 64 bit filesizes.
170 ********************************************************************/
172 int sys_lstat(char *fname
,SMB_STRUCT_STAT
*sbuf
)
174 #if defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
175 return lstat64(fname
, sbuf
);
177 return lstat(fname
, sbuf
);
181 /*******************************************************************
182 An ftruncate() wrapper that will deal with 64 bit filesizes.
183 ********************************************************************/
185 int sys_ftruncate(int fd
, SMB_OFF_T offset
)
187 #if defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
188 return ftruncate64(fd
, offset
);
190 return ftruncate(fd
, offset
);
194 /*******************************************************************
195 An lseek() wrapper that will deal with 64 bit filesizes.
196 ********************************************************************/
198 SMB_OFF_T
sys_lseek(int fd
, SMB_OFF_T offset
, int whence
)
200 #if defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
201 return lseek64(fd
, offset
, whence
);
203 return lseek(fd
, offset
, whence
);
207 /*******************************************************************
208 An fseek() wrapper that will deal with 64 bit filesizes.
209 ********************************************************************/
211 int sys_fseek(FILE *fp
, SMB_OFF_T offset
, int whence
)
213 #if defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
214 return fseek64(fp
, offset
, whence
);
216 return fseek(fp
, offset
, whence
);
220 /*******************************************************************
221 An ftell() wrapper that will deal with 64 bit filesizes.
222 ********************************************************************/
224 SMB_OFF_T
sys_ftell(FILE *fp
)
226 #if defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
227 return (SMB_OFF_T
)ftell64(fp
);
229 return (SMB_OFF_T
)ftell(fp
);
233 /*******************************************************************
234 just a unlink wrapper that calls dos_to_unix.
235 ********************************************************************/
236 int dos_unlink(char *fname
)
238 return(unlink(dos_to_unix(fname
,False
)));
242 /*******************************************************************
243 a simple open() wrapper that calls dos_to_unix.
244 ********************************************************************/
245 int dos_open(char *fname
,int flags
,mode_t mode
)
247 return(open(dos_to_unix(fname
,False
),flags
,mode
));
251 /*******************************************************************
252 a simple opendir() wrapper that calls dos_to_unix
253 ********************************************************************/
254 DIR *dos_opendir(char *dname
)
256 return(opendir(dos_to_unix(dname
,False
)));
259 /*******************************************************************
260 and a stat() wrapper that calls dos_to_unix.
261 ********************************************************************/
262 int dos_stat(char *fname
,SMB_STRUCT_STAT
*sbuf
)
264 return(sys_stat(dos_to_unix(fname
,False
),sbuf
));
267 /*******************************************************************
268 The wait() calls vary between systems
269 ********************************************************************/
270 int sys_waitpid(pid_t pid
,int *status
,int options
)
273 return waitpid(pid
,status
,options
);
274 #else /* HAVE_WAITPID */
275 return wait4(pid
, status
, options
, NULL
);
276 #endif /* HAVE_WAITPID */
279 /*******************************************************************
280 don't forget lstat() that calls dos_to_unix.
281 ********************************************************************/
282 int dos_lstat(char *fname
,SMB_STRUCT_STAT
*sbuf
)
284 return(sys_lstat(dos_to_unix(fname
,False
),sbuf
));
287 /*******************************************************************
288 mkdir() gets a wrapper that calls dos_to_unix.
289 ********************************************************************/
290 int dos_mkdir(char *dname
,mode_t mode
)
292 return(mkdir(dos_to_unix(dname
,False
),mode
));
295 /*******************************************************************
296 do does rmdir() - call dos_to_unix
297 ********************************************************************/
298 int dos_rmdir(char *dname
)
300 return(rmdir(dos_to_unix(dname
,False
)));
303 /*******************************************************************
304 I almost forgot chdir() - call dos_to_unix.
305 ********************************************************************/
306 int dos_chdir(char *dname
)
308 return(chdir(dos_to_unix(dname
,False
)));
311 /*******************************************************************
312 now for utime() - call dos_to_unix.
313 ********************************************************************/
314 int dos_utime(char *fname
,struct utimbuf
*times
)
316 /* if the modtime is 0 or -1 then ignore the call and
318 if (times
->modtime
== (time_t)0 || times
->modtime
== (time_t)-1)
321 /* if the access time is 0 or -1 then set it to the modtime */
322 if (times
->actime
== (time_t)0 || times
->actime
== (time_t)-1)
323 times
->actime
= times
->modtime
;
325 return(utime(dos_to_unix(fname
,False
),times
));
328 /*********************************************************
329 for rename across filesystems Patch from Warren Birnbaum
330 <warrenb@hpcvscdp.cv.hp.com>
331 **********************************************************/
333 static int copy_reg(char *source
, const char *dest
)
335 SMB_STRUCT_STAT source_stats
;
339 int len
; /* Number of bytes read into `buf'. */
341 sys_lstat (source
, &source_stats
);
342 if (!S_ISREG (source_stats
.st_mode
))
345 if (unlink (dest
) && errno
!= ENOENT
)
348 if((ifd
= open (source
, O_RDONLY
, 0)) < 0)
351 if((ofd
= open (dest
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0600)) < 0 )
357 if((buf
= malloc( COPYBUF_SIZE
)) == NULL
)
365 while ((len
= read(ifd
, buf
, COPYBUF_SIZE
)) > 0)
367 if (write_data(ofd
, buf
, len
) < 0)
393 /* chown turns off set[ug]id bits for non-root,
394 so do the chmod last. */
396 /* Try to copy the old file's modtime and access time. */
400 tv
.actime
= source_stats
.st_atime
;
401 tv
.modtime
= source_stats
.st_mtime
;
402 if (utime (dest
, &tv
))
406 /* Try to preserve ownership. For non-root it might fail, but that's ok.
407 But root probably wants to know, e.g. if NFS disallows it. */
408 if (chown (dest
, source_stats
.st_uid
, source_stats
.st_gid
)
412 if (chmod (dest
, source_stats
.st_mode
& 07777))
419 /*******************************************************************
420 for rename() - call dos_to_unix.
421 ********************************************************************/
422 int dos_rename(char *from
, char *to
)
427 pstrcpy (zfrom
, dos_to_unix (from
, False
));
428 pstrcpy (zto
, dos_to_unix (to
, False
));
429 rcode
= rename (zfrom
, zto
);
433 /* Rename across filesystems needed. */
434 rcode
= copy_reg (zfrom
, zto
);
439 /*******************************************************************
440 for chmod - call dos_to_unix.
441 ********************************************************************/
442 int dos_chmod(char *fname
,mode_t mode
)
444 return(chmod(dos_to_unix(fname
,False
),mode
));
447 /*******************************************************************
448 for getwd - takes a UNIX directory name and returns the name
450 ********************************************************************/
451 char *dos_getwd(char *s
)
455 wd
= (char *)getcwd(s
, sizeof (pstring
));
457 wd
= (char *)getwd(s
);
460 unix_to_dos(wd
, True
);
464 /*******************************************************************
465 chown isn't used much but OS/2 doesn't have it
466 ********************************************************************/
467 int sys_chown(char *fname
,int uid
,int gid
)
472 DEBUG(1,("WARNING: no chown!\n"));
476 return(chown(fname
,uid
,gid
));
480 /*******************************************************************
481 os/2 also doesn't have chroot
482 ********************************************************************/
483 int sys_chroot(char *dname
)
488 DEBUG(1,("WARNING: no chroot!\n"));
492 return(chroot(dname
));
496 /**************************************************************************
497 A wrapper for gethostbyname() that tries avoids looking up hostnames
498 in the root domain, which can cause dial-on-demand links to come up for no
500 ****************************************************************************/
501 struct hostent
*sys_gethostbyname(char *name
)
503 #ifdef REDUCE_ROOT_DNS_LOOKUPS
504 char query
[256], hostname
[256];
507 /* Does this name have any dots in it? If so, make no change */
509 if (strchr(name
, '.'))
510 return(gethostbyname(name
));
512 /* Get my hostname, which should have domain name
513 attached. If not, just do the gethostname on the
517 gethostname(hostname
, sizeof(hostname
) - 1);
518 hostname
[sizeof(hostname
) - 1] = 0;
519 if ((domain
= strchr(hostname
, '.')) == NULL
)
520 return(gethostbyname(name
));
522 /* Attach domain name to query and do modified query.
523 If names too large, just do gethostname on the
527 if((strlen(name
) + strlen(domain
)) >= sizeof(query
))
528 return(gethostbyname(name
));
530 slprintf(query
, sizeof(query
)-1, "%s%s", name
, domain
);
531 return(gethostbyname(query
));
532 #else /* REDUCE_ROOT_DNS_LOOKUPS */
533 return(gethostbyname(name
));
534 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
538 /**************************************************************************
539 Try and abstract process capabilities (for systems that have them).
540 ****************************************************************************/
542 BOOL
set_process_capability( uint32 cap_flag
, BOOL enable
)
544 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
545 if(cap_flag
== KERNEL_OPLOCK_CAPABILITY
)
547 cap_t cap
= cap_get_proc();
550 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
556 cap
->cap_effective
|= CAP_NETWORK_MGT
;
558 cap
->cap_effective
&= ~CAP_NETWORK_MGT
;
560 if (cap_set_proc(cap
) == -1) {
561 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
566 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
572 /**************************************************************************
573 Try and abstract inherited process capabilities (for systems that have them).
574 ****************************************************************************/
576 BOOL
set_inherited_process_capability( uint32 cap_flag
, BOOL enable
)
578 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
579 if(cap_flag
== KERNEL_OPLOCK_CAPABILITY
)
581 cap_t cap
= cap_get_proc();
584 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
590 cap
->cap_inheritable
|= CAP_NETWORK_MGT
;
592 cap
->cap_inheritable
&= ~CAP_NETWORK_MGT
;
594 if (cap_set_proc(cap
) == -1) {
595 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
600 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
606 /**************************************************************************
607 Wrapper for random().
608 ****************************************************************************/
610 long sys_random(void)
612 #if defined(HAVE_RANDOM)
613 return (long)random();
614 #elif defined(HAVE_RAND)
617 DEBUG(0,("Error - no random function available !\n"));
622 /**************************************************************************
623 Wrapper for srandom().
624 ****************************************************************************/
626 void sys_srandom(unsigned int seed
)
628 #if defined(HAVE_SRANDOM)
630 #elif defined(HAVE_SRAND)
633 DEBUG(0,("Error - no srandom function available !\n"));