00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "replace.h"
00026
00027 #include "system/filesys.h"
00028 #include "system/time.h"
00029 #include "system/passwd.h"
00030 #include "system/syslog.h"
00031 #include "system/network.h"
00032 #include "system/locale.h"
00033 #include "system/wait.h"
00034
00035 void replace_dummy(void);
00036 void replace_dummy(void) {}
00037
00038 #ifndef HAVE_FTRUNCATE
00039
00040
00041
00042 int rep_ftruncate(int f, off_t l)
00043 {
00044 #ifdef HAVE_CHSIZE
00045 return chsize(f,l);
00046 #elif defined(F_FREESP)
00047 struct flock fl;
00048
00049 fl.l_whence = 0;
00050 fl.l_len = 0;
00051 fl.l_start = l;
00052 fl.l_type = F_WRLCK;
00053 return fcntl(f, F_FREESP, &fl);
00054 #else
00055 #error "you must have a ftruncate function"
00056 #endif
00057 }
00058 #endif
00059
00060
00061 #ifndef HAVE_STRLCPY
00062
00063
00064 size_t rep_strlcpy(char *d, const char *s, size_t bufsize)
00065 {
00066 size_t len = strlen(s);
00067 size_t ret = len;
00068 if (bufsize <= 0) return 0;
00069 if (len >= bufsize) len = bufsize-1;
00070 memcpy(d, s, len);
00071 d[len] = 0;
00072 return ret;
00073 }
00074 #endif
00075
00076 #ifndef HAVE_STRLCAT
00077
00078
00079
00080 size_t rep_strlcat(char *d, const char *s, size_t bufsize)
00081 {
00082 size_t len1 = strlen(d);
00083 size_t len2 = strlen(s);
00084 size_t ret = len1 + len2;
00085
00086 if (len1+len2 >= bufsize) {
00087 if (bufsize < (len1+1)) {
00088 return ret;
00089 }
00090 len2 = bufsize - (len1+1);
00091 }
00092 if (len2 > 0) {
00093 memcpy(d+len1, s, len2);
00094 d[len1+len2] = 0;
00095 }
00096 return ret;
00097 }
00098 #endif
00099
00100 #ifndef HAVE_MKTIME
00101
00102
00103
00104
00105
00106
00107 #define MINUTE 60
00108 #define HOUR 60*MINUTE
00109 #define DAY 24*HOUR
00110 #define YEAR 365*DAY
00111 time_t rep_mktime(struct tm *t)
00112 {
00113 struct tm *u;
00114 time_t epoch = 0;
00115 int n;
00116 int mon [] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
00117 y, m, i;
00118
00119 if(t->tm_year < 70)
00120 return((time_t)-1);
00121
00122 n = t->tm_year + 1900 - 1;
00123 epoch = (t->tm_year - 70) * YEAR +
00124 ((n / 4 - n / 100 + n / 400) - (1969 / 4 - 1969 / 100 + 1969 / 400)) * DAY;
00125
00126 y = t->tm_year + 1900;
00127 m = 0;
00128
00129 for(i = 0; i < t->tm_mon; i++) {
00130 epoch += mon [m] * DAY;
00131 if(m == 1 && y % 4 == 0 && (y % 100 != 0 || y % 400 == 0))
00132 epoch += DAY;
00133
00134 if(++m > 11) {
00135 m = 0;
00136 y++;
00137 }
00138 }
00139
00140 epoch += (t->tm_mday - 1) * DAY;
00141 epoch += t->tm_hour * HOUR + t->tm_min * MINUTE + t->tm_sec;
00142
00143 if((u = localtime(&epoch)) != NULL) {
00144 t->tm_sec = u->tm_sec;
00145 t->tm_min = u->tm_min;
00146 t->tm_hour = u->tm_hour;
00147 t->tm_mday = u->tm_mday;
00148 t->tm_mon = u->tm_mon;
00149 t->tm_year = u->tm_year;
00150 t->tm_wday = u->tm_wday;
00151 t->tm_yday = u->tm_yday;
00152 t->tm_isdst = u->tm_isdst;
00153 }
00154
00155 return(epoch);
00156 }
00157 #endif
00158
00159
00160 #ifndef HAVE_INITGROUPS
00161
00162
00163
00164 int rep_initgroups(char *name, gid_t id)
00165 {
00166 #ifndef HAVE_SETGROUPS
00167
00168 errno = ENOSYS;
00169 return -1;
00170 #else
00171
00172 #include <grp.h>
00173
00174 gid_t *grouplst = NULL;
00175 int max_gr = 32;
00176 int ret;
00177 int i,j;
00178 struct group *g;
00179 char *gr;
00180
00181 if((grouplst = malloc(sizeof(gid_t) * max_gr)) == NULL) {
00182 errno = ENOMEM;
00183 return -1;
00184 }
00185
00186 grouplst[0] = id;
00187 i = 1;
00188 while (i < max_gr && ((g = (struct group *)getgrent()) != (struct group *)NULL)) {
00189 if (g->gr_gid == id)
00190 continue;
00191 j = 0;
00192 gr = g->gr_mem[0];
00193 while (gr && (*gr != (char)NULL)) {
00194 if (strcmp(name,gr) == 0) {
00195 grouplst[i] = g->gr_gid;
00196 i++;
00197 gr = (char *)NULL;
00198 break;
00199 }
00200 gr = g->gr_mem[++j];
00201 }
00202 }
00203 endgrent();
00204 ret = setgroups(i, grouplst);
00205 free(grouplst);
00206 return ret;
00207 #endif
00208 }
00209 #endif
00210
00211
00212 #if (defined(SecureWare) && defined(SCO))
00213
00214
00215
00216 long nap(long milliseconds) {
00217 return syscall(0x0c28, milliseconds);
00218 }
00219 #endif
00220
00221
00222 #ifndef HAVE_MEMMOVE
00223
00224
00225
00226
00227
00228
00229 void *rep_memmove(void *dest,const void *src,int size)
00230 {
00231 unsigned long d,s;
00232 int i;
00233 if (dest==src || !size) return(dest);
00234
00235 d = (unsigned long)dest;
00236 s = (unsigned long)src;
00237
00238 if ((d >= (s+size)) || (s >= (d+size))) {
00239
00240 memcpy(dest,src,size);
00241 return(dest);
00242 }
00243
00244 if (d < s) {
00245
00246 if (s-d >= sizeof(int) &&
00247 !(s%sizeof(int)) &&
00248 !(d%sizeof(int)) &&
00249 !(size%sizeof(int))) {
00250
00251 int *idest = (int *)dest;
00252 int *isrc = (int *)src;
00253 size /= sizeof(int);
00254 for (i=0;i<size;i++) idest[i] = isrc[i];
00255 } else {
00256
00257 char *cdest = (char *)dest;
00258 char *csrc = (char *)src;
00259 for (i=0;i<size;i++) cdest[i] = csrc[i];
00260 }
00261 } else {
00262
00263 if (d-s >= sizeof(int) &&
00264 !(s%sizeof(int)) &&
00265 !(d%sizeof(int)) &&
00266 !(size%sizeof(int))) {
00267
00268 int *idest = (int *)dest;
00269 int *isrc = (int *)src;
00270 size /= sizeof(int);
00271 for (i=size-1;i>=0;i--) idest[i] = isrc[i];
00272 } else {
00273
00274 char *cdest = (char *)dest;
00275 char *csrc = (char *)src;
00276 for (i=size-1;i>=0;i--) cdest[i] = csrc[i];
00277 }
00278 }
00279 return(dest);
00280 }
00281 #endif
00282
00283 #ifndef HAVE_STRDUP
00284
00285
00286
00287 char *rep_strdup(const char *s)
00288 {
00289 size_t len;
00290 char *ret;
00291
00292 if (!s) return(NULL);
00293
00294 len = strlen(s)+1;
00295 ret = (char *)malloc(len);
00296 if (!ret) return(NULL);
00297 memcpy(ret,s,len);
00298 return(ret);
00299 }
00300 #endif
00301
00302 #ifndef WITH_PTHREADS
00303
00304 #ifdef REPLACE_INET_NTOA
00305 char *rep_inet_ntoa(struct in_addr ip)
00306 {
00307 uint8_t *p = (uint8_t *)&ip.s_addr;
00308 static char buf[18];
00309 slprintf(buf, 17, "%d.%d.%d.%d",
00310 (int)p[0], (int)p[1], (int)p[2], (int)p[3]);
00311 return buf;
00312 }
00313 #endif
00314 #endif
00315
00316 #ifndef HAVE_SETLINEBUF
00317 void rep_setlinebuf(FILE *stream)
00318 {
00319 setvbuf(stream, (char *)NULL, _IOLBF, 0);
00320 }
00321 #endif
00322
00323 #ifndef HAVE_VSYSLOG
00324 #ifdef HAVE_SYSLOG
00325 void rep_vsyslog (int facility_priority, const char *format, va_list arglist)
00326 {
00327 char *msg = NULL;
00328 vasprintf(&msg, format, arglist);
00329 if (!msg)
00330 return;
00331 syslog(facility_priority, "%s", msg);
00332 free(msg);
00333 }
00334 #endif
00335 #endif
00336
00337 #ifndef HAVE_STRNLEN
00338
00339
00340
00341 size_t rep_strnlen(const char *s, size_t max)
00342 {
00343 size_t len;
00344
00345 for (len = 0; len < max; len++) {
00346 if (s[len] == '\0') {
00347 break;
00348 }
00349 }
00350 return len;
00351 }
00352 #endif
00353
00354 #ifndef HAVE_STRNDUP
00355
00356
00357
00358 char *rep_strndup(const char *s, size_t n)
00359 {
00360 char *ret;
00361
00362 n = strnlen(s, n);
00363 ret = malloc(n+1);
00364 if (!ret)
00365 return NULL;
00366 memcpy(ret, s, n);
00367 ret[n] = 0;
00368
00369 return ret;
00370 }
00371 #endif
00372
00373 #ifndef HAVE_WAITPID
00374 int rep_waitpid(pid_t pid,int *status,int options)
00375 {
00376 return wait4(pid, status, options, NULL);
00377 }
00378 #endif
00379
00380 #ifndef HAVE_SETEUID
00381 int rep_seteuid(uid_t euid)
00382 {
00383 #ifdef HAVE_SETRESUID
00384 return setresuid(-1, euid, -1);
00385 #else
00386 # error "You need a seteuid function"
00387 #endif
00388 }
00389 #endif
00390
00391 #ifndef HAVE_SETEGID
00392 int rep_setegid(gid_t egid)
00393 {
00394 #ifdef HAVE_SETRESGID
00395 return setresgid(-1, egid, -1);
00396 #else
00397 # error "You need a setegid function"
00398 #endif
00399 }
00400 #endif
00401
00402
00403
00404
00405 #ifndef HAVE_CHROOT
00406 int rep_chroot(const char *dname)
00407 {
00408 errno = ENOSYS;
00409 return -1;
00410 }
00411 #endif
00412
00413
00414
00415
00416
00417 #ifndef HAVE_SECURE_MKSTEMP
00418 int rep_mkstemp(char *template)
00419 {
00420
00421
00422 char *p = mktemp(template);
00423 if (!p)
00424 return -1;
00425 return open(p, O_CREAT|O_EXCL|O_RDWR, 0600);
00426 }
00427 #endif
00428
00429 #ifndef HAVE_MKDTEMP
00430 char *rep_mkdtemp(char *template)
00431 {
00432 char *dname;
00433
00434 if ((dname = mktemp(template))) {
00435 if (mkdir(dname, 0700) >= 0) {
00436 return dname;
00437 }
00438 }
00439
00440 return NULL;
00441 }
00442 #endif
00443
00444 #ifndef HAVE_PREAD
00445 ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset)
00446 {
00447 if (lseek(__fd, __offset, SEEK_SET) != __offset) {
00448 return -1;
00449 }
00450 return read(__fd, __buf, __nbytes);
00451 }
00452 #endif
00453
00454 #ifndef HAVE_PWRITE
00455 ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset)
00456 {
00457 if (lseek(__fd, __offset, SEEK_SET) != __offset) {
00458 return -1;
00459 }
00460 return write(__fd, __buf, __nbytes);
00461 }
00462 #endif
00463
00464 #ifndef HAVE_STRCASESTR
00465 char *rep_strcasestr(const char *haystack, const char *needle)
00466 {
00467 const char *s;
00468 size_t nlen = strlen(needle);
00469 for (s=haystack;*s;s++) {
00470 if (toupper(*needle) == toupper(*s) &&
00471 strncasecmp(s, needle, nlen) == 0) {
00472 return (char *)((intptr_t)s);
00473 }
00474 }
00475 return NULL;
00476 }
00477 #endif
00478
00479 #ifndef HAVE_STRTOK_R
00480
00481 char *rep_strtok_r(char *s, const char *delim, char **save_ptr)
00482 {
00483 char *token;
00484
00485 if (s == NULL) s = *save_ptr;
00486
00487 s += strspn(s, delim);
00488 if (*s == '\0') {
00489 *save_ptr = s;
00490 return NULL;
00491 }
00492
00493 token = s;
00494 s = strpbrk(token, delim);
00495 if (s == NULL) {
00496 *save_ptr = token + strlen(token);
00497 } else {
00498 *s = '\0';
00499 *save_ptr = s + 1;
00500 }
00501
00502 return token;
00503 }
00504 #endif
00505
00506 #ifndef HAVE_STRTOLL
00507 long long int rep_strtoll(const char *str, char **endptr, int base)
00508 {
00509 #ifdef HAVE_STRTOQ
00510 return strtoq(str, endptr, base);
00511 #elif defined(HAVE___STRTOLL)
00512 return __strtoll(str, endptr, base);
00513 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
00514 return (long long int) strtol(str, endptr, base);
00515 #else
00516 # error "You need a strtoll function"
00517 #endif
00518 }
00519 #endif
00520
00521
00522 #ifndef HAVE_STRTOULL
00523 unsigned long long int rep_strtoull(const char *str, char **endptr, int base)
00524 {
00525 #ifdef HAVE_STRTOUQ
00526 return strtouq(str, endptr, base);
00527 #elif defined(HAVE___STRTOULL)
00528 return __strtoull(str, endptr, base);
00529 #elif SIZEOF_LONG == SIZEOF_LONG_LONG
00530 return (unsigned long long int) strtoul(str, endptr, base);
00531 #else
00532 # error "You need a strtoull function"
00533 #endif
00534 }
00535 #endif
00536
00537 #ifndef HAVE_SETENV
00538 int rep_setenv(const char *name, const char *value, int overwrite)
00539 {
00540 char *p;
00541 size_t l1, l2;
00542 int ret;
00543
00544 if (!overwrite && getenv(name)) {
00545 return 0;
00546 }
00547
00548 l1 = strlen(name);
00549 l2 = strlen(value);
00550
00551 p = malloc(l1+l2+2);
00552 if (p == NULL) {
00553 return -1;
00554 }
00555 memcpy(p, name, l1);
00556 p[l1] = '=';
00557 memcpy(p+l1+1, value, l2);
00558 p[l1+l2+1] = 0;
00559
00560 ret = putenv(p);
00561 if (ret != 0) {
00562 free(p);
00563 }
00564
00565 return ret;
00566 }
00567 #endif
00568
00569 #ifndef HAVE_UNSETENV
00570 int rep_unsetenv(const char *name)
00571 {
00572 extern char **environ;
00573 size_t len = strlen(name);
00574 size_t i;
00575 int found = 0;
00576
00577 for (i=0; (environ && environ[i]); i++) {
00578 if (found) {
00579 environ[i-1] = environ[i];
00580 continue;
00581 }
00582
00583 if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
00584 free(environ[i]);
00585 environ[i] = NULL;
00586 found = 1;
00587 continue;
00588 }
00589 }
00590
00591 return 0;
00592 }
00593 #endif
00594
00595 #ifndef HAVE_SOCKETPAIR
00596 int rep_socketpair(int d, int type, int protocol, int sv[2])
00597 {
00598 if (d != AF_UNIX) {
00599 errno = EAFNOSUPPORT;
00600 return -1;
00601 }
00602
00603 if (protocol != 0) {
00604 errno = EPROTONOSUPPORT;
00605 return -1;
00606 }
00607
00608 if (type != SOCK_STREAM) {
00609 errno = EOPNOTSUPP;
00610 return -1;
00611 }
00612
00613 return pipe(sv);
00614 }
00615 #endif