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