2 Unix SMB/Netbios implementation.
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.
24 extern int DEBUGLEVEL;
26 void replace_dummy(void);
27 void replace_dummy(void) {}
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)
42 return fcntl(f, F_FREESP, &fl);
48 /*******************************************************************
49 a mktime() replacement for those who don't have it - contributed by
50 C.A. Lademann <cal@zls.com>
51 ********************************************************************/
53 #define HOUR 60*MINUTE
56 time_t mktime(struct tm *t)
60 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
66 epoch = (t->tm_year - 70) * YEAR +
67 (t->tm_year / 4 - 70 / 4 - t->tm_year / 100) * DAY;
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))
83 epoch += (t->tm_mday - 1) * DAY;
84 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
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;
100 #endif /* !HAVE_MKTIME */
105 /* Rename a file. (from libiberty in GNU binutils) */
106 int rename(const char *zfrom, const char *zto)
108 if (link (zfrom, zto) < 0)
113 || link (zfrom, zto) < 0)
116 return unlink (zfrom);
123 * Search for a match in a netgroup. This replaces it on broken systems.
125 int innetgr(char *group,char *host,char *user,char *dom)
127 char *hst, *usr, *dm;
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))) {
145 #ifndef HAVE_INITGROUPS
146 /****************************************************************************
147 some systems don't have an initgroups call
148 ****************************************************************************/
149 int initgroups(char *name,gid_t id)
151 #ifndef HAVE_SETGROUPS
154 DEBUG(1,("WARNING: running without setgroups\n"));
157 /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
160 gid_t grouplst[NGROUPS_MAX];
167 while (i < NGROUPS_MAX &&
168 ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
173 while (gr && (*gr != (char)NULL)) {
174 if (strcmp(name,gr) == 0) {
175 grouplst[i] = g->gr_gid;
184 return(setgroups(i,grouplst));
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);
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
206 ********************************************************************/
207 void *memmove(void *dest,const void *src,int size)
211 if (dest==src || !size) return(dest);
213 d = (unsigned long)dest;
214 s = (unsigned long)src;
216 if ((d >= (s+size)) || (s >= (d+size))) {
218 memcpy(dest,src,size);
223 /* we can forward copy */
224 if (s-d >= sizeof(int) &&
227 !(size%sizeof(int))) {
228 /* do it all as words */
229 int *idest = (int *)dest;
230 int *isrc = (int *)src;
232 for (i=0;i<size;i++) idest[i] = isrc[i];
235 char *cdest = (char *)dest;
236 char *csrc = (char *)src;
237 for (i=0;i<size;i++) cdest[i] = csrc[i];
240 /* must backward copy */
241 if (d-s >= sizeof(int) &&
244 !(size%sizeof(int))) {
245 /* do it all as words */
246 int *idest = (int *)dest;
247 int *isrc = (int *)src;
249 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
252 char *cdest = (char *)dest;
253 char *csrc = (char *)src;
254 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
262 /****************************************************************************
264 ****************************************************************************/
265 char *strdup(const char *s)
270 if (!s) return(NULL);
273 ret = (char *)malloc(len);
274 if (!ret) return(NULL);
280 #ifdef REPLACE_INET_NTOA
281 char *rep_inet_ntoa(struct in_addr ip)
283 unsigned char *p = (unsigned char *)&ip.s_addr;
286 slprintf(buf, 17, "%d.%d.%d.%d",
287 (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
289 slprintf(buf, 17, "%d.%d.%d.%d",
290 (int)p[3], (int)p[2], (int)p[1], (int)p[0]);