From 3ee9d45426a9b3b584d1ffb9f81af26790a83b4c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 03:39:58 +0000 Subject: [PATCH] moved some more locking routines to locking.c, and moved replacement routines for broken OSes from util.c to replace.c. --- source/include/proto.h | 34 ++-- source/lib/replace.c | 322 +++++++++++++++++++++++++++++ source/lib/util.c | 427 --------------------------------------- source/locking/locking.c | 131 ++++++++++++ 4 files changed, 470 insertions(+), 444 deletions(-) create mode 100644 source/lib/replace.c diff --git a/source/include/proto.h b/source/include/proto.h index bb2bff241ed..b8b178bf703 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -88,6 +88,9 @@ void lp_dump(void); int lp_servicenumber(char *pszServiceName); char *my_workgroup(void); char *volume_label(int snum); +BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type); +int file_lock(char *name,int timeout); +void file_unlock(int fd); BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset); BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode); BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode); @@ -115,19 +118,19 @@ void do_announce_request(char *info, char *to_name, int announce_type, void announce_backup(void); void announce_host(void); void announce_master(void); -struct work_record *remove_workgroup(struct domain_record *d, +struct work_record *remove_workgroup(struct subnet_record *d, struct work_record *work); void expire_browse_cache(time_t t); -struct work_record *find_workgroupstruct(struct domain_record *d, +struct work_record *find_workgroupstruct(struct subnet_record *d, fstring name, BOOL add); -struct domain_record *find_domain(struct in_addr source_ip); +struct subnet_record *find_domain(struct in_addr ip); void dump_workgroups(void); -struct domain_record *add_domain_entry(struct in_addr source_ip, +struct subnet_record *add_subnet_entry(struct in_addr source_ip, struct in_addr source_mask, char *name, BOOL add); struct browse_cache_record *add_browser_entry(char *name, int type, char *wg, time_t ttl, struct in_addr ip); -struct server_record *add_server_entry(struct domain_record *d, +struct server_record *add_server_entry(struct subnet_record *d, struct work_record *work, char *name,int servertype, int ttl,char *comment, @@ -136,9 +139,9 @@ void write_browse_list(void); void expire_servers(time_t t); void check_master_browser(void); void browser_gone(char *work_name, struct in_addr ip); -void send_election(struct domain_record *d, char *group,uint32 criterion, +void send_election(struct subnet_record *d, char *group,uint32 criterion, int timeup,char *name); -void become_nonmaster(struct domain_record *d, struct work_record *work); +void become_nonmaster(struct subnet_record *d, struct work_record *work); void run_elections(void); void process_election(struct packet_struct *p,char *buf); BOOL check_elections(void); @@ -254,6 +257,13 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); +char *Strstr(char *s, char *p); +time_t Mktime(struct tm *t); +int InNetGr(char *group,char *host,char *user,char *dom); +void *malloc_wrapped(int size,char *file,int line); +void *realloc_wrapped(void *ptr,int size,char *file,int line); +void free_wrapped(void *ptr,char *file,int line); +void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line); int reply_special(char *inbuf,char *outbuf); int reply_tcon(char *inbuf,char *outbuf); int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize); @@ -402,9 +412,6 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change); BOOL user_in_list(char *user,char *list); void setup_logging(char *pname,BOOL interactive); void reopen_logs(void); -BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type); -int file_lock(char *name,int timeout); -void file_unlock(int fd); BOOL is_a_socket(int fd); BOOL next_token(char **ptr,char *buff,char *sep); char **toktocliplist(int *ctok, char *sep); @@ -509,13 +516,6 @@ char *gidtoname(int gid); void BlockSignals(BOOL block); void ajt_panic(void); char *readdirname(void *p); -void *malloc_wrapped(int size,char *file,int line); -void *realloc_wrapped(void *ptr,int size,char *file,int line); -void free_wrapped(void *ptr,char *file,int line); -char *Strstr(char *s, char *p); -time_t Mktime(struct tm *t); -int InNetGr(char *group,char *host,char *user,char *dom); -void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line); int VT_Check(char *buffer); int VT_Start_utmp(void); int VT_Stop_utmp(void); diff --git a/source/lib/replace.c b/source/lib/replace.c new file mode 100644 index 00000000000..14e3c184b7d --- /dev/null +++ b/source/lib/replace.c @@ -0,0 +1,322 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + replacement routines for broken systems + Copyright (C) Andrew Tridgell 1992-1995 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + void replace_dummy(void) +{} + +#ifdef REPLACE_STRLEN +/**************************************************************************** +a replacement strlen() that returns int for solaris +****************************************************************************/ + int Strlen(char *s) +{ + int ret=0; + if (!s) return(0); + while (*s++) ret++; + return(ret); +} +#endif + +#ifdef NO_FTRUNCATE + /******************************************************************* +ftruncate for operating systems that don't have it +********************************************************************/ + int ftruncate(int f,long l) +{ + struct flock fl; + + fl.l_whence = 0; + fl.l_len = 0; + fl.l_start = l; + fl.l_type = F_WRLCK; + return fcntl(f, F_FREESP, &fl); +} +#endif + + +#ifdef REPLACE_STRSTR +/**************************************************************************** +Mips version of strstr doesn't seem to work correctly. +There is a #define in includes.h to redirect calls to this function. +****************************************************************************/ +char *Strstr(char *s, char *p) +{ + int len = strlen(p); + + while ( *s != '\0' ) { + if ( strncmp(s, p, len) == 0 ) + return s; + s++; + } + + return NULL; +} +#endif /* REPLACE_STRSTR */ + + +#ifdef REPLACE_MKTIME +/******************************************************************* +a mktime() replacement for those who don't have it - contributed by +C.A. Lademann +********************************************************************/ +#define MINUTE 60 +#define HOUR 60*MINUTE +#define DAY 24*HOUR +#define YEAR 365*DAY +time_t Mktime(struct tm *t) +{ + struct tm *u; + time_t epoch = 0; + int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + y, m, i; + + if(t->tm_year < 70) + return((time_t)-1); + + epoch = (t->tm_year - 70) * YEAR + + (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY; + + y = t->tm_year; + m = 0; + + for(i = 0; i < t->tm_mon; i++) { + epoch += mon [m] * DAY; + if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) + epoch += DAY; + + if(++m > 11) { + m = 0; + y++; + } + } + + epoch += (t->tm_mday - 1) * DAY; + epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; + + if((u = localtime(&epoch)) != NULL) { + t->tm_sec = u->tm_sec; + t->tm_min = u->tm_min; + t->tm_hour = u->tm_hour; + t->tm_mday = u->tm_mday; + t->tm_mon = u->tm_mon; + t->tm_year = u->tm_year; + t->tm_wday = u->tm_wday; + t->tm_yday = u->tm_yday; + t->tm_isdst = u->tm_isdst; +#ifndef NO_TM_NAME + memcpy(t->tm_name, u->tm_name, LTZNMAX); +#endif + } + + return(epoch); +} +#endif /* REPLACE_MKTIME */ + + + +#ifdef REPLACE_RENAME +/* Rename a file. (from libiberty in GNU binutils) */ + int rename (zfrom, zto) + const char *zfrom; + const char *zto; +{ + if (link (zfrom, zto) < 0) + { + if (errno != EEXIST) + return -1; + if (unlink (zto) < 0 + || link (zfrom, zto) < 0) + return -1; + } + return unlink (zfrom); +} +#endif + + +#ifdef REPLACE_INNETGR +/* + * Search for a match in a netgroup. This replaces it on broken systems. + */ +int InNetGr(char *group,char *host,char *user,char *dom) +{ + char *hst, *usr, *dm; + + setnetgrent(group); + while (getnetgrent(&hst, &usr, &dm)) + if (((host == 0) || (hst == 0) || !strcmp(host, hst)) && + ((user == 0) || (usr == 0) || !strcmp(user, usr)) && + ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) { + endnetgrent(); + return (1); + } + endnetgrent(); + return (0); +} +#endif + + + +#ifdef NO_INITGROUPS +#include +#include +#include + +#ifndef NULL +#define NULL (void *)0 +#endif + +/**************************************************************************** + some systems don't have an initgroups call +****************************************************************************/ + int initgroups(char *name,gid_t id) +{ +#ifdef NO_SETGROUPS + /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ + return(0); +#else + gid_t grouplst[NGROUPS_MAX]; + int i,j; + struct group *g; + char *gr; + + grouplst[0] = id; + i = 1; + while (i < NGROUPS_MAX && + ((g = (struct group *)getgrent()) != (struct group *)NULL)) + { + if (g->gr_gid == id) + continue; + j = 0; + gr = g->gr_mem[0]; + while (gr && (*gr != (char)NULL)) { + if (strcmp(name,gr) == 0) { + grouplst[i] = g->gr_gid; + i++; + gr = (char *)NULL; + break; + } + gr = g->gr_mem[++j]; + } + } + endgrent(); + return(setgroups(i,grouplst)); +#endif +} +#endif + + +#if (defined(SecureWare) && defined(SCO)) +/* This is needed due to needing the nap() function but we don't want + to include the Xenix libraries since that will break other things... + BTW: system call # 0x0c28 is the same as calling nap() */ +long nap(long milliseconds) { + return syscall(0x0c28, milliseconds); +} +#endif + + + +#if WRAP_MALLOC + +/* undo the wrapping temporarily */ +#undef malloc +#undef realloc +#undef free + +/**************************************************************************** +wrapper for malloc() to catch memory errors +****************************************************************************/ +void *malloc_wrapped(int size,char *file,int line) +{ +#ifdef xx_old_malloc + void *res = xx_old_malloc(size); +#else + void *res = malloc(size); +#endif + DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n", + file,line, + size,(unsigned int)res)); + return(res); +} + +/**************************************************************************** +wrapper for realloc() to catch memory errors +****************************************************************************/ +void *realloc_wrapped(void *ptr,int size,char *file,int line) +{ +#ifdef xx_old_realloc + void *res = xx_old_realloc(ptr,size); +#else + void *res = realloc(ptr,size); +#endif + DEBUG(3,("Realloc\n")); + DEBUG(3,("free called from %s(%d) with ptr=0x%X\n", + file,line, + (unsigned int)ptr)); + DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n", + file,line, + size,(unsigned int)res)); + return(res); +} + +/**************************************************************************** +wrapper for free() to catch memory errors +****************************************************************************/ +void free_wrapped(void *ptr,char *file,int line) +{ +#ifdef xx_old_free + xx_old_free(ptr); +#else + free(ptr); +#endif + DEBUG(3,("free called from %s(%d) with ptr=0x%X\n", + file,line,(unsigned int)ptr)); + return; +} + +/* and re-do the define for spots lower in this file */ +#define malloc(size) malloc_wrapped(size,__FILE__,__LINE__) +#define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__) +#define free(ptr) free_wrapped(ptr,__FILE__,__LINE__) + +#endif + + +#if WRAP_MEMCPY +#undef memcpy +/******************************************************************* +a wrapper around memcpy for diagnostic purposes +********************************************************************/ +void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line) +{ + if (l>64 && (((int)d)%4) != (((int)s)%4)) + DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line)); +#ifdef xx_old_memcpy + return(xx_old_memcpy(d,s,l)); +#else + return(memcpy(d,s,l)); +#endif +} +#define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__) +#endif + diff --git a/source/lib/util.c b/source/lib/util.c index cfe8ea05b09..6402b9a049d 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -266,136 +266,6 @@ va_dcl return(0); } -/**************************************************************************** -routine to do file locking -****************************************************************************/ -BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type) -{ -#if HAVE_FCNTL_LOCK - struct flock lock; - int ret; - -#if 1 - uint32 mask = 0xC0000000; - - /* make sure the count is reasonable, we might kill the lockd otherwise */ - count &= ~mask; - - /* the offset is often strange - remove 2 of its bits if either of - the top two bits are set. Shift the top ones by two bits. This - still allows OLE2 apps to operate, but should stop lockd from - dieing */ - if ((offset & mask) != 0) - offset = (offset & ~mask) | ((offset & mask) >> 2); -#else - unsigned long mask = ((unsigned)1<<31); - - /* interpret negative counts as large numbers */ - if (count < 0) - count &= ~mask; - - /* no negative offsets */ - offset &= ~mask; - - /* count + offset must be in range */ - while ((offset < 0 || (offset + count < 0)) && mask) - { - offset &= ~mask; - mask = mask >> 1; - } -#endif - - - DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type)); - - lock.l_type = type; - lock.l_whence = SEEK_SET; - lock.l_start = (int)offset; - lock.l_len = (int)count; - lock.l_pid = 0; - - errno = 0; - - ret = fcntl(fd,op,&lock); - - if (errno != 0) - DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno))); - - /* a lock query */ - if (op == F_GETLK) - { - if ((ret != -1) && - (lock.l_type != F_UNLCK) && - (lock.l_pid != 0) && - (lock.l_pid != getpid())) - { - DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid)); - return(True); - } - - /* it must be not locked or locked by me */ - return(False); - } - - /* a lock set or unset */ - if (ret == -1) - { - DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n", - offset,count,op,type,strerror(errno))); - - /* perhaps it doesn't support this sort of locking?? */ - if (errno == EINVAL) - { - DEBUG(3,("locking not supported? returning True\n")); - return(True); - } - - return(False); - } - - /* everything went OK */ - DEBUG(5,("Lock call successful\n")); - - return(True); -#else - return(False); -#endif -} - -/******************************************************************* -lock a file - returning a open file descriptor or -1 on failure -The timeout is in seconds. 0 means no timeout -********************************************************************/ -int file_lock(char *name,int timeout) -{ - int fd = open(name,O_RDWR|O_CREAT,0666); - time_t t=0; - if (fd < 0) return(-1); - -#if HAVE_FCNTL_LOCK - if (timeout) t = time(NULL); - while (!timeout || (time(NULL)-t < timeout)) { - if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd); - msleep(LOCK_RETRY_TIMEOUT); - } - return(-1); -#else - return(fd); -#endif -} - -/******************************************************************* -unlock a file locked by file_lock -********************************************************************/ -void file_unlock(int fd) -{ - if (fd<0) return; -#if HAVE_FCNTL_LOCK - fcntl_lock(fd,F_SETLK,0,1,F_UNLCK); -#endif - close(fd); -} - /**************************************************************************** determine if a file descriptor is in fact a socket ****************************************************************************/ @@ -2915,39 +2785,6 @@ void Abort(void ) exit(2); } - -#ifdef REPLACE_STRLEN -/**************************************************************************** -a replacement strlen() that returns int for solaris -****************************************************************************/ - int Strlen(char *s) -{ - int ret=0; - if (!s) return(0); - while (*s++) ret++; - return(ret); -} -#endif - - -#ifdef NO_FTRUNCATE - /******************************************************************* -ftruncate for operating systems that don't have it -********************************************************************/ - int ftruncate(int f,long l) -{ - struct flock fl; - - fl.l_whence = 0; - fl.l_len = 0; - fl.l_start = l; - fl.l_type = F_WRLCK; - return fcntl(f, F_FREESP, &fl); -} -#endif - - - /**************************************************************************** get my own name and IP ****************************************************************************/ @@ -3451,267 +3288,3 @@ char *readdirname(void *p) -#if (defined(SecureWare) && defined(SCO)) -/* This is needed due to needing the nap() function but we don't want - to include the Xenix libraries since that will break other things... - BTW: system call # 0x0c28 is the same as calling nap() */ -long nap(long milliseconds) { - return syscall(0x0c28, milliseconds); -} -#endif - -#ifdef NO_INITGROUPS -#include -#include -#include - -#ifndef NULL -#define NULL (void *)0 -#endif - -/**************************************************************************** - some systems don't have an initgroups call -****************************************************************************/ - int initgroups(char *name,gid_t id) -{ -#ifdef NO_SETGROUPS - /* yikes! no SETGROUPS or INITGROUPS? how can this work? */ - return(0); -#else - gid_t grouplst[NGROUPS_MAX]; - int i,j; - struct group *g; - char *gr; - - grouplst[0] = id; - i = 1; - while (i < NGROUPS_MAX && - ((g = (struct group *)getgrent()) != (struct group *)NULL)) - { - if (g->gr_gid == id) - continue; - j = 0; - gr = g->gr_mem[0]; - while (gr && (*gr != (char)NULL)) { - if (strcmp(name,gr) == 0) { - grouplst[i] = g->gr_gid; - i++; - gr = (char *)NULL; - break; - } - gr = g->gr_mem[++j]; - } - } - endgrent(); - return(setgroups(i,grouplst)); -#endif -} -#endif - - -#if WRAP_MALLOC - -/* undo the wrapping temporarily */ -#undef malloc -#undef realloc -#undef free - -/**************************************************************************** -wrapper for malloc() to catch memory errors -****************************************************************************/ -void *malloc_wrapped(int size,char *file,int line) -{ -#ifdef xx_old_malloc - void *res = xx_old_malloc(size); -#else - void *res = malloc(size); -#endif - DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n", - file,line, - size,(unsigned int)res)); - return(res); -} - -/**************************************************************************** -wrapper for realloc() to catch memory errors -****************************************************************************/ -void *realloc_wrapped(void *ptr,int size,char *file,int line) -{ -#ifdef xx_old_realloc - void *res = xx_old_realloc(ptr,size); -#else - void *res = realloc(ptr,size); -#endif - DEBUG(3,("Realloc\n")); - DEBUG(3,("free called from %s(%d) with ptr=0x%X\n", - file,line, - (unsigned int)ptr)); - DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n", - file,line, - size,(unsigned int)res)); - return(res); -} - -/**************************************************************************** -wrapper for free() to catch memory errors -****************************************************************************/ -void free_wrapped(void *ptr,char *file,int line) -{ -#ifdef xx_old_free - xx_old_free(ptr); -#else - free(ptr); -#endif - DEBUG(3,("free called from %s(%d) with ptr=0x%X\n", - file,line,(unsigned int)ptr)); - return; -} - -/* and re-do the define for spots lower in this file */ -#define malloc(size) malloc_wrapped(size,__FILE__,__LINE__) -#define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__) -#define free(ptr) free_wrapped(ptr,__FILE__,__LINE__) - -#endif - -#ifdef REPLACE_STRSTR -/**************************************************************************** -Mips version of strstr doesn't seem to work correctly. -There is a #define in includes.h to redirect calls to this function. -****************************************************************************/ -char *Strstr(char *s, char *p) -{ - int len = strlen(p); - - while ( *s != '\0' ) { - if ( strncmp(s, p, len) == 0 ) - return s; - s++; - } - - return NULL; -} -#endif /* REPLACE_STRSTR */ - - -#ifdef REPLACE_MKTIME -/******************************************************************* -a mktime() replacement for those who don't have it - contributed by -C.A. Lademann -********************************************************************/ -#define MINUTE 60 -#define HOUR 60*MINUTE -#define DAY 24*HOUR -#define YEAR 365*DAY -time_t Mktime(struct tm *t) -{ - struct tm *u; - time_t epoch = 0; - int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - y, m, i; - - if(t->tm_year < 70) - return((time_t)-1); - - epoch = (t->tm_year - 70) * YEAR + - (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY; - - y = t->tm_year; - m = 0; - - for(i = 0; i < t->tm_mon; i++) { - epoch += mon [m] * DAY; - if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0)) - epoch += DAY; - - if(++m > 11) { - m = 0; - y++; - } - } - - epoch += (t->tm_mday - 1) * DAY; - epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec; - - if((u = localtime(&epoch)) != NULL) { - t->tm_sec = u->tm_sec; - t->tm_min = u->tm_min; - t->tm_hour = u->tm_hour; - t->tm_mday = u->tm_mday; - t->tm_mon = u->tm_mon; - t->tm_year = u->tm_year; - t->tm_wday = u->tm_wday; - t->tm_yday = u->tm_yday; - t->tm_isdst = u->tm_isdst; -#ifndef NO_TM_NAME - memcpy(t->tm_name, u->tm_name, LTZNMAX); -#endif - } - - return(epoch); -} -#endif /* REPLACE_MKTIME */ - - - -#ifdef REPLACE_RENAME -/* Rename a file. (from libiberty in GNU binutils) */ - int rename (zfrom, zto) - const char *zfrom; - const char *zto; -{ - if (link (zfrom, zto) < 0) - { - if (errno != EEXIST) - return -1; - if (unlink (zto) < 0 - || link (zfrom, zto) < 0) - return -1; - } - return unlink (zfrom); -} -#endif - - -#ifdef REPLACE_INNETGR -/* - * Search for a match in a netgroup. This replaces it on broken systems. - */ -int InNetGr(char *group,char *host,char *user,char *dom) -{ - char *hst, *usr, *dm; - - setnetgrent(group); - while (getnetgrent(&hst, &usr, &dm)) - if (((host == 0) || (hst == 0) || !strcmp(host, hst)) && - ((user == 0) || (usr == 0) || !strcmp(user, usr)) && - ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) { - endnetgrent(); - return (1); - } - endnetgrent(); - return (0); -} -#endif - - -#if WRAP_MEMCPY -#undef memcpy -/******************************************************************* -a wrapper around memcpy for diagnostic purposes -********************************************************************/ -void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line) -{ - if (l>64 && (((int)d)%4) != (((int)s)%4)) - DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line)); -#ifdef xx_old_memcpy - return(xx_old_memcpy(d,s,l)); -#else - return(memcpy(d,s,l)); -#endif -} -#define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__) -#endif - - - diff --git a/source/locking/locking.c b/source/locking/locking.c index 6ff3ab5d125..9ece7712665 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -28,6 +28,137 @@ extern files_struct Files[]; pstring share_del_pending=""; +/**************************************************************************** +routine to do file locking +****************************************************************************/ +BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type) +{ +#if HAVE_FCNTL_LOCK + struct flock lock; + int ret; + +#if 1 + uint32 mask = 0xC0000000; + + /* make sure the count is reasonable, we might kill the lockd otherwise */ + count &= ~mask; + + /* the offset is often strange - remove 2 of its bits if either of + the top two bits are set. Shift the top ones by two bits. This + still allows OLE2 apps to operate, but should stop lockd from + dieing */ + if ((offset & mask) != 0) + offset = (offset & ~mask) | ((offset & mask) >> 2); +#else + unsigned long mask = ((unsigned)1<<31); + + /* interpret negative counts as large numbers */ + if (count < 0) + count &= ~mask; + + /* no negative offsets */ + offset &= ~mask; + + /* count + offset must be in range */ + while ((offset < 0 || (offset + count < 0)) && mask) + { + offset &= ~mask; + mask = mask >> 1; + } +#endif + + + DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type)); + + lock.l_type = type; + lock.l_whence = SEEK_SET; + lock.l_start = (int)offset; + lock.l_len = (int)count; + lock.l_pid = 0; + + errno = 0; + + ret = fcntl(fd,op,&lock); + + if (errno != 0) + DEBUG(3,("fcntl lock gave errno %d (%s)\n",errno,strerror(errno))); + + /* a lock query */ + if (op == F_GETLK) + { + if ((ret != -1) && + (lock.l_type != F_UNLCK) && + (lock.l_pid != 0) && + (lock.l_pid != getpid())) + { + DEBUG(3,("fd %d is locked by pid %d\n",fd,lock.l_pid)); + return(True); + } + + /* it must be not locked or locked by me */ + return(False); + } + + /* a lock set or unset */ + if (ret == -1) + { + DEBUG(3,("lock failed at offset %d count %d op %d type %d (%s)\n", + offset,count,op,type,strerror(errno))); + + /* perhaps it doesn't support this sort of locking?? */ + if (errno == EINVAL) + { + DEBUG(3,("locking not supported? returning True\n")); + return(True); + } + + return(False); + } + + /* everything went OK */ + DEBUG(5,("Lock call successful\n")); + + return(True); +#else + return(False); +#endif +} + +/******************************************************************* +lock a file - returning a open file descriptor or -1 on failure +The timeout is in seconds. 0 means no timeout +********************************************************************/ +int file_lock(char *name,int timeout) +{ + int fd = open(name,O_RDWR|O_CREAT,0666); + time_t t=0; + if (fd < 0) return(-1); + +#if HAVE_FCNTL_LOCK + if (timeout) t = time(NULL); + while (!timeout || (time(NULL)-t < timeout)) { + if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)) return(fd); + msleep(LOCK_RETRY_TIMEOUT); + } + return(-1); +#else + return(fd); +#endif +} + +/******************************************************************* +unlock a file locked by file_lock +********************************************************************/ +void file_unlock(int fd) +{ + if (fd<0) return; +#if HAVE_FCNTL_LOCK + fcntl_lock(fd,F_SETLK,0,1,F_UNLCK); +#endif + close(fd); +} + + /**************************************************************************** utility function called to see if a file region is locked ****************************************************************************/ -- 2.34.1