merge from the autoconf2 branch to the main branch
[ira/wip.git] / source3 / 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-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  void replace_dummy(void) 
28 {}
29
30
31 #ifndef HAVE_FTRUNCATE
32  /*******************************************************************
33 ftruncate for operating systems that don't have it
34 ********************************************************************/
35  int ftruncate(int f,long l)
36 {
37       struct  flock   fl;
38
39       fl.l_whence = 0;
40       fl.l_len = 0;
41       fl.l_start = l;
42       fl.l_type = F_WRLCK;
43       return fcntl(f, F_FREESP, &fl);
44 }
45 #endif
46
47
48 #ifndef HAVE_MKTIME
49 /*******************************************************************
50 a mktime() replacement for those who don't have it - contributed by 
51 C.A. Lademann <cal@zls.com>
52 ********************************************************************/
53 #define  MINUTE  60
54 #define  HOUR    60*MINUTE
55 #define  DAY             24*HOUR
56 #define  YEAR    365*DAY
57  time_t mktime(struct tm *t)
58 {
59   struct tm       *u;
60   time_t  epoch = 0;
61   int             mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
62   y, m, i;
63
64   if(t->tm_year < 70)
65     return((time_t)-1);
66
67   epoch = (t->tm_year - 70) * YEAR + 
68     (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
69
70   y = t->tm_year;
71   m = 0;
72
73   for(i = 0; i < t->tm_mon; i++) {
74     epoch += mon [m] * DAY;
75     if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
76       epoch += DAY;
77     
78     if(++m > 11) {
79       m = 0;
80       y++;
81     }
82   }
83
84   epoch += (t->tm_mday - 1) * DAY;
85   epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
86   
87   if((u = localtime(&epoch)) != NULL) {
88     t->tm_sec = u->tm_sec;
89     t->tm_min = u->tm_min;
90     t->tm_hour = u->tm_hour;
91     t->tm_mday = u->tm_mday;
92     t->tm_mon = u->tm_mon;
93     t->tm_year = u->tm_year;
94     t->tm_wday = u->tm_wday;
95     t->tm_yday = u->tm_yday;
96     t->tm_isdst = u->tm_isdst;
97   }
98
99   return(epoch);
100 }
101 #endif /* !HAVE_MKTIME */
102
103
104
105 #ifndef HAVE_RENAME
106 /* Rename a file. (from libiberty in GNU binutils)  */
107  int rename(const char *zfrom, const char *zto)
108 {
109   if (link (zfrom, zto) < 0)
110     {
111       if (errno != EEXIST)
112         return -1;
113       if (unlink (zto) < 0
114           || link (zfrom, zto) < 0)
115         return -1;
116     }
117   return unlink (zfrom);
118 }
119 #endif
120
121
122 #ifndef HAVE_INNETGR
123 /*
124  * Search for a match in a netgroup. This replaces it on broken systems.
125  */
126  int innetgr(char *group,char *host,char *user,char *dom)
127 {
128         char *hst, *usr, *dm;
129   
130         setnetgrent(group);
131         while (getnetgrent(&hst, &usr, &dm)) {
132                 if (((host == 0) || (hst == 0) || !strcmp(host, hst)) &&
133                     ((user == 0) || (usr == 0) || !strcmp(user, usr)) &&
134                     ((dom == 0) || (dm == 0) || !strcmp(dom, dm))) {
135                         endnetgrent();
136                         return (1);
137                 }
138         }
139         endnetgrent();
140         return (0);
141 }
142 #endif
143
144
145
146 #ifndef HAVE_INITGROUPS
147 /****************************************************************************
148  some systems don't have an initgroups call 
149 ****************************************************************************/
150  int initgroups(char *name,gid_t id)
151 {
152 #ifndef HAVE_SETGROUPS
153         static int done;
154         if (!done) {
155                 DEBUG(1,("WARNING: running without setgroups\n"));
156                 done=1;
157         }
158         /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
159         return(0);
160 #else
161         gid_t  grouplst[NGROUPS_MAX];
162         int    i,j;
163         struct group *g;
164         char   *gr;
165         
166         grouplst[0] = id;
167         i = 1;
168         while (i < NGROUPS_MAX && 
169                ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
170                 if (g->gr_gid == id)
171                         continue;
172                 j = 0;
173                 gr = g->gr_mem[0];
174                 while (gr && (*gr != (char)NULL)) {
175                         if (strcmp(name,gr) == 0) {
176                                 grouplst[i] = g->gr_gid;
177                                 i++;
178                                 gr = (char *)NULL;
179                                 break;
180                         }
181                         gr = g->gr_mem[++j];
182                 }
183         }
184         endgrent();
185         return(setgroups(i,grouplst));
186 #endif
187 }
188 #endif
189
190
191 #if (defined(SecureWare) && defined(SCO))
192 /* This is needed due to needing the nap() function but we don't want
193    to include the Xenix libraries since that will break other things...
194    BTW: system call # 0x0c28 is the same as calling nap() */
195  long nap(long milliseconds) {
196          return syscall(0x0c28, milliseconds);
197  }
198 #endif
199
200
201 #ifndef HAVE_MEMMOVE
202 /*******************************************************************
203 safely copies memory, ensuring no overlap problems.
204 this is only used if the machine does not have it's own memmove().
205 this is not the fastest algorithm in town, but it will do for our
206 needs.
207 ********************************************************************/
208  void *memmove(void *dest,const void *src,int size)
209 {
210         unsigned long d,s;
211         int i;
212         if (dest==src || !size) return(dest);
213
214         d = (unsigned long)dest;
215         s = (unsigned long)src;
216
217         if ((d >= (s+size)) || (s >= (d+size))) {
218                 /* no overlap */
219                 memcpy(dest,src,size);
220                 return(dest);
221         }
222
223         if (d < s) {
224                 /* we can forward copy */
225                 if (s-d >= sizeof(int) && 
226                     !(s%sizeof(int)) && 
227                     !(d%sizeof(int)) && 
228                     !(size%sizeof(int))) {
229                         /* do it all as words */
230                         int *idest = (int *)dest;
231                         int *isrc = (int *)src;
232                         size /= sizeof(int);
233                         for (i=0;i<size;i++) idest[i] = isrc[i];
234                 } else {
235                         /* simplest */
236                         char *cdest = (char *)dest;
237                         char *csrc = (char *)src;
238                         for (i=0;i<size;i++) cdest[i] = csrc[i];
239                 }
240         } else {
241                 /* must backward copy */
242                 if (d-s >= sizeof(int) && 
243                     !(s%sizeof(int)) && 
244                     !(d%sizeof(int)) && 
245                     !(size%sizeof(int))) {
246                         /* do it all as words */
247                         int *idest = (int *)dest;
248                         int *isrc = (int *)src;
249                         size /= sizeof(int);
250                         for (i=size-1;i>=0;i--) idest[i] = isrc[i];
251                 } else {
252                         /* simplest */
253                         char *cdest = (char *)dest;
254                         char *csrc = (char *)src;
255                         for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
256                 }      
257         }
258         return(dest);
259 }
260 #endif
261
262 #ifndef HAVE_STRDUP
263 /****************************************************************************
264 duplicate a string
265 ****************************************************************************/
266  char *strdup(const char *s)
267 {
268         int len;
269         char *ret;
270
271         if (!s) return(NULL);
272
273         len = strlen(s)+1;
274         ret = (char *)malloc(len);
275         if (!ret) return(NULL);
276         memcpy(ret,s,len);
277         return(ret);
278 }
279 #endif
280