2 Unix SMB/CIFS implementation.
3 replacement routines for broken systems
4 Copyright (C) Andrew Tridgell 1992-1998
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 void replace_dummy(void);
24 void replace_dummy(void) {}
26 #ifndef HAVE_FTRUNCATE
27 /*******************************************************************
28 ftruncate for operating systems that don't have it
29 ********************************************************************/
30 int ftruncate(int f
,SMB_OFF_T l
)
38 return fcntl(f
, F_FREESP
, &fl
);
40 #endif /* HAVE_FTRUNCATE */
44 /* like strncpy but does not 0 fill the buffer and always null
45 terminates. bufsize is the size of the destination buffer */
46 size_t strlcpy(char *d
, const char *s
, size_t bufsize
)
48 size_t len
= strlen(s
);
50 if (bufsize
<= 0) return 0;
51 if (len
>= bufsize
) len
= bufsize
-1;
59 /* like strncat but does not 0 fill the buffer and always null
60 terminates. bufsize is the length of the buffer, which should
61 be one more than the maximum resulting string length */
62 size_t strlcat(char *d
, const char *s
, size_t bufsize
)
64 size_t len1
= strlen(d
);
65 size_t len2
= strlen(s
);
66 size_t ret
= len1
+ len2
;
68 if (len1
+len2
>= bufsize
) {
69 len2
= bufsize
- (len1
+1);
72 memcpy(d
+len1
, s
, len2
);
80 /*******************************************************************
81 a mktime() replacement for those who don't have it - contributed by
82 C.A. Lademann <cal@zls.com>
83 Corrections by richard.kettlewell@kewill.com
84 ********************************************************************/
87 #define HOUR 60*MINUTE
90 time_t mktime(struct tm
*t
)
95 int mon
[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
101 n
= t
->tm_year
+ 1900 - 1;
102 epoch
= (t
->tm_year
- 70) * YEAR
+
103 ((n
/ 4 - n
/ 100 + n
/ 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY
;
105 y
= t
->tm_year
+ 1900;
108 for(i
= 0; i
< t
->tm_mon
; i
++) {
109 epoch
+= mon
[m
] * DAY
;
110 if(m
== 1 && y
% 4 == 0 && (y
% 100 != 0 || y
% 400 == 0))
119 epoch
+= (t
->tm_mday
- 1) * DAY
;
120 epoch
+= t
->tm_hour
* HOUR
+ t
->tm_min
* MINUTE
+ t
->tm_sec
;
122 if((u
= localtime(&epoch
)) != NULL
) {
123 t
->tm_sec
= u
->tm_sec
;
124 t
->tm_min
= u
->tm_min
;
125 t
->tm_hour
= u
->tm_hour
;
126 t
->tm_mday
= u
->tm_mday
;
127 t
->tm_mon
= u
->tm_mon
;
128 t
->tm_year
= u
->tm_year
;
129 t
->tm_wday
= u
->tm_wday
;
130 t
->tm_yday
= u
->tm_yday
;
131 t
->tm_isdst
= u
->tm_isdst
;
136 #endif /* !HAVE_MKTIME */
141 /* Rename a file. (from libiberty in GNU binutils) */
142 int rename(const char *zfrom
, const char *zto
)
144 if (link (zfrom
, zto
) < 0)
149 || link (zfrom
, zto
) < 0)
152 return unlink (zfrom
);
154 #endif /* HAVE_RENAME */
158 #if defined(HAVE_SETNETGRENT) && defined(HAVE_GETNETGRENT) && defined(HAVE_ENDNETGRENT)
160 * Search for a match in a netgroup. This replaces it on broken systems.
162 int innetgr(const char *group
,const char *host
,const char *user
,const char *dom
)
164 char *hst
, *usr
, *dm
;
167 while (getnetgrent(&hst
, &usr
, &dm
)) {
168 if (((host
== 0) || (hst
== 0) || !strcmp(host
, hst
)) &&
169 ((user
== 0) || (usr
== 0) || !strcmp(user
, usr
)) &&
170 ((dom
== 0) || (dm
== 0) || !strcmp(dom
, dm
))) {
178 #endif /* HAVE_SETNETGRENT HAVE_GETNETGRENT HAVE_ENDNETGRENT */
179 #endif /* HAVE_INNETGR */
183 #ifndef HAVE_INITGROUPS
184 /****************************************************************************
185 some systems don't have an initgroups call
186 ****************************************************************************/
187 int initgroups(char *name
,gid_t id
)
189 #ifndef HAVE_SETGROUPS
192 DEBUG(1,("WARNING: running without setgroups\n"));
195 /* yikes! no SETGROUPS or INITGROUPS? how can this work? */
197 #else /* HAVE_SETGROUPS */
198 gid_t
*grouplst
= NULL
;
199 int max_gr
= groups_max();
205 if((grouplst
= (gid_t
*)malloc(sizeof(gid_t
) * max_gr
)) == NULL
) {
206 DEBUG(0,("initgroups: malloc fail !\n"));
212 while (i
< max_gr
&& ((g
= (struct group
*)getgrent()) != (struct group
*)NULL
)) {
217 while (gr
&& (*gr
!= (char)NULL
)) {
218 if (strcmp(name
,gr
) == 0) {
219 grouplst
[i
] = g
->gr_gid
;
228 ret
= sys_setgroups(i
,grouplst
);
231 #endif /* HAVE_SETGROUPS */
233 #endif /* HAVE_INITGROUPS */
236 #if (defined(SecureWare) && defined(SCO))
237 /* This is needed due to needing the nap() function but we don't want
238 to include the Xenix libraries since that will break other things...
239 BTW: system call # 0x0c28 is the same as calling nap() */
240 long nap(long milliseconds
) {
241 return syscall(0x0c28, milliseconds
);
247 /*******************************************************************
248 safely copies memory, ensuring no overlap problems.
249 this is only used if the machine does not have it's own memmove().
250 this is not the fastest algorithm in town, but it will do for our
252 ********************************************************************/
253 void *memmove(void *dest
,const void *src
,int size
)
257 if (dest
==src
|| !size
) return(dest
);
259 d
= (unsigned long)dest
;
260 s
= (unsigned long)src
;
262 if ((d
>= (s
+size
)) || (s
>= (d
+size
))) {
264 memcpy(dest
,src
,size
);
269 /* we can forward copy */
270 if (s
-d
>= sizeof(int) &&
273 !(size
%sizeof(int))) {
274 /* do it all as words */
275 int *idest
= (int *)dest
;
276 int *isrc
= (int *)src
;
278 for (i
=0;i
<size
;i
++) idest
[i
] = isrc
[i
];
281 char *cdest
= (char *)dest
;
282 char *csrc
= (char *)src
;
283 for (i
=0;i
<size
;i
++) cdest
[i
] = csrc
[i
];
286 /* must backward copy */
287 if (d
-s
>= sizeof(int) &&
290 !(size
%sizeof(int))) {
291 /* do it all as words */
292 int *idest
= (int *)dest
;
293 int *isrc
= (int *)src
;
295 for (i
=size
-1;i
>=0;i
--) idest
[i
] = isrc
[i
];
298 char *cdest
= (char *)dest
;
299 char *csrc
= (char *)src
;
300 for (i
=size
-1;i
>=0;i
--) cdest
[i
] = csrc
[i
];
305 #endif /* HAVE_MEMMOVE */
308 /****************************************************************************
310 ****************************************************************************/
311 char *strdup(const char *s
)
316 if (!s
) return(NULL
);
319 ret
= (char *)malloc(len
);
320 if (!ret
) return(NULL
);
324 #endif /* HAVE_STRDUP */
326 #ifdef REPLACE_INET_NTOA
327 char *rep_inet_ntoa(struct in_addr ip
)
329 unsigned char *p
= (unsigned char *)&ip
.s_addr
;
331 slprintf(buf
, 17, "%d.%d.%d.%d",
332 (int)p
[0], (int)p
[1], (int)p
[2], (int)p
[3]);
335 #endif /* REPLACE_INET_NTOA */
339 #define ULONG_MAX ((unsigned long)(~0L)) /* 0xFFFFFFFF */
343 * Convert a string to an unsigned long integer.
344 * Taken from libg++ - libiberty code.
346 * Ignores `locale' stuff. Assumes that the upper and lower case
347 * alphabets and digits are each contiguous.
349 unsigned long strtoul(const char *nptr
, char **endptr
, int base
)
351 const char *s
= nptr
;
354 unsigned long cutoff
;
355 int neg
= 0, any
, cutlim
;
358 * See strtol for comments as to the logic used.
362 } while (isspace(c
));
368 if ((base
== 0 || base
== 16) &&
369 c
== '0' && (*s
== 'x' || *s
== 'X')) {
375 base
= c
== '0' ? 8 : 10;
376 cutoff
= (unsigned long)ULONG_MAX
/ (unsigned long)base
;
377 cutlim
= (int)((unsigned long)ULONG_MAX
% (unsigned long)base
);
378 for (acc
= 0, any
= 0;; c
= *s
++) {
382 c
-= isupper(c
) ? 'A' - 10 : 'a' - 10;
387 if (any
< 0 || acc
> cutoff
|| acc
== cutoff
&& c
> cutlim
)
401 *endptr
= (char *) (any
? s
- 1 : nptr
);
404 #endif /* HAVE_STRTOUL */
406 #ifndef HAVE_SETLINEBUF
407 int setlinebuf(FILE *stream
)
409 return setvbuf(stream
, (char *)NULL
, _IOLBF
, 0);
411 #endif /* HAVE_SETLINEBUF */
415 void vsyslog (int facility_priority
, char *format
, va_list arglist
)
418 vasprintf(&msg
, format
, arglist
);
421 syslog(facility_priority
, "%s", msg
);
424 #endif /* HAVE_SYSLOG */
425 #endif /* HAVE_VSYSLOG */
430 yes, I know this looks insane, but its really needed. The function in the
431 Linux timegm() manpage does not work on solaris.
433 time_t timegm(struct tm
*tm
)
441 tm3
= *localtime(&t
);
443 tm2
.tm_isdst
= tm3
.tm_isdst
;
452 int setenv(const char *name
, const char *value
, int overwrite
)
457 asprintf(&p
, "%s=%s", name
, value
);
459 if (overwrite
|| getenv(name
)) {
460 if (p
) ret
= putenv(p
);