moved some more locking routines to locking.c, and moved replacement
[samba.git] / source / lib / replace.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    replacement routines for broken systems
5    Copyright (C) Andrew Tridgell 1992-1995
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  void replace_dummy(void) 
25 {}
26
27 #ifdef REPLACE_STRLEN
28 /****************************************************************************
29 a replacement strlen() that returns int for solaris
30 ****************************************************************************/
31  int Strlen(char *s)
32 {
33   int ret=0;
34   if (!s) return(0);
35   while (*s++) ret++;
36   return(ret);
37 }
38 #endif
39
40 #ifdef NO_FTRUNCATE
41  /*******************************************************************
42 ftruncate for operating systems that don't have it
43 ********************************************************************/
44  int ftruncate(int f,long l)
45 {
46       struct  flock   fl;
47
48       fl.l_whence = 0;
49       fl.l_len = 0;
50       fl.l_start = l;
51       fl.l_type = F_WRLCK;
52       return fcntl(f, F_FREESP, &fl);
53 }
54 #endif
55
56
57 #ifdef REPLACE_STRSTR
58 /****************************************************************************
59 Mips version of strstr doesn't seem to work correctly.
60 There is a #define in includes.h to redirect calls to this function.
61 ****************************************************************************/
62 char *Strstr(char *s, char *p)
63 {
64         int len = strlen(p);
65
66         while ( *s != '\0' ) {
67                 if ( strncmp(s, p, len) == 0 )
68                 return s;
69                 s++;
70         }
71
72         return NULL;
73 }
74 #endif /* REPLACE_STRSTR */
75
76
77 #ifdef REPLACE_MKTIME
78 /*******************************************************************
79 a mktime() replacement for those who don't have it - contributed by 
80 C.A. Lademann <cal@zls.com>
81 ********************************************************************/
82 #define  MINUTE  60
83 #define  HOUR    60*MINUTE
84 #define  DAY             24*HOUR
85 #define  YEAR    365*DAY
86 time_t Mktime(struct tm      *t)
87 {
88   struct tm       *u;
89   time_t  epoch = 0;
90   int             mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
91   y, m, i;
92
93   if(t->tm_year < 70)
94     return((time_t)-1);
95
96   epoch = (t->tm_year - 70) * YEAR + 
97     (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
98
99   y = t->tm_year;
100   m = 0;
101
102   for(i = 0; i < t->tm_mon; i++) {
103     epoch += mon [m] * DAY;
104     if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
105       epoch += DAY;
106     
107     if(++m > 11) {
108       m = 0;
109       y++;
110     }
111   }
112
113   epoch += (t->tm_mday - 1) * DAY;
114   epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
115   
116   if((u = localtime(&epoch)) != NULL) {
117     t->tm_sec = u->tm_sec;
118     t->tm_min = u->tm_min;
119     t->tm_hour = u->tm_hour;
120     t->tm_mday = u->tm_mday;
121     t->tm_mon = u->tm_mon;
122     t->tm_year = u->tm_year;
123     t->tm_wday = u->tm_wday;
124     t->tm_yday = u->tm_yday;
125     t->tm_isdst = u->tm_isdst;
126 #ifndef NO_TM_NAME
127     memcpy(t->tm_name, u->tm_name, LTZNMAX);
128 #endif
129   }
130
131   return(epoch);
132 }
133 #endif /* REPLACE_MKTIME */
134
135
136
137 #ifdef REPLACE_RENAME
138 /* Rename a file. (from libiberty in GNU binutils)  */
139  int rename (zfrom, zto)
140      const char *zfrom;
141      const char *zto;
142 {
143   if (link (zfrom, zto) < 0)
144     {
145       if (errno != EEXIST)
146         return -1;
147       if (unlink (zto) < 0
148           || link (zfrom, zto) < 0)
149         return -1;
150     }
151   return unlink (zfrom);
152 }
153 #endif
154
155
156 #ifdef REPLACE_INNETGR
157 /*
158  * Search for a match in a netgroup. This replaces it on broken systems.
159  */
160 int InNetGr(char *group,char *host,char *user,char *dom)
161 {
162   char *hst, *usr, *dm;
163   
164   setnetgrent(group);
165   while (getnetgrent(&hst, &usr, &dm))
166     if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
167         ((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
168         ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
169       endnetgrent();
170       return (1);
171     }
172   endnetgrent();
173   return (0);
174 }
175 #endif
176
177
178
179 #ifdef NO_INITGROUPS
180 #include <sys/types.h>
181 #include <limits.h>
182 #include <grp.h>
183
184 #ifndef NULL
185 #define NULL (void *)0
186 #endif
187
188 /****************************************************************************
189  some systems don't have an initgroups call 
190 ****************************************************************************/
191  int initgroups(char *name,gid_t id)
192 {
193 #ifdef NO_SETGROUPS
194   /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
195   return(0);
196 #else
197   gid_t  grouplst[NGROUPS_MAX];
198   int    i,j;
199   struct group *g;
200   char   *gr;
201
202   grouplst[0] = id;
203   i = 1;
204   while (i < NGROUPS_MAX && 
205          ((g = (struct group *)getgrent()) != (struct group *)NULL)) 
206     {
207       if (g->gr_gid == id)
208         continue;
209       j = 0;
210       gr = g->gr_mem[0];
211       while (gr && (*gr != (char)NULL)) {
212         if (strcmp(name,gr) == 0) {
213           grouplst[i] = g->gr_gid;
214           i++;
215           gr = (char *)NULL;
216           break;
217         }
218         gr = g->gr_mem[++j];
219       }
220     }
221   endgrent();
222   return(setgroups(i,grouplst));
223 #endif
224 }
225 #endif
226
227
228 #if (defined(SecureWare) && defined(SCO))
229 /* This is needed due to needing the nap() function but we don't want
230    to include the Xenix libraries since that will break other things...
231    BTW: system call # 0x0c28 is the same as calling nap() */
232 long nap(long milliseconds) {
233   return syscall(0x0c28, milliseconds);
234 }
235 #endif
236
237
238
239 #if WRAP_MALLOC
240
241 /* undo the wrapping temporarily */
242 #undef malloc
243 #undef realloc
244 #undef free
245
246 /****************************************************************************
247 wrapper for malloc() to catch memory errors
248 ****************************************************************************/
249 void *malloc_wrapped(int size,char *file,int line)
250 {
251 #ifdef xx_old_malloc
252   void *res = xx_old_malloc(size);
253 #else
254   void *res = malloc(size);
255 #endif
256   DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
257         file,line,
258         size,(unsigned int)res));
259   return(res);
260 }
261
262 /****************************************************************************
263 wrapper for realloc() to catch memory errors
264 ****************************************************************************/
265 void *realloc_wrapped(void *ptr,int size,char *file,int line)
266 {
267 #ifdef xx_old_realloc
268   void *res = xx_old_realloc(ptr,size);
269 #else
270   void *res = realloc(ptr,size);
271 #endif
272   DEBUG(3,("Realloc\n"));
273   DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
274         file,line,
275         (unsigned int)ptr));
276   DEBUG(3,("Malloc called from %s(%d) with size=%d gave ptr=0x%X\n",
277         file,line,
278         size,(unsigned int)res));
279   return(res);
280 }
281
282 /****************************************************************************
283 wrapper for free() to catch memory errors
284 ****************************************************************************/
285 void free_wrapped(void *ptr,char *file,int line)
286 {
287 #ifdef xx_old_free
288   xx_old_free(ptr);
289 #else
290   free(ptr);
291 #endif
292   DEBUG(3,("free called from %s(%d) with ptr=0x%X\n",
293         file,line,(unsigned int)ptr));
294   return;
295 }
296
297 /* and re-do the define for spots lower in this file */
298 #define malloc(size) malloc_wrapped(size,__FILE__,__LINE__)
299 #define realloc(ptr,size) realloc_wrapped(ptr,size,__FILE__,__LINE__)
300 #define free(ptr) free_wrapped(ptr,__FILE__,__LINE__)
301
302 #endif
303
304
305 #if WRAP_MEMCPY
306 #undef memcpy
307 /*******************************************************************
308 a wrapper around memcpy for diagnostic purposes
309 ********************************************************************/
310 void *memcpy_wrapped(void *d,void *s,int l,char *fname,int line)
311 {
312   if (l>64 && (((int)d)%4) != (((int)s)%4))
313     DEBUG(4,("Misaligned memcpy(0x%X,0x%X,%d) at %s(%d)\n",d,s,l,fname,line));
314 #ifdef xx_old_memcpy  
315   return(xx_old_memcpy(d,s,l));
316 #else
317   return(memcpy(d,s,l));
318 #endif
319 }
320 #define memcpy(d,s,l) memcpy_wrapped(d,s,l,__FILE__,__LINE__)
321 #endif
322