Makefile.in: Fixed bug with continuation line causing proto to fail.
[Samba/gebeck_regimport.git] / source / lib / system.c
blobf474633dd110d6b9eb4486ac9b2e340100592589
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 Samba system utilities
5 Copyright (C) Andrew Tridgell 1992-1998
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.
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.
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.
22 #include "includes.h"
24 extern int DEBUGLEVEL;
27 The idea is that this file will eventually have wrappers around all
28 important system calls in samba. The aims are:
30 - to enable easier porting by putting OS dependent stuff in here
32 - to allow for hooks into other "pseudo-filesystems"
34 - to allow easier integration of things like the japanese extensions
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.
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 #ifndef HAVE_SELECT
48 static int pollfd(int fd)
50 int r=0;
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
60 return(r);
63 int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
65 fd_set fds2;
66 int counter=0;
67 int found=0;
69 FD_ZERO(&fds2);
71 while (1)
73 int i;
74 for (i=0;i<maxfd;i++) {
75 if (FD_ISSET(i,fds) && pollfd(i)>0) {
76 found++;
77 FD_SET(i,&fds2);
81 if (found) {
82 memcpy((void *)fds,(void *)&fds2,sizeof(fds2));
83 return(found);
86 if (tval && tval->tv_sec < counter) return(0);
87 sleep(1);
88 counter++;
92 #else /* !NO_SELECT */
93 int sys_select(int maxfd, fd_set *fds,struct timeval *tval)
95 #ifdef USE_POLL
96 struct pollfd pfd[256];
97 int i;
98 int maxpoll;
99 int timeout;
100 int pollrtn;
102 maxpoll = 0;
103 for( i = 0; i < maxfd; i++) {
104 if(FD_ISSET(i,fds)) {
105 struct pollfd *pfdp = &pfd[maxpoll++];
106 pfdp->fd = i;
107 pfdp->events = POLLIN;
108 pfdp->revents = 0;
112 timeout = (tval != NULL) ? (tval->tv_sec * 1000) + (tval->tv_usec/1000) :
114 errno = 0;
115 do {
116 pollrtn = poll( &pfd[0], maxpoll, timeout);
117 } while (pollrtn<0 && errno == EINTR);
119 FD_ZERO(fds);
121 for( i = 0; i < maxpoll; i++)
122 if( pfd[i].revents & POLLIN )
123 FD_SET(pfd[i].fd,fds);
125 return pollrtn;
126 #else /* USE_POLL */
128 struct timeval t2;
129 int selrtn;
131 do {
132 if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2));
133 errno = 0;
134 selrtn = select(maxfd,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL);
135 } while (selrtn<0 && errno == EINTR);
137 return(selrtn);
139 #endif /* USE_POLL */
140 #endif /* NO_SELECT */
142 /*******************************************************************
143 A stat() wrapper that will deal with 64 bit filesizes.
144 ********************************************************************/
146 int sys_stat(char *fname,SMB_STRUCT_STAT *sbuf)
148 #if defined(HAVE_OFF64_T) && defined(HAVE_STAT64)
149 return stat64(fname, sbuf);
150 #else
151 return stat(fname, sbuf);
152 #endif
155 /*******************************************************************
156 An fstat() wrapper that will deal with 64 bit filesizes.
157 ********************************************************************/
159 int sys_fstat(int fd,SMB_STRUCT_STAT *sbuf)
161 #if defined(HAVE_OFF64_T) && defined(HAVE_FSTAT64)
162 return fstat64(fd, sbuf);
163 #else
164 return fstat(fd, sbuf);
165 #endif
168 /*******************************************************************
169 An lstat() wrapper that will deal with 64 bit filesizes.
170 ********************************************************************/
172 int sys_lstat(char *fname,SMB_STRUCT_STAT *sbuf)
174 #if defined(HAVE_OFF64_T) && defined(HAVE_LSTAT64)
175 return lstat64(fname, sbuf);
176 #else
177 return lstat(fname, sbuf);
178 #endif
181 /*******************************************************************
182 An ftruncate() wrapper that will deal with 64 bit filesizes.
183 ********************************************************************/
185 int sys_ftruncate(int fd, SMB_OFF_T offset)
187 #if defined(HAVE_OFF64_T) && defined(HAVE_FTRUNCATE64)
188 return ftruncate64(fd, offset);
189 #else
190 return ftruncate(fd, offset);
191 #endif
194 /*******************************************************************
195 An lseek() wrapper that will deal with 64 bit filesizes.
196 ********************************************************************/
198 SMB_OFF_T sys_lseek(int fd, SMB_OFF_T offset, int whence)
200 #if defined(HAVE_OFF64_T) && defined(HAVE_LSEEK64)
201 return lseek64(fd, offset, whence);
202 #else
203 return lseek(fd, offset, whence);
204 #endif
207 /*******************************************************************
208 An fseek() wrapper that will deal with 64 bit filesizes.
209 ********************************************************************/
211 int sys_fseek(FILE *fp, SMB_OFF_T offset, int whence)
213 #if defined(LARGE_SMB_OFF_T) && defined(HAVE_FSEEK64)
214 return fseek64(fp, offset, whence);
215 #else
216 return fseek(fp, offset, whence);
217 #endif
220 /*******************************************************************
221 An ftell() wrapper that will deal with 64 bit filesizes.
222 ********************************************************************/
224 SMB_OFF_T sys_ftell(FILE *fp)
226 #if defined(LARGE_SMB_OFF_T) && defined(HAVE_FTELL64)
227 return (SMB_OFF_T)ftell64(fp);
228 #else
229 return (SMB_OFF_T)ftell(fp);
230 #endif
233 /*******************************************************************
234 just a unlink wrapper that calls dos_to_unix.
235 ********************************************************************/
236 int dos_unlink(char *fname)
238 return(unlink(dos_to_unix(fname,False)));
242 /*******************************************************************
243 a simple open() wrapper that calls dos_to_unix.
244 ********************************************************************/
245 int dos_open(char *fname,int flags,mode_t mode)
247 return(open(dos_to_unix(fname,False),flags,mode));
251 /*******************************************************************
252 a simple opendir() wrapper that calls dos_to_unix
253 ********************************************************************/
254 DIR *dos_opendir(char *dname)
256 return(opendir(dos_to_unix(dname,False)));
259 /*******************************************************************
260 and a stat() wrapper that calls dos_to_unix.
261 ********************************************************************/
262 int dos_stat(char *fname,SMB_STRUCT_STAT *sbuf)
264 return(sys_stat(dos_to_unix(fname,False),sbuf));
267 /*******************************************************************
268 The wait() calls vary between systems
269 ********************************************************************/
270 int sys_waitpid(pid_t pid,int *status,int options)
272 #ifdef HAVE_WAITPID
273 return waitpid(pid,status,options);
274 #else /* HAVE_WAITPID */
275 return wait4(pid, status, options, NULL);
276 #endif /* HAVE_WAITPID */
279 /*******************************************************************
280 don't forget lstat() that calls dos_to_unix.
281 ********************************************************************/
282 int dos_lstat(char *fname,SMB_STRUCT_STAT *sbuf)
284 return(sys_lstat(dos_to_unix(fname,False),sbuf));
287 /*******************************************************************
288 mkdir() gets a wrapper that calls dos_to_unix.
289 ********************************************************************/
290 int dos_mkdir(char *dname,mode_t mode)
292 return(mkdir(dos_to_unix(dname,False),mode));
295 /*******************************************************************
296 do does rmdir() - call dos_to_unix
297 ********************************************************************/
298 int dos_rmdir(char *dname)
300 return(rmdir(dos_to_unix(dname,False)));
303 /*******************************************************************
304 I almost forgot chdir() - call dos_to_unix.
305 ********************************************************************/
306 int dos_chdir(char *dname)
308 return(chdir(dos_to_unix(dname,False)));
311 /*******************************************************************
312 now for utime() - call dos_to_unix.
313 ********************************************************************/
314 int dos_utime(char *fname,struct utimbuf *times)
316 /* if the modtime is 0 or -1 then ignore the call and
317 return success */
318 if (times->modtime == (time_t)0 || times->modtime == (time_t)-1)
319 return 0;
321 /* if the access time is 0 or -1 then set it to the modtime */
322 if (times->actime == (time_t)0 || times->actime == (time_t)-1)
323 times->actime = times->modtime;
325 return(utime(dos_to_unix(fname,False),times));
328 /*********************************************************
329 for rename across filesystems Patch from Warren Birnbaum
330 <warrenb@hpcvscdp.cv.hp.com>
331 **********************************************************/
333 static int copy_reg(char *source, const char *dest)
335 SMB_STRUCT_STAT source_stats;
336 int ifd;
337 int ofd;
338 char *buf;
339 int len; /* Number of bytes read into `buf'. */
341 sys_lstat (source, &source_stats);
342 if (!S_ISREG (source_stats.st_mode))
343 return 1;
345 if (unlink (dest) && errno != ENOENT)
346 return 1;
348 if((ifd = open (source, O_RDONLY, 0)) < 0)
349 return 1;
351 if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0 )
353 close (ifd);
354 return 1;
357 if((buf = malloc( COPYBUF_SIZE )) == NULL)
359 close (ifd);
360 close (ofd);
361 unlink (dest);
362 return 1;
365 while ((len = read(ifd, buf, COPYBUF_SIZE)) > 0)
367 if (write_data(ofd, buf, len) < 0)
369 close (ifd);
370 close (ofd);
371 unlink (dest);
372 free(buf);
373 return 1;
376 free(buf);
377 if (len < 0)
379 close (ifd);
380 close (ofd);
381 unlink (dest);
382 return 1;
385 if (close (ifd) < 0)
387 close (ofd);
388 return 1;
390 if (close (ofd) < 0)
391 return 1;
393 /* chown turns off set[ug]id bits for non-root,
394 so do the chmod last. */
396 /* Try to copy the old file's modtime and access time. */
398 struct utimbuf tv;
400 tv.actime = source_stats.st_atime;
401 tv.modtime = source_stats.st_mtime;
402 if (utime (dest, &tv))
403 return 1;
406 /* Try to preserve ownership. For non-root it might fail, but that's ok.
407 But root probably wants to know, e.g. if NFS disallows it. */
408 if (chown (dest, source_stats.st_uid, source_stats.st_gid)
409 && (errno != EPERM))
410 return 1;
412 if (chmod (dest, source_stats.st_mode & 07777))
413 return 1;
415 unlink (source);
416 return 0;
419 /*******************************************************************
420 for rename() - call dos_to_unix.
421 ********************************************************************/
422 int dos_rename(char *from, char *to)
424 int rcode;
425 pstring zfrom, zto;
427 pstrcpy (zfrom, dos_to_unix (from, False));
428 pstrcpy (zto, dos_to_unix (to, False));
429 rcode = rename (zfrom, zto);
431 if (errno == EXDEV)
433 /* Rename across filesystems needed. */
434 rcode = copy_reg (zfrom, zto);
436 return rcode;
439 /*******************************************************************
440 for chmod - call dos_to_unix.
441 ********************************************************************/
442 int dos_chmod(char *fname,mode_t mode)
444 return(chmod(dos_to_unix(fname,False),mode));
447 /*******************************************************************
448 for getwd - takes a UNIX directory name and returns the name
449 in dos format.
450 ********************************************************************/
451 char *dos_getwd(char *s)
453 char *wd;
454 #ifdef HAVE_GETCWD
455 wd = (char *)getcwd(s, sizeof (pstring));
456 #else
457 wd = (char *)getwd(s);
458 #endif
459 if (wd)
460 unix_to_dos(wd, True);
461 return wd;
464 /*******************************************************************
465 chown isn't used much but OS/2 doesn't have it
466 ********************************************************************/
467 int sys_chown(char *fname,int uid,int gid)
469 #ifndef HAVE_CHOWN
470 static int done;
471 if (!done) {
472 DEBUG(1,("WARNING: no chown!\n"));
473 done=1;
475 #else
476 return(chown(fname,uid,gid));
477 #endif
480 /*******************************************************************
481 os/2 also doesn't have chroot
482 ********************************************************************/
483 int sys_chroot(char *dname)
485 #ifndef HAVE_CHROOT
486 static int done;
487 if (!done) {
488 DEBUG(1,("WARNING: no chroot!\n"));
489 done=1;
491 #else
492 return(chroot(dname));
493 #endif
496 /**************************************************************************
497 A wrapper for gethostbyname() that tries avoids looking up hostnames
498 in the root domain, which can cause dial-on-demand links to come up for no
499 apparent reason.
500 ****************************************************************************/
501 struct hostent *sys_gethostbyname(char *name)
503 #ifdef REDUCE_ROOT_DNS_LOOKUPS
504 char query[256], hostname[256];
505 char *domain;
507 /* Does this name have any dots in it? If so, make no change */
509 if (strchr(name, '.'))
510 return(gethostbyname(name));
512 /* Get my hostname, which should have domain name
513 attached. If not, just do the gethostname on the
514 original string.
517 gethostname(hostname, sizeof(hostname) - 1);
518 hostname[sizeof(hostname) - 1] = 0;
519 if ((domain = strchr(hostname, '.')) == NULL)
520 return(gethostbyname(name));
522 /* Attach domain name to query and do modified query.
523 If names too large, just do gethostname on the
524 original string.
527 if((strlen(name) + strlen(domain)) >= sizeof(query))
528 return(gethostbyname(name));
530 slprintf(query, sizeof(query)-1, "%s%s", name, domain);
531 return(gethostbyname(query));
532 #else /* REDUCE_ROOT_DNS_LOOKUPS */
533 return(gethostbyname(name));
534 #endif /* REDUCE_ROOT_DNS_LOOKUPS */
538 /**************************************************************************
539 Try and abstract process capabilities (for systems that have them).
540 ****************************************************************************/
542 BOOL set_process_capability( uint32 cap_flag, BOOL enable )
544 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
545 if(cap_flag == KERNEL_OPLOCK_CAPABILITY)
547 cap_t cap = cap_get_proc();
549 if (cap == NULL) {
550 DEBUG(0,("set_process_capability: cap_get_proc failed. Error was %s\n",
551 strerror(errno)));
552 return False;
555 if(enable)
556 cap->cap_effective |= CAP_NETWORK_MGT;
557 else
558 cap->cap_effective &= ~CAP_NETWORK_MGT;
560 if (cap_set_proc(cap) == -1) {
561 DEBUG(0,("set_process_capability: cap_set_proc failed. Error was %s\n",
562 strerror(errno)));
563 return False;
566 DEBUG(10,("set_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
568 #endif
569 return True;
572 /**************************************************************************
573 Try and abstract inherited process capabilities (for systems that have them).
574 ****************************************************************************/
576 BOOL set_inherited_process_capability( uint32 cap_flag, BOOL enable )
578 #if defined(HAVE_IRIX_SPECIFIC_CAPABILITIES)
579 if(cap_flag == KERNEL_OPLOCK_CAPABILITY)
581 cap_t cap = cap_get_proc();
583 if (cap == NULL) {
584 DEBUG(0,("set_inherited_process_capability: cap_get_proc failed. Error was %s\n",
585 strerror(errno)));
586 return False;
589 if(enable)
590 cap->cap_inheritable |= CAP_NETWORK_MGT;
591 else
592 cap->cap_inheritable &= ~CAP_NETWORK_MGT;
594 if (cap_set_proc(cap) == -1) {
595 DEBUG(0,("set_inherited_process_capability: cap_set_proc failed. Error was %s\n",
596 strerror(errno)));
597 return False;
600 DEBUG(10,("set_inherited_process_capability: Set KERNEL_OPLOCK_CAPABILITY.\n"));
602 #endif
603 return True;
606 /**************************************************************************
607 Wrapper for random().
608 ****************************************************************************/
610 long sys_random(void)
612 #if defined(HAVE_RANDOM)
613 return (long)random();
614 #elif defined(HAVE_RAND)
615 return (long)rand();
616 #else
617 DEBUG(0,("Error - no random function available !\n"));
618 exit(1);
619 #endif
622 /**************************************************************************
623 Wrapper for srandom().
624 ****************************************************************************/
626 void sys_srandom(unsigned int seed)
628 #if defined(HAVE_SRANDOM)
629 srandom(seed);
630 #elif defined(HAVE_SRAND)
631 srand(seed);
632 #else
633 DEBUG(0,("Error - no srandom function available !\n"));
634 exit(1);
635 #endif