home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1998 July & August / Pcwk78a98.iso / Wtestowe / Clico / UNIX / SAMBA / SOURCE / SAMBA.TAR / samba-1.9.17 / source / system.c < prev    next >
C/C++ Source or Header  |  1997-08-25  |  10KB  |  415 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    Samba system utilities
  5.    Copyright (C) Andrew Tridgell 1992-1997
  6.    
  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.
  11.    
  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.
  16.    
  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.
  20. */
  21.  
  22. #include "includes.h"
  23.  
  24. extern int DEBUGLEVEL;
  25.  
  26. /*
  27.    The idea is that this file will eventually have wrappers around all
  28.    important system calls in samba. The aims are:
  29.  
  30.    - to enable easier porting by putting OS dependent stuff in here
  31.  
  32.    - to allow for hooks into other "pseudo-filesystems"
  33.  
  34.    - to allow easier integration of things like the japanese extensions
  35.  
  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.
  39. */
  40.  
  41.  
  42. /*******************************************************************
  43. this replaces the normal select() system call
  44. return if some data has arrived on one of the file descriptors
  45. return -1 means error
  46. ********************************************************************/
  47. #ifdef NO_SELECT
  48. static int pollfd(int fd)
  49. {
  50.   int     r=0;
  51.  
  52. #ifdef HAS_RDCHK
  53.   r = rdchk(fd);
  54. #elif defined(TCRDCHK)
  55.   (void)ioctl(fd, TCRDCHK, &r);
  56. #else
  57.   (void)ioctl(fd, FIONREAD, &r);
  58. #endif
  59.  
  60.   return(r);
  61. }
  62.  
  63. int sys_select(fd_set *fds,struct timeval *tval)
  64. {
  65.   fd_set fds2;
  66.   int counter=0;
  67.   int found=0;
  68.  
  69.   FD_ZERO(&fds2);
  70.  
  71.   while (1) 
  72.     {
  73.       int i;
  74.       for (i=0;i<255;i++) {
  75.     if (FD_ISSET(i,fds) && pollfd(i)>0) {
  76.       found++;
  77.       FD_SET(i,&fds2);
  78.     }
  79.       }
  80.  
  81.       if (found) {
  82.     memcpy((void *)fds,(void *)&fds2,sizeof(fds2));
  83.     return(found);
  84.       }
  85.       
  86.       if (tval && tval->tv_sec < counter) return(0);
  87.       sleep(1);
  88.       counter++;
  89.     }
  90. }
  91.  
  92. #else
  93. int sys_select(fd_set *fds,struct timeval *tval)
  94. {
  95.   struct timeval t2;
  96.   int selrtn;
  97.  
  98.   do {
  99.     if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
  100.     errno = 0;
  101.     selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
  102.   } while (selrtn<0 && errno == EINTR);
  103.  
  104.   return(selrtn);
  105. }
  106. #endif
  107.  
  108.  
  109. /*******************************************************************
  110. just a unlink wrapper
  111. ********************************************************************/
  112. int sys_unlink(char *fname)
  113. {
  114.   return(unlink(dos_to_unix(fname,False)));
  115. }
  116.  
  117.  
  118. /*******************************************************************
  119. a simple open() wrapper
  120. ********************************************************************/
  121. int sys_open(char *fname,int flags,int mode)
  122. {
  123.   return(open(dos_to_unix(fname,False),flags,mode));
  124. }
  125.  
  126.  
  127. /*******************************************************************
  128. a simple opendir() wrapper
  129. ********************************************************************/
  130. DIR *sys_opendir(char *dname)
  131. {
  132.   return(opendir(dos_to_unix(dname,False)));
  133. }
  134.  
  135.  
  136. /*******************************************************************
  137. and a stat() wrapper
  138. ********************************************************************/
  139. int sys_stat(char *fname,struct stat *sbuf)
  140. {
  141.   return(stat(dos_to_unix(fname,False),sbuf));
  142. }
  143.  
  144. /*******************************************************************
  145. The wait() calls vary between systems
  146. ********************************************************************/
  147. int sys_waitpid(pid_t pid,int *status,int options)
  148. {
  149. #ifdef USE_WAITPID
  150.   return waitpid(pid,status,options);
  151. #else /* USE_WAITPID */
  152.   return wait4(pid, status, options, NULL);
  153. #endif /* USE_WAITPID */
  154. }
  155.  
  156. /*******************************************************************
  157. don't forget lstat()
  158. ********************************************************************/
  159. int sys_lstat(char *fname,struct stat *sbuf)
  160. {
  161.   return(lstat(dos_to_unix(fname,False),sbuf));
  162. }
  163.  
  164.  
  165. /*******************************************************************
  166. mkdir() gets a wrapper
  167. ********************************************************************/
  168. int sys_mkdir(char *dname,int mode)
  169. {
  170.   return(mkdir(dos_to_unix(dname,False),mode));
  171. }
  172.  
  173.  
  174. /*******************************************************************
  175. do does rmdir()
  176. ********************************************************************/
  177. int sys_rmdir(char *dname)
  178. {
  179.   return(rmdir(dos_to_unix(dname,False)));
  180. }
  181.  
  182.  
  183. /*******************************************************************
  184. I almost forgot chdir()
  185. ********************************************************************/
  186. int sys_chdir(char *dname)
  187. {
  188.   return(chdir(dos_to_unix(dname,False)));
  189. }
  190.  
  191.  
  192. /*******************************************************************
  193. now for utime()
  194. ********************************************************************/
  195. int sys_utime(char *fname,struct utimbuf *times)
  196. {
  197.   return(utime(dos_to_unix(fname,False),times));
  198. }
  199.  
  200. /*********************************************************
  201. for rename across filesystems Patch from Warren Birnbaum 
  202. <warrenb@hpcvscdp.cv.hp.com>
  203. **********************************************************/
  204.  
  205. static int
  206. copy_reg (const char *source, const char *dest)
  207. {
  208.   struct stat source_stats;
  209.   int ifd;
  210.   int full_write();
  211.   int safe_read();
  212.   int ofd;
  213.   char *buf;
  214.   int len;                      /* Number of bytes read into `buf'. */
  215.  
  216.   lstat (source, &source_stats);
  217.   if (!S_ISREG (source_stats.st_mode))
  218.     {
  219.       return 1;
  220.     }
  221.  
  222.   if (unlink (dest) && errno != ENOENT)
  223.     {
  224.       return 1;
  225.     }
  226.  
  227.   if((ifd = open (source, O_RDONLY, 0)) < 0)
  228.     {
  229.       return 1;
  230.     }
  231.   if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 )
  232.     {
  233.       close (ifd);
  234.       return 1;
  235.     }
  236.  
  237.   if((buf = malloc( COPYBUF_SIZE )) == NULL)
  238.     {
  239.       close (ifd);  
  240.       close (ofd);  
  241.       unlink (dest);
  242.       return 1;
  243.     }
  244.  
  245.   while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0)
  246.     {
  247.       if (write_data(ofd, buf, len) < 0)
  248.         {
  249.           close (ifd);
  250.           close (ofd);
  251.           unlink (dest);
  252.           free(buf);
  253.           return 1;
  254.         }
  255.     }
  256.   free(buf);
  257.   if (len < 0)
  258.     {
  259.       close (ifd);
  260.       close (ofd);
  261.       unlink (dest);
  262.       return 1;
  263.     }
  264.  
  265.   if (close (ifd) < 0)
  266.     {
  267.       close (ofd);
  268.       return 1;
  269.     }
  270.   if (close (ofd) < 0)
  271.     {
  272.       return 1;
  273.     }
  274.  
  275.   /* chown turns off set[ug]id bits for non-root,
  276.      so do the chmod last.  */
  277.  
  278.   /* Try to copy the old file's modtime and access time.  */
  279.   {
  280.     struct utimbuf tv;
  281.  
  282.     tv.actime = source_stats.st_atime;
  283.     tv.modtime = source_stats.st_mtime;
  284.     if (utime (dest, &tv))
  285.       {
  286.         return 1;
  287.       }
  288.   }
  289.  
  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)
  293.       && (errno != EPERM))
  294.     {
  295.       return 1;
  296.     }
  297.  
  298.   if (chmod (dest, source_stats.st_mode & 07777))
  299.     {
  300.       return 1;
  301.     }
  302.   unlink (source);
  303.   return 0;
  304. }
  305.  
  306. /*******************************************************************
  307. for rename()
  308. ********************************************************************/
  309. int sys_rename(char *from, char *to)
  310. {
  311.     int rcode;  
  312.     pstring zfrom, zto;
  313.  
  314.     strcpy (zfrom, dos_to_unix (from, False));
  315.     strcpy (zto, dos_to_unix (to, False));
  316.     rcode = rename (zfrom, zto);
  317.  
  318.     if (errno == EXDEV) 
  319.       {
  320.         /* Rename across filesystems needed. */
  321.         rcode = copy_reg (zfrom, zto);        
  322.       }
  323.     return rcode;
  324. }
  325.  
  326. /*******************************************************************
  327. for chmod
  328. ********************************************************************/
  329. int sys_chmod(char *fname,int mode)
  330. {
  331.   return(chmod(dos_to_unix(fname,False),mode));
  332. }
  333.  
  334. /*******************************************************************
  335. for getwd
  336. ********************************************************************/
  337. char *sys_getwd(char *s)
  338. {
  339.   char *wd;
  340. #ifdef USE_GETCWD
  341.   wd = (char *) getcwd (s, sizeof (pstring));
  342. #else
  343.   wd = (char *) getwd (s);
  344. #endif
  345.   if (wd)
  346.     unix_to_dos (wd, True);
  347.   return wd;
  348. }
  349.  
  350. /*******************************************************************
  351. chown isn't used much but OS/2 doesn't have it
  352. ********************************************************************/
  353. int sys_chown(char *fname,int uid,int gid)
  354. {
  355. #ifdef NO_CHOWN
  356.   DEBUG(1,("Warning - chown(%s,%d,%d) not done\n",fname,uid,gid));
  357. #else
  358.   return(chown(fname,uid,gid));
  359. #endif
  360. }
  361.  
  362. /*******************************************************************
  363. os/2 also doesn't have chroot
  364. ********************************************************************/
  365. int sys_chroot(char *dname)
  366. {
  367. #ifdef NO_CHROOT
  368.   DEBUG(1,("Warning - chroot(%s) not done\n",dname));
  369. #else
  370.   return(chroot(dname));
  371. #endif
  372. }
  373.  
  374. /**************************************************************************
  375. A wrapper for gethostbyname() that tries avoids looking up hostnames 
  376. in the root domain, which can cause dial-on-demand links to come up for no
  377. apparent reason.
  378. ****************************************************************************/
  379. struct hostent *sys_gethostbyname(char *name)
  380. {
  381. #ifdef REDUCE_ROOT_DNS_LOOKUPS
  382.   char query[256], hostname[256];
  383.   char *domain;
  384.  
  385.   /* Does this name have any dots in it? If so, make no change */
  386.  
  387.   if (strchr(name, '.'))
  388.     return(gethostbyname(name));
  389.  
  390.   /* Get my hostname, which should have domain name 
  391.      attached. If not, just do the gethostname on the
  392.      original string. 
  393.   */
  394.  
  395.   gethostname(hostname, sizeof(hostname) - 1);
  396.   hostname[sizeof(hostname) - 1] = 0;
  397.   if ((domain = strchr(hostname, '.')) == NULL)
  398.     return(gethostbyname(name));
  399.  
  400.   /* Attach domain name to query and do modified query.
  401.      If names too large, just do gethostname on the
  402.      original string.
  403.   */
  404.  
  405.   if((strlen(name) + strlen(domain)) >= sizeof(query))
  406.     return(gethostbyname(name));
  407.  
  408.   sprintf(query, "%s%s", name, domain);
  409.   return(gethostbyname(query));
  410. #else /* REDUCE_ROOT_DNS_LOOKUPS */
  411.   return(gethostbyname(name));
  412. #endif /* REDUCE_ROOT_DNS_LOOKUPS */
  413. }
  414.  
  415.