don't list the IPC$ share in directory listings (it causes infinite
[Samba/gbeck.git] / source / lib / replace.c
blob6441efe44c7d02d550b3504012c156bf88a3de3a
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 replacement routines for broken systems
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 void replace_dummy(void)
31 #ifndef HAVE_FTRUNCATE
32 /*******************************************************************
33 ftruncate for operating systems that don't have it
34 ********************************************************************/
35 int ftruncate(int f,SMB_OFF_T l)
37 struct flock fl;
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);
45 #endif
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)
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;
64 if(t->tm_year < 70)
65 return((time_t)-1);
67 epoch = (t->tm_year - 70) * YEAR +
68 (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
70 y = t->tm_year;
71 m = 0;
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;
78 if(++m > 11) {
79 m = 0;
80 y++;
84 epoch += (t->tm_mday - 1) * DAY;
85 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
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;
99 return(epoch);
101 #endif /* !HAVE_MKTIME */
105 #ifndef HAVE_RENAME
106 /* Rename a file. (from libiberty in GNU binutils) */
107 int rename(const char *zfrom, const char *zto)
109 if (link (zfrom, zto) < 0)
111 if (errno != EEXIST)
112 return -1;
113 if (unlink (zto) < 0
114 || link (zfrom, zto) < 0)
115 return -1;
117 return unlink (zfrom);
119 #endif
122 #ifndef HAVE_INNETGR
124 * Search for a match in a netgroup. This replaces it on broken systems.
126 int innetgr(char *group,char *host,char *user,char *dom)
128 char *hst, *usr, *dm;
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);
139 endnetgrent();
140 return (0);
142 #endif
146 #ifndef HAVE_INITGROUPS
147 /****************************************************************************
148 some systems don't have an initgroups call
149 ****************************************************************************/
150 int initgroups(char *name,gid_t id)
152 #ifndef HAVE_SETGROUPS
153 static int done;
154 if (!done) {
155 DEBUG(1,("WARNING: running without setgroups\n"));
156 done=1;
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;
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;
181 gr = g->gr_mem[++j];
184 endgrent();
185 return(setgroups(i,grouplst));
186 #endif
188 #endif
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);
198 #endif
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)
210 unsigned long d,s;
211 int i;
212 if (dest==src || !size) return(dest);
214 d = (unsigned long)dest;
215 s = (unsigned long)src;
217 if ((d >= (s+size)) || (s >= (d+size))) {
218 /* no overlap */
219 memcpy(dest,src,size);
220 return(dest);
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];
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];
258 return(dest);
260 #endif
262 #ifndef HAVE_STRDUP
263 /****************************************************************************
264 duplicate a string
265 ****************************************************************************/
266 char *strdup(const char *s)
268 int len;
269 char *ret;
271 if (!s) return(NULL);
273 len = strlen(s)+1;
274 ret = (char *)malloc(len);
275 if (!ret) return(NULL);
276 memcpy(ret,s,len);
277 return(ret);
279 #endif
281 #ifdef REPLACE_INET_NTOA
282 char *rep_inet_ntoa(struct in_addr ip)
284 unsigned char *p = (unsigned char *)&ip.s_addr;
285 static char buf[18];
286 #if WORDS_BIGENDIAN
287 slprintf(buf, 17, "%d.%d.%d.%d",
288 (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
289 #else
290 slprintf(buf, 17, "%d.%d.%d.%d",
291 (int)p[3], (int)p[2], (int)p[1], (int)p[0]);
292 #endif
293 return buf;
295 #endif