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