1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00
samba-mirror/source3/lib/system.c
Andrew Tridgell 33a003de40 This commit does 3 main things:
1) put the encryption code in by default, with no #ifdef. It is still
disabled by default so you need to add "encrypt passwords = yes" in
smb.conf but at least all binaries will have it.

2) cleanup the kanji code so it compiles with no warnings

3) get rid of lots of uses of ugly non-portable C code. The main
offender being things like "register" but also remove uses of the
"const" keyword as there are compilers out there that don't support it
and even those that do often complain about its usage. Users don't
like warnings :-(

There is still some work to do. We need to replace the md4 code with
our own implementation. The current code (from rfc1186) is PD but is
not very portable. The new RFC (rfc1320) is more portable but adds
copyright restrictions. I'll do a from-scratch MD4 soon.

We also need to test that what I've implemented is portable. It should
be, but I'm too tired right now to test it on anything other than
intel linux.
(This used to be commit db917c62c1)
1997-09-14 16:37:18 +00:00

414 lines
10 KiB
C

/*
Unix SMB/Netbios implementation.
Version 1.9.
Samba system utilities
Copyright (C) Andrew Tridgell 1992-1997
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
extern int DEBUGLEVEL;
/*
The idea is that this file will eventually have wrappers around all
important system calls in samba. The aims are:
- to enable easier porting by putting OS dependent stuff in here
- to allow for hooks into other "pseudo-filesystems"
- to allow easier integration of things like the japanese extensions
- to support the philosophy of Samba to expose the features of
the OS within the SMB model. In general whatever file/printer/variable
expansions/etc make sense to the OS should be acceptable to Samba.
*/
/*******************************************************************
this replaces the normal select() system call
return if some data has arrived on one of the file descriptors
return -1 means error
********************************************************************/
#ifdef NO_SELECT
static int pollfd(int fd)
{
int r=0;
#ifdef HAS_RDCHK
r = rdchk(fd);
#elif defined(TCRDCHK)
(void)ioctl(fd, TCRDCHK, &r);
#else
(void)ioctl(fd, FIONREAD, &r);
#endif
return(r);
}
int sys_select(fd_set *fds,struct timeval *tval)
{
fd_set fds2;
int counter=0;
int found=0;
FD_ZERO(&fds2);
while (1)
{
int i;
for (i=0;i<255;i++) {
if (FD_ISSET(i,fds) && pollfd(i)>0) {
found++;
FD_SET(i,&fds2);
}
}
if (found) {
memcpy((void *)fds,(void *)&fds2,sizeof(fds2));
return(found);
}
if (tval && tval->tv_sec < counter) return(0);
sleep(1);
counter++;
}
}
#else
int sys_select(fd_set *fds,struct timeval *tval)
{
struct timeval t2;
int selrtn;
do {
if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
errno = 0;
selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
} while (selrtn<0 && errno == EINTR);
return(selrtn);
}
#endif
/*******************************************************************
just a unlink wrapper
********************************************************************/
int sys_unlink(char *fname)
{
return(unlink(dos_to_unix(fname,False)));
}
/*******************************************************************
a simple open() wrapper
********************************************************************/
int sys_open(char *fname,int flags,int mode)
{
return(open(dos_to_unix(fname,False),flags,mode));
}
/*******************************************************************
a simple opendir() wrapper
********************************************************************/
DIR *sys_opendir(char *dname)
{
return(opendir(dos_to_unix(dname,False)));
}
/*******************************************************************
and a stat() wrapper
********************************************************************/
int sys_stat(char *fname,struct stat *sbuf)
{
return(stat(dos_to_unix(fname,False),sbuf));
}
/*******************************************************************
The wait() calls vary between systems
********************************************************************/
int sys_waitpid(pid_t pid,int *status,int options)
{
#ifdef USE_WAITPID
return waitpid(pid,status,options);
#else /* USE_WAITPID */
return wait4(pid, status, options, NULL);
#endif /* USE_WAITPID */
}
/*******************************************************************
don't forget lstat()
********************************************************************/
int sys_lstat(char *fname,struct stat *sbuf)
{
return(lstat(dos_to_unix(fname,False),sbuf));
}
/*******************************************************************
mkdir() gets a wrapper
********************************************************************/
int sys_mkdir(char *dname,int mode)
{
return(mkdir(dos_to_unix(dname,False),mode));
}
/*******************************************************************
do does rmdir()
********************************************************************/
int sys_rmdir(char *dname)
{
return(rmdir(dos_to_unix(dname,False)));
}
/*******************************************************************
I almost forgot chdir()
********************************************************************/
int sys_chdir(char *dname)
{
return(chdir(dos_to_unix(dname,False)));
}
/*******************************************************************
now for utime()
********************************************************************/
int sys_utime(char *fname,struct utimbuf *times)
{
return(utime(dos_to_unix(fname,False),times));
}
/*********************************************************
for rename across filesystems Patch from Warren Birnbaum
<warrenb@hpcvscdp.cv.hp.com>
**********************************************************/
static int copy_reg(char *source, const char *dest)
{
struct stat source_stats;
int ifd;
int full_write();
int safe_read();
int ofd;
char *buf;
int len; /* Number of bytes read into `buf'. */
lstat (source, &source_stats);
if (!S_ISREG (source_stats.st_mode))
{
return 1;
}
if (unlink (dest) && errno != ENOENT)
{
return 1;
}
if((ifd = open (source, O_RDONLY, 0)) < 0)
{
return 1;
}
if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 )
{
close (ifd);
return 1;
}
if((buf = malloc( COPYBUF_SIZE )) == NULL)
{
close (ifd);
close (ofd);
unlink (dest);
return 1;
}
while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0)
{
if (write_data(ofd, buf, len) < 0)
{
close (ifd);
close (ofd);
unlink (dest);
free(buf);
return 1;
}
}
free(buf);
if (len < 0)
{
close (ifd);
close (ofd);
unlink (dest);
return 1;
}
if (close (ifd) < 0)
{
close (ofd);
return 1;
}
if (close (ofd) < 0)
{
return 1;
}
/* chown turns off set[ug]id bits for non-root,
so do the chmod last. */
/* Try to copy the old file's modtime and access time. */
{
struct utimbuf tv;
tv.actime = source_stats.st_atime;
tv.modtime = source_stats.st_mtime;
if (utime (dest, &tv))
{
return 1;
}
}
/* Try to preserve ownership. For non-root it might fail, but that's ok.
But root probably wants to know, e.g. if NFS disallows it. */
if (chown (dest, source_stats.st_uid, source_stats.st_gid)
&& (errno != EPERM))
{
return 1;
}
if (chmod (dest, source_stats.st_mode & 07777))
{
return 1;
}
unlink (source);
return 0;
}
/*******************************************************************
for rename()
********************************************************************/
int sys_rename(char *from, char *to)
{
int rcode;
pstring zfrom, zto;
strcpy (zfrom, dos_to_unix (from, False));
strcpy (zto, dos_to_unix (to, False));
rcode = rename (zfrom, zto);
if (errno == EXDEV)
{
/* Rename across filesystems needed. */
rcode = copy_reg (zfrom, zto);
}
return rcode;
}
/*******************************************************************
for chmod
********************************************************************/
int sys_chmod(char *fname,int mode)
{
return(chmod(dos_to_unix(fname,False),mode));
}
/*******************************************************************
for getwd
********************************************************************/
char *sys_getwd(char *s)
{
char *wd;
#ifdef USE_GETCWD
wd = (char *) getcwd (s, sizeof (pstring));
#else
wd = (char *) getwd (s);
#endif
if (wd)
unix_to_dos (wd, True);
return wd;
}
/*******************************************************************
chown isn't used much but OS/2 doesn't have it
********************************************************************/
int sys_chown(char *fname,int uid,int gid)
{
#ifdef NO_CHOWN
DEBUG(1,("Warning - chown(%s,%d,%d) not done\n",fname,uid,gid));
#else
return(chown(fname,uid,gid));
#endif
}
/*******************************************************************
os/2 also doesn't have chroot
********************************************************************/
int sys_chroot(char *dname)
{
#ifdef NO_CHROOT
DEBUG(1,("Warning - chroot(%s) not done\n",dname));
#else
return(chroot(dname));
#endif
}
/**************************************************************************
A wrapper for gethostbyname() that tries avoids looking up hostnames
in the root domain, which can cause dial-on-demand links to come up for no
apparent reason.
****************************************************************************/
struct hostent *sys_gethostbyname(char *name)
{
#ifdef REDUCE_ROOT_DNS_LOOKUPS
char query[256], hostname[256];
char *domain;
/* Does this name have any dots in it? If so, make no change */
if (strchr(name, '.'))
return(gethostbyname(name));
/* Get my hostname, which should have domain name
attached. If not, just do the gethostname on the
original string.
*/
gethostname(hostname, sizeof(hostname) - 1);
hostname[sizeof(hostname) - 1] = 0;
if ((domain = strchr(hostname, '.')) == NULL)
return(gethostbyname(name));
/* Attach domain name to query and do modified query.
If names too large, just do gethostname on the
original string.
*/
if((strlen(name) + strlen(domain)) >= sizeof(query))
return(gethostbyname(name));
sprintf(query, "%s%s", name, domain);
return(gethostbyname(query));
#else /* REDUCE_ROOT_DNS_LOOKUPS */
return(gethostbyname(name));
#endif /* REDUCE_ROOT_DNS_LOOKUPS */
}