home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Linux / Divers / samba-1.9.18p7.tar.gz / samba-1.9.18p7.tar / samba-1.9.18p7 / source / system.c < prev    next >
C/C++ Source or Header  |  1998-05-11  |  11KB  |  421 lines

  1. /* 
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    Samba system utilities
  5.    Copyright (C) Andrew Tridgell 1992-1998
  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.   /* if the modtime is 0 or -1 then ignore the call and
  198.      return success */
  199.   if (times->modtime == (time_t)0 || times->modtime == (time_t)-1)
  200.     return 0;
  201.   
  202.   /* if the access time is 0 or -1 then set it to the modtime */
  203.   if (times->actime == (time_t)0 || times->actime == (time_t)-1)
  204.     times->actime = times->modtime;
  205.    
  206.   return(utime(dos_to_unix(fname,False),times));
  207. }
  208.  
  209. /*********************************************************
  210. for rename across filesystems Patch from Warren Birnbaum 
  211. <warrenb@hpcvscdp.cv.hp.com>
  212. **********************************************************/
  213.  
  214. static int copy_reg(char *source, const char *dest)
  215. {
  216.   struct stat source_stats;
  217.   int ifd;
  218.   int ofd;
  219.   char *buf;
  220.   int len;                      /* Number of bytes read into `buf'. */
  221.  
  222.   lstat (source, &source_stats);
  223.   if (!S_ISREG (source_stats.st_mode))
  224.     {
  225.       return 1;
  226.     }
  227.  
  228.   if (unlink (dest) && errno != ENOENT)
  229.     {
  230.       return 1;
  231.     }
  232.  
  233.   if((ifd = open (source, O_RDONLY, 0)) < 0)
  234.     {
  235.       return 1;
  236.     }
  237.   if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 )
  238.     {
  239.       close (ifd);
  240.       return 1;
  241.     }
  242.  
  243.   if((buf = malloc( COPYBUF_SIZE )) == NULL)
  244.     {
  245.       close (ifd);  
  246.       close (ofd);  
  247.       unlink (dest);
  248.       return 1;
  249.     }
  250.  
  251.   while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0)
  252.     {
  253.       if (write_data(ofd, buf, len) < 0)
  254.         {
  255.           close (ifd);
  256.           close (ofd);
  257.           unlink (dest);
  258.           free(buf);
  259.           return 1;
  260.         }
  261.     }
  262.   free(buf);
  263.   if (len < 0)
  264.     {
  265.       close (ifd);
  266.       close (ofd);
  267.       unlink (dest);
  268.       return 1;
  269.     }
  270.  
  271.   if (close (ifd) < 0)
  272.     {
  273.       close (ofd);
  274.       return 1;
  275.     }
  276.   if (close (ofd) < 0)
  277.     {
  278.       return 1;
  279.     }
  280.  
  281.   /* chown turns off set[ug]id bits for non-root,
  282.      so do the chmod last.  */
  283.  
  284.   /* Try to copy the old file's modtime and access time.  */
  285.   {
  286.     struct utimbuf tv;
  287.  
  288.     tv.actime = source_stats.st_atime;
  289.     tv.modtime = source_stats.st_mtime;
  290.     if (utime (dest, &tv))
  291.       {
  292.         return 1;
  293.       }
  294.   }
  295.  
  296.   /* Try to preserve ownership.  For non-root it might fail, but that's ok.
  297.      But root probably wants to know, e.g. if NFS disallows it.  */
  298.   if (chown (dest, source_stats.st_uid, source_stats.st_gid)
  299.       && (errno != EPERM))
  300.     {
  301.       return 1;
  302.     }
  303.  
  304.   if (chmod (dest, source_stats.st_mode & 07777))
  305.     {
  306.       return 1;
  307.     }
  308.   unlink (source);
  309.   return 0;
  310. }
  311.  
  312. /*******************************************************************
  313. for rename()
  314. ********************************************************************/
  315. int sys_rename(char *from, char *to)
  316. {
  317.     int rcode;  
  318.     pstring zfrom, zto;
  319.  
  320.     pstrcpy (zfrom, dos_to_unix (from, False));
  321.     pstrcpy (zto, dos_to_unix (to, False));
  322.     rcode = rename (zfrom, zto);
  323.  
  324.     if (errno == EXDEV) 
  325.       {
  326.         /* Rename across filesystems needed. */
  327.         rcode = copy_reg (zfrom, zto);        
  328.       }
  329.     return rcode;
  330. }
  331.  
  332. /*******************************************************************
  333. for chmod
  334. ********************************************************************/
  335. int sys_chmod(char *fname,int mode)
  336. {
  337.   return(chmod(dos_to_unix(fname,False),mode));
  338. }
  339.  
  340. /*******************************************************************
  341. for getwd
  342. ********************************************************************/
  343. char *sys_getwd(char *s)
  344. {
  345.   char *wd;
  346. #ifdef USE_GETCWD
  347.   wd = (char *) getcwd (s, sizeof (pstring));
  348. #else
  349.   wd = (char *) getwd (s);
  350. #endif
  351.   if (wd)
  352.     unix_to_dos (wd, True);
  353.   return wd;
  354. }
  355.  
  356. /*******************************************************************
  357. chown isn't used much but OS/2 doesn't have it
  358. ********************************************************************/
  359. int sys_chown(char *fname,int uid,int gid)
  360. {
  361. #ifdef NO_CHOWN
  362.   DEBUG(1,("Warning - chown(%s,%d,%d) not done\n",fname,uid,gid));
  363. #else
  364.   return(chown(fname,uid,gid));
  365. #endif
  366. }
  367.  
  368. /*******************************************************************
  369. os/2 also doesn't have chroot
  370. ********************************************************************/
  371. int sys_chroot(char *dname)
  372. {
  373. #ifdef NO_CHROOT
  374.   DEBUG(1,("Warning - chroot(%s) not done\n",dname));
  375. #else
  376.   return(chroot(dname));
  377. #endif
  378. }
  379.  
  380. /**************************************************************************
  381. A wrapper for gethostbyname() that tries avoids looking up hostnames 
  382. in the root domain, which can cause dial-on-demand links to come up for no
  383. apparent reason.
  384. ****************************************************************************/
  385. struct hostent *sys_gethostbyname(char *name)
  386. {
  387. #ifdef REDUCE_ROOT_DNS_LOOKUPS
  388.   char query[256], hostname[256];
  389.   char *domain;
  390.  
  391.   /* Does this name have any dots in it? If so, make no change */
  392.  
  393.   if (strchr(name, '.'))
  394.     return(gethostbyname(name));
  395.  
  396.   /* Get my hostname, which should have domain name 
  397.      attached. If not, just do the gethostname on the
  398.      original string. 
  399.   */
  400.  
  401.   gethostname(hostname, sizeof(hostname) - 1);
  402.   hostname[sizeof(hostname) - 1] = 0;
  403.   if ((domain = strchr(hostname, '.')) == NULL)
  404.     return(gethostbyname(name));
  405.  
  406.   /* Attach domain name to query and do modified query.
  407.      If names too large, just do gethostname on the
  408.      original string.
  409.   */
  410.  
  411.   if((strlen(name) + strlen(domain)) >= sizeof(query))
  412.     return(gethostbyname(name));
  413.  
  414.   slprintf(query, sizeof(query)-1, "%s%s", name, domain);
  415.   return(gethostbyname(query));
  416. #else /* REDUCE_ROOT_DNS_LOOKUPS */
  417.   return(gethostbyname(name));
  418. #endif /* REDUCE_ROOT_DNS_LOOKUPS */
  419. }
  420.  
  421.