2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1997
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(fd_set
*fds
,struct timeval
*tval
)
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);
93 int sys_select(fd_set
*fds
,struct timeval
*tval
)
99 if (tval
) memcpy((void *)&t2
,(void *)tval
,sizeof(t2
));
101 selrtn
= select(255,SELECT_CAST fds
,NULL
,NULL
,tval
?&t2
:NULL
);
102 } while (selrtn
<0 && errno
== EINTR
);
109 /*******************************************************************
110 just a unlink wrapper
111 ********************************************************************/
112 int sys_unlink(char *fname
)
114 return(unlink(dos_to_unix(fname
,False
)));
118 /*******************************************************************
119 a simple open() wrapper
120 ********************************************************************/
121 int sys_open(char *fname
,int flags
,int mode
)
123 return(open(dos_to_unix(fname
,False
),flags
,mode
));
127 /*******************************************************************
128 a simple opendir() wrapper
129 ********************************************************************/
130 DIR *sys_opendir(char *dname
)
132 return(opendir(dos_to_unix(dname
,False
)));
136 /*******************************************************************
138 ********************************************************************/
139 int sys_stat(char *fname
,struct stat
*sbuf
)
141 return(stat(dos_to_unix(fname
,False
),sbuf
));
144 /*******************************************************************
145 The wait() calls vary between systems
146 ********************************************************************/
147 int sys_waitpid(pid_t pid
,int *status
,int options
)
150 return waitpid(pid
,status
,options
);
151 #else /* USE_WAITPID */
152 return wait4(pid
, status
, options
, NULL
);
153 #endif /* USE_WAITPID */
156 /*******************************************************************
158 ********************************************************************/
159 int sys_lstat(char *fname
,struct stat
*sbuf
)
161 return(lstat(dos_to_unix(fname
,False
),sbuf
));
165 /*******************************************************************
166 mkdir() gets a wrapper
167 ********************************************************************/
168 int sys_mkdir(char *dname
,int mode
)
170 return(mkdir(dos_to_unix(dname
,False
),mode
));
174 /*******************************************************************
176 ********************************************************************/
177 int sys_rmdir(char *dname
)
179 return(rmdir(dos_to_unix(dname
,False
)));
183 /*******************************************************************
184 I almost forgot chdir()
185 ********************************************************************/
186 int sys_chdir(char *dname
)
188 return(chdir(dos_to_unix(dname
,False
)));
192 /*******************************************************************
194 ********************************************************************/
195 int sys_utime(char *fname
,struct utimbuf
*times
)
197 return(utime(dos_to_unix(fname
,False
),times
));
200 /*********************************************************
201 for rename across filesystems Patch from Warren Birnbaum
202 <warrenb@hpcvscdp.cv.hp.com>
203 **********************************************************/
206 copy_reg (const char *source
, const char *dest
)
208 struct stat source_stats
;
214 int len
; /* Number of bytes read into `buf'. */
216 lstat (source
, &source_stats
);
217 if (!S_ISREG (source_stats
.st_mode
))
222 if (unlink (dest
) && errno
!= ENOENT
)
227 if((ifd
= open (source
, O_RDONLY
, 0)) < 0)
231 if((ofd
= open (dest
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0600)) < 0 )
237 if((buf
= malloc( COPYBUF_SIZE
)) == NULL
)
245 while ((len
= read(ifd
, buf
, COPYBUF_SIZE
)) > 0)
247 if (write_data(ofd
, buf
, len
) < 0)
275 /* chown turns off set[ug]id bits for non-root,
276 so do the chmod last. */
278 /* Try to copy the old file's modtime and access time. */
282 tv
.actime
= source_stats
.st_atime
;
283 tv
.modtime
= source_stats
.st_mtime
;
284 if (utime (dest
, &tv
))
290 /* Try to preserve ownership. For non-root it might fail, but that's ok.
291 But root probably wants to know, e.g. if NFS disallows it. */
292 if (chown (dest
, source_stats
.st_uid
, source_stats
.st_gid
)
298 if (chmod (dest
, source_stats
.st_mode
& 07777))
306 /*******************************************************************
308 ********************************************************************/
309 int sys_rename(char *from
, char *to
)
314 strcpy (zfrom
, dos_to_unix (from
, False
));
315 strcpy (zto
, dos_to_unix (to
, False
));
316 rcode
= rename (zfrom
, zto
);
320 /* Rename across filesystems needed. */
321 rcode
= copy_reg (zfrom
, zto
);
326 /*******************************************************************
328 ********************************************************************/
329 int sys_chmod(char *fname
,int mode
)
331 return(chmod(dos_to_unix(fname
,False
),mode
));
334 /*******************************************************************
335 chown isn't used much but OS/2 doesn't have it
336 ********************************************************************/
337 int sys_chown(char *fname
,int uid
,int gid
)
340 DEBUG(1,("Warning - chown(%s,%d,%d) not done\n",fname
,uid
,gid
));
342 return(chown(fname
,uid
,gid
));
346 /*******************************************************************
347 os/2 also doesn't have chroot
348 ********************************************************************/
349 int sys_chroot(char *dname
)
352 DEBUG(1,("Warning - chroot(%s) not done\n",dname
));
354 return(chroot(dname
));
358 /**************************************************************************
359 A wrapper for gethostbyname() that tries avoids looking up hostnames
360 in the root domain, which can cause dial-on-demand links to come up for no
362 ****************************************************************************/
363 struct hostent
*sys_gethostbyname(char *name
)
365 char query
[256], hostname
[256];
368 /* Does this name have any dots in it? If so, make no change */
370 if (strchr(name
, '.'))
371 return(gethostbyname(name
));
373 /* Get my hostname, which should have domain name
374 attached. If not, just do the gethostname on the
378 gethostname(hostname
, sizeof(hostname
) - 1);
379 hostname
[sizeof(hostname
) - 1] = 0;
380 if ((domain
= strchr(hostname
, '.')) == NULL
)
381 return(gethostbyname(name
));
383 /* Attach domain name to query and do modified query.
384 If names too large, just do gethostname on the
388 if((strlen(name
) + strlen(domain
)) >= sizeof(query
))
389 return(gethostbyname(name
));
391 sprintf(query
, "%s%s", name
, domain
);
392 return(gethostbyname(query
));