Changes to allow Samba to be compiled with -Wstrict-prototypes
[nivanova/samba-autobuild/.git] / source3 / lib / system.c
index 7dc585223a13bff01e148a33ea6daecf2b41c51c..3eef8e5034c257aeec2980427112b89de68afeef 100644 (file)
@@ -2,7 +2,7 @@
    Unix SMB/Netbios implementation.
    Version 1.9.
    Samba system utilities
-   Copyright (C) Andrew Tridgell 1992-1995
+   Copyright (C) Andrew Tridgell 1992-1998
    
    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
@@ -98,7 +98,7 @@ int sys_select(fd_set *fds,struct timeval *tval)
   do {
     if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
     errno = 0;
-    selrtn = select(16,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
+    selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
   } while (selrtn<0 && errno == EINTR);
 
   return(selrtn);
@@ -141,6 +141,18 @@ 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()
 ********************************************************************/
@@ -182,24 +194,164 @@ now for utime()
 ********************************************************************/
 int sys_utime(char *fname,struct utimbuf *times)
 {
+  /* if the modtime is 0 or -1 then ignore the call and
+     return success */
+  if (times->modtime == (time_t)0 || times->modtime == (time_t)-1)
+    return 0;
+  
+  /* if the access time is 0 or -1 then set it to the modtime */
+  if (times->actime == (time_t)0 || times->actime == (time_t)-1)
+    times->actime = times->modtime;
+   
   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 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)
 {
-#ifdef KANJI
+    int rcode;  
     pstring zfrom, zto;
-    strcpy (zfrom, dos_to_unix (from, False));
-    strcpy (zto, dos_to_unix (to, False));
-    return rename (zfrom, zto);
-#else 
-    return rename (from, to);
-#endif /* KANJI */
+
+    pstrcpy (zfrom, dos_to_unix (from, False));
+    pstrcpy (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
@@ -224,3 +376,45 @@ int sys_chroot(char *dname)
   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 */
+}
+