/* Compatibility routines. * * IRC Services is copyright (c) 1996-2007 Andrew Church. * E-mail: * Parts written by Andrew Kempe and others. * This program is free but copyrighted software; see the file COPYING for * details. */ #include "services.h" #if !HAVE_HSTRERROR # include #endif /*************************************************************************/ #if !HAVE_HSTRERROR /* hstrerror: return an error message for the given h_errno code. */ const char *hstrerror(int h_errnum) { switch (h_errnum) { case HOST_NOT_FOUND: return "Host not found"; case TRY_AGAIN: return "Host not found, try again"; case NO_RECOVERY: return "Nameserver error"; case NO_DATA: return "No data of requested type"; default: return "Unknown error"; } } #endif /* !HAVE_HSTRERROR */ /*************************************************************************/ #if !HAVE_SNPRINTF /* [v]snprintf: Like [v]sprintf, but don't write more than len bytes * (including null terminator). Return the number of bytes * written. */ #if BAD_SNPRINTF int vsnprintf(char *buf, size_t len, const char *fmt, va_list args) { if (len <= 0) return 0; *buf = 0; #undef vsnprintf vsnprintf(buf, len, fmt, args); #define vsnprintf my_vsnprintf buf[len-1] = 0; return strlen(buf); } #endif /* BAD_SNPRINTF */ int snprintf(char *buf, size_t len, const char *fmt, ...) { va_list args; int ret; va_start(args, fmt); ret = vsnprintf(buf, len, fmt, args); va_end(args); return ret; } #endif /* !HAVE_SNPRINTF */ /*************************************************************************/ #if !HAVE_STRTOK /* glibc 2.2 (RedHat 7.0) has a broken strtok--it dies if called with a * NULL parameter after returning NULL once. glibc and possibly other * libraries also return non-NULL for strtok(NULL, "") even after * returning NULL for strtok(NULL, " "). */ char *strtok(char *str, const char *delim) { static char *current = NULL; char *ret; if (str) current = str; if (!current) return NULL; current += strspn(current, delim); ret = *current ? current : NULL; current += strcspn(current, delim); if (!*current) current = NULL; else *current++ = 0; return ret; } #endif /* !HAVE_STRTOK */ /*************************************************************************/ #if !HAVE_STRICMP && !HAVE_STRCASECMP /* stricmp, strnicmp: Case-insensitive versions of strcmp() and * strncmp(). */ int stricmp(const char *s1, const char *s2) { register int c; while ((c = tolower(*s1)) == tolower(*s2)) { if (c == 0) return 0; s1++; s2++; } if (c < tolower(*s2)) return -1; return 1; } int strnicmp(const char *s1, const char *s2, size_t len) { register int c; if (!len) return 0; while ((c = tolower(*s1)) == tolower(*s2) && len > 0) { if (c == 0 || --len == 0) return 0; s1++; s2++; } if (c < tolower(*s2)) return -1; return 1; } #endif /*************************************************************************/ #if !HAVE_STRDUP char *strdup(const char *s) { char *new = malloc(strlen(s)+1); if (new) strcpy(new, s); return new; } #endif /*************************************************************************/ #if !HAVE_STRSPN size_t strspn(const char *s, const char *accept) { size_t i = 0; while (*s && strchr(accept, *s)) ++i, ++s; return i; } size_t strcspn(const char *s, const char *reject) { size_t i = 0; while (*s && !strchr(reject, *s)) ++i, ++s; return i; } #endif /*************************************************************************/ #if !HAVE_STRERROR # if HAVE_SYS_ERRLIST extern char *sys_errlist[]; # endif char *strerror(int errnum) { # if HAVE_SYS_ERRLIST return sys_errlist[errnum]; # else static char buf[20]; snprintf(buf, sizeof(buf), "Error %d", errnum); return buf; # endif } #endif /*************************************************************************/ #if !HAVE_STRSIGNAL char *strsignal(int signum) { static char buf[32]; switch (signum) { case SIGHUP: strscpy(buf, "Hangup", sizeof(buf)); break; case SIGINT: strscpy(buf, "Interrupt", sizeof(buf)); break; case SIGQUIT: strscpy(buf, "Quit", sizeof(buf)); break; #ifdef SIGILL case SIGILL: strscpy(buf, "Illegal instruction", sizeof(buf)); break; #endif #ifdef SIGABRT case SIGABRT: strscpy(buf, "Abort", sizeof(buf)); break; #endif #if defined(SIGIOT) && (!defined(SIGABRT) || SIGIOT != SIGABRT) case SIGIOT: strscpy(buf, "IOT trap", sizeof(buf)); break; #endif #ifdef SIGBUS case SIGBUS: strscpy(buf, "Bus error", sizeof(buf)); break; #endif case SIGFPE: strscpy(buf, "Floating point exception", sizeof(buf)); break; case SIGKILL: strscpy(buf, "Killed", sizeof(buf)); break; case SIGUSR1: strscpy(buf, "User signal 1", sizeof(buf)); break; case SIGSEGV: strscpy(buf, "Segmentation fault", sizeof(buf));break; case SIGUSR2: strscpy(buf, "User signal 2", sizeof(buf)); break; case SIGPIPE: strscpy(buf, "Broken pipe", sizeof(buf)); break; case SIGALRM: strscpy(buf, "Alarm clock", sizeof(buf)); break; case SIGTERM: strscpy(buf, "Terminated", sizeof(buf)); break; case SIGSTOP: strscpy(buf, "Suspended (signal)", sizeof(buf));break; case SIGTSTP: strscpy(buf, "Suspended", sizeof(buf)); break; case SIGIO: strscpy(buf, "I/O error", sizeof(buf)); break; default: snprintf(buf, sizeof(buf), "Signal %d\n", signum); break; } return buf; } #endif /*************************************************************************/