#include "defs.h"
#include "ircaux.h"
#include "irc_std.h"
#define MAIN_SOURCE
#include "modval.h"
#ifndef HAVE_TPARM
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#ifndef MAX_PUSHED
#define MAX_PUSHED 32
#endif
#define ARG 1
#define NUM 2
#define INTEGER 1
#define STRING 2
#define MAX_LINE 640
typedef void* anyptr;
typedef struct stack_str {
int type;
int argnum;
int value;
} stack;
static stack S[MAX_PUSHED];
static stack vars['z'-'a'+1];
static int pos = 0;
static struct arg_str {
int type;
int integer;
char *string;
} arg_list[10];
static int argcnt;
static va_list tparm_args;
static int pusharg(int arg)
{
if (pos == MAX_PUSHED)
return 1;
S[pos].type = ARG;
S[pos++].argnum = arg;
return 0;
}
static int pushnum(int num)
{
if (pos == MAX_PUSHED)
return 1;
S[pos].type = NUM;
S[pos++].value = num;
return 0;
}
static int getarg(int argnum, int type, anyptr p)
{
while (argcnt < argnum) {
arg_list[argcnt].type = INTEGER;
arg_list[argcnt++].integer = (int) va_arg(tparm_args, int);
}
if (argcnt > argnum) {
if (arg_list[argnum].type != type)
return 1;
else if (type == STRING)
*(char **)p = arg_list[argnum].string;
else
*(int *)p = arg_list[argnum].integer;
} else {
arg_list[argcnt].type = type;
if (type == STRING)
*(char **)p = arg_list[argcnt++].string
= (char *) va_arg(tparm_args, char *);
else
*(int *)p = arg_list[argcnt++].integer = (int) va_arg(tparm_args, int);
}
return 0;
}
static int popstring(char **str)
{
if (pos-- == 0)
return 1;
if (S[pos].type != ARG)
return 1;
return(getarg(S[pos].argnum, STRING, (anyptr) str));
}
static int popnum(int *num)
{
if (pos-- == 0)
return 1;
switch (S[pos].type) {
case ARG:
return (getarg(S[pos].argnum, INTEGER, (anyptr) num));
case NUM:
*num = S[pos].value;
return 0;
}
return 1;
}
static int cvtchar(const char *sp, char *c)
{
switch(*sp) {
case '\\':
switch(*++sp) {
case '\'':
case '$':
case '\\':
case '%':
*c = *sp;
return 2;
case '\0':
*c = '\\';
return 1;
case '0':
if (sp[1] == '0' && sp[2] == '0') {
*c = '\0';
return 4;
}
*c = '\200';
return 2;
default:
*c = *sp;
return 2;
}
default:
*c = *sp;
return 1;
}
}
static int termcap;
char *tparm(const char *str, ...) {
static char OOPS[] = "OOPS";
static char buf[MAX_LINE];
register const char *sp;
register char *dp;
register char *fmt;
char conv_char;
char scan_for;
int scan_depth = 0, if_depth;
static int i, j;
static char *s, c;
char fmt_buf[MAX_LINE];
char sbuf[MAX_LINE];
if (!str)
return NULL;
va_start(tparm_args, str);
sp = str;
dp = buf;
scan_for = 0;
if_depth = 0;
argcnt = 0;
pos = 0;
termcap = 1;
while(*sp != '\0') {
switch(*sp) {
case '\\':
if (scan_for) {
if (*++sp != '\0')
sp++;
break;
}
*dp++ = *sp++;
if (*sp != '\0')
*dp++ = *sp++;
break;
case '%':
sp++;
if (scan_for) {
if (*sp == scan_for && if_depth == scan_depth) {
if (scan_for == ';')
if_depth--;
scan_for = 0;
} else if (*sp == '?')
if_depth++;
else if (*sp == ';') {
if (if_depth == 0)
return OOPS;
else
if_depth--;
}
sp++;
break;
}
fmt = NULL;
switch(*sp) {
case '%':
*dp++ = *sp++;
break;
case '+':
if (!termcap) {
if (popnum(&j) || popnum(&i))
return OOPS;
i += j;
if (pushnum(i))
return OOPS;
sp++;
break;
}
;
case 'C':
if (*sp == 'C') {
if (getarg(termcap - 1, INTEGER, &i))
return OOPS;
if (i >= 96) {
i /= 96;
if (i == '$')
*dp++ = '\\';
*dp++ = i;
}
}
fmt = "%c";
case 'a':
if (!termcap)
return OOPS;
if (getarg(termcap - 1, INTEGER, (anyptr) &i))
return OOPS;
if (*++sp == '\0')
return OOPS;
if ((sp[1] == 'p' || sp[1] == 'c')
&& sp[2] != '\0' && fmt == NULL) {
int val, lc;
if (sp[1] == 'p'
&& getarg(termcap - 1 + sp[2] - '@',
INTEGER, (anyptr) &val))
return OOPS;
if (sp[1] == 'c') {
lc = cvtchar(sp + 2, &c) + 2;
val = c & 0177;
} else
lc = 2;
switch(sp[0]) {
case '=':
break;
case '+':
val = i + val;
break;
case '-':
val = i - val;
break;
case '*':
val = i * val;
break;
case '/':
val = i / val;
break;
default:
lc = cvtchar(sp, &c);
val = c + i;
break;
}
arg_list[termcap - 1].integer = val;
sp += lc;
break;
}
sp += cvtchar(sp, &c);
arg_list[termcap - 1].integer = c + i;
if (fmt == NULL)
break;
sp--;
case '-':
if (!termcap) {
if (popnum(&j) || popnum(&i))
return OOPS;
i -= j;
if (pushnum(i))
return OOPS;
sp++;
break;
}
fmt = "%c";
case 's':
if (termcap && (fmt == NULL || *sp == '-')) {
if (getarg(termcap - 1, INTEGER, &i))
return OOPS;
if (*++sp == '\0')
return OOPS;
sp += cvtchar(sp, &c);
arg_list[termcap - 1].integer = c - i;
if (fmt == NULL)
break;
sp--;
}
if (!termcap)
return OOPS;
;
case '.':
if (termcap && fmt == NULL)
fmt = "%c";
;
case 'd':
if (termcap && fmt == NULL)
fmt = "%d";
;
case '2':
if (termcap && fmt == NULL)
fmt = "%02d";
;
case '3':
if (termcap && fmt == NULL)
fmt = "%03d";
;
case ':': case ' ': case '#': case 'u':
case 'x': case 'X': case 'o': case 'c':
case '0': case '1': case '4': case '5':
case '6': case '7': case '8': case '9':
if (fmt == NULL) {
if (termcap)
return OOPS;
if (*sp == ':')
sp++;
fmt = fmt_buf;
*fmt++ = '%';
while(*sp != 's' && *sp != 'x' && *sp != 'X' && *sp != 'd' && *sp != 'o' && *sp != 'c' && *sp != 'u') {
if (*sp == '\0')
return OOPS;
*fmt++ = *sp++;
}
*fmt++ = *sp;
*fmt = '\0';
fmt = fmt_buf;
}
conv_char = fmt[strlen(fmt) - 1];
if (conv_char == 's') {
if (popstring(&s))
return OOPS;
sprintf(sbuf, fmt, s);
} else {
if (termcap) {
if (getarg(termcap++ - 1,
INTEGER, &i))
return OOPS;
} else
if (popnum(&i))
return OOPS;
if (i == 0 && conv_char == 'c')
*sbuf = 0;
else
sprintf(sbuf, fmt, i);
}
sp++;
fmt = sbuf;
while(*fmt != '\0') {
if (*fmt == '$')
*dp++ = '\\';
*dp++ = *fmt++;
}
break;
case 'r':
if (!termcap || getarg(1, INTEGER, &i))
return OOPS;
arg_list[1].integer = arg_list[0].integer;
arg_list[0].integer = i;
sp++;
break;
case 'i':
if (getarg(1, INTEGER, &i)
|| arg_list[0].type != INTEGER)
return OOPS;
arg_list[1].integer++;
arg_list[0].integer++;
sp++;
break;
case 'n':
if (!termcap || getarg(1, INTEGER, &i))
return OOPS;
arg_list[0].integer ^= 0140;
arg_list[1].integer ^= 0140;
sp++;
break;
case '>':
if (!termcap) {
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i > j);
if (pushnum(i))
return OOPS;
sp++;
break;
}
if (getarg(termcap-1, INTEGER, &i))
return OOPS;
sp += cvtchar(sp, &c);
if (i > c) {
sp += cvtchar(sp, &c);
arg_list[termcap-1].integer += c;
} else
sp += cvtchar(sp, &c);
sp++;
break;
case 'B':
if (!termcap || getarg(termcap-1, INTEGER, &i))
return OOPS;
arg_list[termcap-1].integer = 16*(i/10)+i%10;
sp++;
break;
case 'D':
if (!termcap || getarg(termcap-1, INTEGER, &i))
return OOPS;
arg_list[termcap-1].integer = i - 2 * (i % 16);
sp++;
break;
case 'p':
if (termcap > 1)
return OOPS;
if (*++sp == '\0')
return OOPS;
if (*sp == '0')
i = 9;
else
i = *sp - '1';
if (i < 0 || i > 9)
return OOPS;
if (pusharg(i))
return OOPS;
termcap = 0;
sp++;
break;
case 'P':
if (termcap || *++sp == '\0')
return OOPS;
i = *sp++ - 'a';
if (i < 0 || i > 25)
return OOPS;
if (pos-- == 0)
return OOPS;
switch(vars[i].type = S[pos].type) {
case ARG:
vars[i].argnum = S[pos].argnum;
break;
case NUM:
vars[i].value = S[pos].value;
break;
}
break;
case 'g':
if (termcap || *++sp == '\0')
return OOPS;
i = *sp++ - 'a';
if (i < 0 || i > 25)
return OOPS;
switch(vars[i].type) {
case ARG:
if (pusharg(vars[i].argnum))
return OOPS;
break;
case NUM:
if (pushnum(vars[i].value))
return OOPS;
break;
}
break;
case '\'':
if (termcap > 1)
return OOPS;
if (*++sp == '\0')
return OOPS;
sp += cvtchar(sp, &c);
if (pushnum(c) || *sp++ != '\'')
return OOPS;
termcap = 0;
break;
case '{':
if (termcap > 1)
return OOPS;
i = 0;
sp++;
while(isdigit((unsigned char)*sp))
i = 10 * i + *sp++ - '0';
if (*sp++ != '}' || pushnum(i))
return OOPS;
termcap = 0;
break;
case 'l':
if (termcap || popstring(&s))
return OOPS;
i = strlen(s);
if (pushnum(i))
return OOPS;
sp++;
break;
case '*':
if (termcap || popnum(&j) || popnum(&i))
return OOPS;
i *= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '/':
if (termcap || popnum(&j) || popnum(&i))
return OOPS;
i /= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case 'm':
if (termcap) {
if (getarg(1, INTEGER, &i))
return OOPS;
arg_list[0].integer ^= 0177;
arg_list[1].integer ^= 0177;
sp++;
break;
}
if (popnum(&j) || popnum(&i))
return OOPS;
i %= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '&':
if (popnum(&j) || popnum(&i))
return OOPS;
i &= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '|':
if (popnum(&j) || popnum(&i))
return OOPS;
i |= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '^':
if (popnum(&j) || popnum(&i))
return OOPS;
i ^= j;
if (pushnum(i))
return OOPS;
sp++;
break;
case '=':
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i == j);
if (pushnum(i))
return OOPS;
sp++;
break;
case '<':
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i < j);
if (pushnum(i))
return OOPS;
sp++;
break;
case 'A':
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i && j);
if (pushnum(i))
return OOPS;
sp++;
break;
case 'O':
if (popnum(&j) || popnum(&i))
return OOPS;
i = (i || j);
if (pushnum(i))
return OOPS;
sp++;
break;
case '!':
if (popnum(&i))
return OOPS;
i = !i;
if (pushnum(i))
return OOPS;
sp++;
break;
case '~':
if (popnum(&i))
return OOPS;
i = ~i;
if (pushnum(i))
return OOPS;
sp++;
break;
case '?':
if (termcap > 1)
return OOPS;
termcap = 0;
if_depth++;
sp++;
break;
case 't':
if (popnum(&i) || if_depth == 0)
return OOPS;
if (!i) {
scan_for = 'e';
scan_depth = if_depth;
}
sp++;
break;
case 'e':
if (if_depth == 0)
return OOPS;
scan_for = ';';
scan_depth = if_depth;
sp++;
break;
case ';':
if (if_depth-- == 0)
return OOPS;
sp++;
break;
case 'b':
if (--termcap < 1)
return OOPS;
sp++;
break;
case 'f':
if (!termcap++)
return OOPS;
sp++;
break;
}
break;
default:
if (scan_for)
sp++;
else
*dp++ = *sp++;
break;
}
}
va_end(tparm_args);
*dp = '\0';
return buf;
}
#endif
#ifndef HAVE_STRTOUL
unsigned long strtoul (const char *nptr, char **endptr, int base)
{
const char *s;
unsigned long acc, cutoff;
int c;
int neg, any, cutlim;
s = nptr;
do
c = *s++;
while (isspace(c));
if (c == '-')
{
neg = 1;
c = *s++;
}
else
{
neg = 0;
if (c == '+')
c = *s++;
}
if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X'))
{
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
#ifndef ULONG_MAX
#define ULONG_MAX (unsigned long) -1
#endif
cutoff = ULONG_MAX / (unsigned long)base;
cutlim = ULONG_MAX % (unsigned long)base;
for (acc = 0, any = 0;; c = *s++)
{
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0)
continue;
if (acc > cutoff || acc == cutoff && c > cutlim)
{
any = -1;
acc = ULONG_MAX;
errno = ERANGE;
}
else
{
any = 1;
acc *= (unsigned long)base;
acc += c;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != 0)
*endptr = (char *) (any ? s - 1 : nptr);
return (acc);
}
#endif
#ifndef HAVE_SCANDIR
#define RESIZEDIR(x, y, z) x = realloc((void *)(x), sizeof(y) * (z))
#define INITIAL_SIZE 30
typedef struct dirent DIRENT;
#if defined(_SCO_DS)
# undef DIRSIZ
#endif
#ifndef DIRSIZ
# define DIRSIZ(d) (sizeof(DIRENT) + strlen(d->d_name) + 1)
#endif
int scandir (const char *name,
DIRENT ***list,
int (*selector) (DIRENT *),
int (*sorter) (const void *, const void *))
{
DIRENT **names;
static DIRENT *e;
DIR *dp;
int i;
int size = INITIAL_SIZE;
if (!(names = (DIRENT **)malloc(size * sizeof(DIRENT *))))
return -1;
if (access(name, R_OK | X_OK))
return -1;
if (!(dp = opendir(name)))
return -1;
for (i = 0; (e = readdir(dp));)
{
if (!selector || (*selector)(e))
{
if (i + 1 >= size)
{
size <<= 1;
RESIZEDIR(names, DIRENT *, size);
if (!names)
{
closedir(dp);
return (-1);
}
}
names[i] = (DIRENT *)malloc(DIRSIZ(e));
if (names[i] == NULL)
{
int j;
for (j = 0; j < i; j++)
free(names[j]);
free(names);
closedir(dp);
return -1;
}
memcpy(names[i], e, DIRSIZ(e));
i++;
}
}
RESIZEDIR(names, DIRENT *, i + 2);
names[i + 1] = 0;
*list = names;
closedir(dp);
if (i && sorter)
qsort(names, i, sizeof(DIRENT *), sorter);
return i;
}
#endif
#if 1
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
int bsd_setenv(const char *name, const char *value, int rewrite);
__inline__ static char *__findenv(const char *name, int *offset)
{
extern char **environ;
register int len, i;
register const char *np;
register char **p, *cp;
if (name == NULL || environ == NULL)
return (NULL);
for (np = name; *np && *np != '='; ++np)
continue;
len = np - name;
for (p = environ; (cp = *p) != NULL; ++p) {
for (np = name, i = len; i && *cp; i--)
if (*cp++ != *np++)
break;
if (i == 0 && *cp++ == '=') {
*offset = p - environ;
return (cp);
}
}
return (NULL);
}
char *bsd_getenv(const char *name)
{
int offset;
return (__findenv(name, &offset));
}
int bsd_setenv(const char *name, const char *value, int rewrite)
{
extern char **environ;
static int alloced;
register char *c;
int l_value, offset;
if (*value == '=')
++value;
l_value = strlen(value);
if ((c = __findenv(name, &offset))) {
if (!rewrite)
return (0);
if (strlen(c) >= l_value) {
while ( (*c++ = *value++) );
return (0);
}
} else {
register int cnt;
register char **p;
for (p = environ, cnt = 0; *p; ++p, ++cnt);
if (alloced) {
environ = (char **)realloc((char *)environ,
(size_t)(sizeof(char *) * (cnt + 2)));
if (!environ)
return (-1);
}
else {
alloced = 1;
p = malloc((size_t)(sizeof(char *) * (cnt + 2)));
if (!p)
return (-1);
memcpy(p, environ, cnt * sizeof(char *));
environ = p;
}
environ[cnt + 1] = NULL;
offset = cnt;
}
for (c = (char *)name; *c && *c != '='; ++c);
if (!(environ[offset] =
malloc((size_t)((int)(c - name) + l_value + 2))))
return (-1);
for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
for (*c++ = '='; (*c++ = *value++); );
return (0);
}
int bsd_putenv(const char *str)
{
char *p, *equal;
int rval;
if ((p = strdup(str)) == NULL)
return (-1);
if ((equal = strchr(p, '=')) == NULL) {
free(p);
return (-1);
}
*equal = '\0';
rval = bsd_setenv(p, equal + 1, 1);
free(p);
return (rval);
}
void bsd_unsetenv(const char *name)
{
extern char **environ;
register char **p;
int offset;
while (__findenv(name, &offset))
for (p = &environ[offset];; ++p)
if (!(*p = *(p + 1)))
break;
}
#endif
#if !defined(HAVE_INET_ATON)
int inet_aton(const char *cp, struct in_addr *addr)
{
unsigned long val;
int base, n;
char c;
unsigned parts[4];
unsigned *pp = parts;
c = *cp;
for (;;) {
if (!isdigit((unsigned char)c))
return (0);
val = 0; base = 10;
if (c == '0') {
c = *++cp;
if (c == 'x' || c == 'X')
base = 16, c = *++cp;
else
base = 8;
}
for (;;) {
if (isascii((unsigned char)c) && isdigit((unsigned char)c)) {
val = (val * base) + (c - '0');
c = *++cp;
} else if (base == 16 && isascii((unsigned char)c) && isxdigit((unsigned char)c)) {
val = (val << 4) |
(c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
c = *++cp;
} else
break;
}
if (c == '.') {
if (pp >= parts + 3)
return (0);
*pp++ = val;
c = *++cp;
} else
break;
}
if (c != '\0' && (!isascii((unsigned char)c) || !isspace((unsigned char)c)))
return (0);
n = pp - parts + 1;
switch (n) {
case 0:
return (0);
case 1:
break;
case 2:
if (val > 0xffffff)
return (0);
val |= parts[0] << 24;
break;
case 3:
if (val > 0xffff)
return (0);
val |= (parts[0] << 24) | (parts[1] << 16);
break;
case 4:
if (val > 0xff)
return (0);
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
break;
}
if (addr)
addr->s_addr = htonl(val);
return (1);
}
#endif
#if 0
int vsnprintf (char *str, size_t size, const char *format, va_list ap)
{
int ret = vsprintf(str, format, ap);
if (ret == (int)str && strlen(str) > size)
ircpanic("Buffer overflow in vsnprintf");
if (ret != (int)str && ret > size)
ircpanic("Buffer overflow in vsnprintf");
return ret;
}
#endif
#if 0
int snprintf (char *str, size_t size, const char *format, ...)
{
int ret;
va_list args;
va_start(args, format);
ret = vsnprintf(str, size, format, args);
va_end(args);
return ret;
}
#endif
#ifndef HAVE_VSNPRINTF
#undef isdigit
#define isdigit(ch) ((ch) >= '0' && (ch) <= '9')
#define MINUS_FLAG 0x1
#define PLUS_FLAG 0x2
#define SPACE_FLAG 0x4
#define HASH_FLAG 0x8
#define CONV_TO_SHORT 0x10
#define IS_LONG_INT 0x20
#define IS_LONG_DOUBLE 0x40
#define X_UPCASE 0x80
#define IS_NEGATIVE 0x100
#define UNSIGNED_DEC 0x200
#define ZERO_PADDING 0x400
#undef sprintf
static int
snprintf_get_directive(const char *str, int *flags, int *width,
int *precision, char *format_char, va_list *ap)
{
int length, value;
const char *orig_str = str;
*flags = 0;
*width = 0;
*precision = 0;
*format_char = (char)0;
if (*str == '%')
{
str++;
while (*str == '-' || *str == '+' || *str == ' '
|| *str == '#' || *str == '0')
{
switch (*str)
{
case '-':
*flags |= MINUS_FLAG;
break;
case '+':
*flags |= PLUS_FLAG;
break;
case ' ':
*flags |= SPACE_FLAG;
break;
case '#':
*flags |= HASH_FLAG;
break;
case '0':
*flags |= ZERO_PADDING;
break;
}
str++;
}
if ((*flags & MINUS_FLAG) && (*flags & ZERO_PADDING))
*flags &= ~ZERO_PADDING;
if (isdigit(*str))
{
for (value = 0; *str && isdigit(*str); str++)
value = 10 * value + *str - '0';
*width = value;
}
else
if (*str == '*')
{
*width = va_arg(*ap, int);
str++;
}
if (*str == '.')
{
str++;
if (isdigit(*str))
{
for (value = 0; *str && isdigit(*str); str++)
value = 10 * value + *str - '0';
*precision = value;
}
else
if (*str == '*')
{
*precision = va_arg(*ap, int);
str++;
}
else
*precision = 0;
}
if (*str == 'h')
{
*flags |= CONV_TO_SHORT;
str++;
}
else
{
if (*str == 'l')
{
*flags |= IS_LONG_INT;
str++;
}
else
{
if (*str == 'L')
{
*flags |= IS_LONG_DOUBLE;
str++;
}
}
}
*format_char = *str;
str++;
length = str - orig_str;
switch (*format_char)
{
case 'i': case 'd': case 'o': case 'u': case 'x': case 'X':
case 'f': case 'e': case 'E': case 'g': case 'G':
case 'c': case 's': case 'p': case 'n':
if (*format_char == 'X')
*flags |= X_UPCASE;
if (*format_char == 'o')
*flags |= UNSIGNED_DEC;
return length;
default:
return 0;
}
}
else
{
return 0;
}
}
static int
snprintf_convert_ulong(char *buffer, size_t buf_size, int base, char *digits,
unsigned long int ulong_val, int flags, int width,
int precision)
{
int tmp_buf_len = 100 + width, len;
char *tmp_buf, *tmp_buf_ptr, prefix[2];
tmp_buf = alloca(tmp_buf_len+1);
prefix[0] = '\0';
prefix[1] = '\0';
tmp_buf_ptr = tmp_buf + tmp_buf_len;
do
{
*--tmp_buf_ptr = digits[ulong_val % base];
ulong_val /= base;
precision--;
}
while ((ulong_val != 0 || precision > 0) && tmp_buf_ptr > tmp_buf);
if (!(flags & IS_NEGATIVE))
{
if (base == 16 && (flags & HASH_FLAG))
{
if (flags && X_UPCASE)
{
prefix[0] = 'x';
prefix[1] = '0';
}
else
{
prefix[0] = 'X';
prefix[1] = '0';
}
}
if (base == 8 && (flags & HASH_FLAG))
prefix[0] = '0';
if (base == 10 && !(flags & UNSIGNED_DEC) && (flags & PLUS_FLAG))
prefix[0] = '+';
else
if (base == 10 && !(flags & UNSIGNED_DEC) && (flags & SPACE_FLAG))
prefix[0] = ' ';
}
else
prefix[0] = '-';
if (prefix[0] != '\0' && tmp_buf_ptr > tmp_buf)
{
*--tmp_buf_ptr = prefix[0];
if (prefix[1] != '\0' && tmp_buf_ptr > tmp_buf)
*--tmp_buf_ptr = prefix[1];
}
len = (tmp_buf + tmp_buf_len) - tmp_buf_ptr;
if (len <= buf_size)
{
if (len < width)
{
if (width > (tmp_buf_ptr - tmp_buf))
width = (tmp_buf_ptr - tmp_buf);
if (flags & MINUS_FLAG)
{
memcpy(buffer, tmp_buf_ptr, len);
memset(buffer + len, (flags & ZERO_PADDING)?'0':' ',
width - len);
len = width;
}
else
{
memset(buffer, (flags & ZERO_PADDING)?'0':' ',
width - len);
memcpy(buffer + width - len, tmp_buf_ptr, len);
len = width;
}
}
else
{
memcpy(buffer, tmp_buf_ptr, len);
}
return len;
}
else
{
memcpy(buffer, tmp_buf_ptr, buf_size);
return buf_size;
}
}
#ifndef KERNEL
static int
snprintf_convert_float(char *buffer, size_t buf_size,
double dbl_val, int flags, int width,
int precision, char format_char)
{
char print_buf[160], print_buf_len = 0;
char format_str[80], *format_str_ptr;
format_str_ptr = format_str;
if (width > 155) width = 155;
if (precision <= 0)
precision = 6;
if (precision > 120)
precision = 120;
*format_str_ptr++ = '%';
if (flags & MINUS_FLAG)
*format_str_ptr++ = '-';
if (flags & PLUS_FLAG)
*format_str_ptr++ = '+';
if (flags & SPACE_FLAG)
*format_str_ptr++ = ' ';
if (flags & ZERO_PADDING)
*format_str_ptr++ = '0';
if (flags & HASH_FLAG)
*format_str_ptr++ = '#';
sprintf(format_str_ptr, "%d.%d", width, precision);
format_str_ptr += strlen(format_str_ptr);
if (flags & IS_LONG_DOUBLE)
*format_str_ptr++ = 'L';
*format_str_ptr++ = format_char;
*format_str_ptr++ = '\0';
sprintf(print_buf, format_str, dbl_val);
print_buf_len = strlen(print_buf);
if (print_buf_len > buf_size)
print_buf_len = buf_size;
strncpy(buffer, print_buf, print_buf_len);
return print_buf_len;
}
#endif
#endif
#ifndef HAVE_SNPRINTF
extern int snprintf(char *str, size_t size, const char *format, ...)
{
int ret;
va_list ap;
va_start(ap, format);
ret = vsnprintf(str, size, format, ap);
va_end(ap);
return ret;
}
#endif
#ifndef HAVE_VSNPRINTF
extern int vsnprintf(char *str, size_t size, const char *format, va_list ap)
{
int status, left = (int)size - 1;
const char *format_ptr = format;
int flags, width, precision, i;
char format_char, *orig_str = str;
int *int_ptr;
long int long_val;
unsigned long int ulong_val;
char *str_val;
#ifndef KERNEL
double dbl_val;
#endif
flags = 0;
while (format_ptr < format + strlen(format))
{
if (*format_ptr == '%')
{
if (format_ptr[1] == '%' && left > 0)
{
*str++ = '%';
left--;
format_ptr += 2;
}
else
{
if (left <= 0)
{
*str = '\0';
return size;
}
else
{
status = snprintf_get_directive(format_ptr, &flags, &width,
&precision, &format_char,
&ap);
if (status == 0)
{
*str = '\0';
return 0;
}
else
{
format_ptr += status;
switch (format_char)
{
case 'i': case 'd':
if (flags & IS_LONG_INT)
long_val = va_arg(ap, long int);
else
long_val = (long int) va_arg(ap, int);
if (long_val < 0)
{
ulong_val = (unsigned long int) -long_val;
flags |= IS_NEGATIVE;
}
else
{
ulong_val = (unsigned long int) long_val;
}
status = snprintf_convert_ulong(str, left, 10,
"0123456789",
ulong_val, flags,
width, precision);
str += status;
left -= status;
break;
case 'x':
if (flags & IS_LONG_INT)
ulong_val = va_arg(ap, unsigned long int);
else
ulong_val =
(unsigned long int) va_arg(ap, unsigned int);
status = snprintf_convert_ulong(str, left, 16,
"0123456789abcdef",
ulong_val, flags,
width, precision);
str += status;
left -= status;
break;
case 'X':
if (flags & IS_LONG_INT)
ulong_val = va_arg(ap, unsigned long int);
else
ulong_val =
(unsigned long int) va_arg(ap, unsigned int);
status = snprintf_convert_ulong(str, left, 16,
"0123456789ABCDEF",
ulong_val, flags,
width, precision);
str += status;
left -= status;
break;
case 'o':
if (flags & IS_LONG_INT)
ulong_val = va_arg(ap, unsigned long int);
else
ulong_val =
(unsigned long int) va_arg(ap, unsigned int);
status = snprintf_convert_ulong(str, left, 8,
"01234567",
ulong_val, flags,
width, precision);
str += status;
left -= status;
break;
case 'u':
if (flags & IS_LONG_INT)
ulong_val = va_arg(ap, unsigned long int);
else
ulong_val =
(unsigned long int) va_arg(ap, unsigned int);
status = snprintf_convert_ulong(str, left, 10,
"0123456789",
ulong_val, flags,
width, precision);
str += status;
left -= status;
break;
case 'p':
break;
case 'c':
if (flags & IS_LONG_INT)
ulong_val = va_arg(ap, unsigned long int);
else
ulong_val =
(unsigned long int) va_arg(ap, unsigned int);
*str++ = (unsigned char)ulong_val;
left--;
break;
case 's':
str_val = va_arg(ap, char *);
if (str_val == NULL)
str_val = "(null)";
if (precision == 0)
precision = strlen(str_val);
else
{
if (memchr(str_val, 0, precision) != NULL)
precision = strlen(str_val);
}
if (precision > left)
precision = left;
if (width > left)
width = left;
if (width < precision)
width = precision;
i = width - precision;
if (flags & MINUS_FLAG)
{
strncpy(str, str_val, precision);
memset(str + precision,
(flags & ZERO_PADDING)?'0':' ', i);
}
else
{
memset(str, (flags & ZERO_PADDING)?'0':' ', i);
strncpy(str + i, str_val, precision);
}
str += width;
left -= width;
break;
case 'n':
int_ptr = va_arg(ap, int *);
*int_ptr = str - orig_str;
break;
#ifndef KERNEL
case 'f': case 'e': case 'E': case 'g': case 'G':
if (flags & IS_LONG_DOUBLE)
dbl_val = (double) va_arg(ap, long double);
else
dbl_val = va_arg(ap, double);
status =
snprintf_convert_float(str, left, dbl_val, flags,
width, precision,
format_char);
str += status;
left -= status;
break;
#endif
default:
break;
}
}
}
}
}
else
{
if (left > 0)
{
*str++ = *format_ptr++;
left--;
}
else
{
*str = '\0';
return size;
}
}
}
*str = '\0';
return size - left - 1;
}
#endif
#ifndef HAVE_STRLCPY
size_t strlcpy (char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
if (n == 0) {
if (siz != 0)
*d = '\0';
while (*s++)
;
}
return(s - src - 1);
}
#endif
#ifndef HAVE_STRLCAT
size_t strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
while (*d != '\0' && n-- != 0)
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src));
}
#endif
#ifndef HAVE_SETSID
int setsid (void)
{
#ifdef __EMX__
return 0;
#else
return setpgrp(getpid(), getpid());
#endif
}
#endif
#ifndef HAVE_MEMMOVE
typedef int word;
#define wsize sizeof(word)
#define wmask (wsize - 1)
void * memmove(char *dst0, const char *src0, register size_t length)
{
register char *dst = dst0;
register const char *src = src0;
register size_t t;
if (length == 0 || dst == src)
goto retval;
#define TLOOP(s) if (t) TLOOP1(s)
#define TLOOP1(s) do { s; } while (--t)
if ((unsigned long)dst < (unsigned long)src) {
t = (int)src;
if ((t | (int)dst) & wmask) {
if ((t ^ (int)dst) & wmask || length < wsize)
t = length;
else
t = wsize - (t & wmask);
length -= t;
TLOOP1(*dst++ = *src++);
}
t = length / wsize;
TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
t = length & wmask;
TLOOP(*dst++ = *src++);
} else {
src += length;
dst += length;
t = (int)src;
if ((t | (int)dst) & wmask) {
if ((t ^ (int)dst) & wmask || length <= wsize)
t = length;
else
t &= wmask;
length -= t;
TLOOP1(*--dst = *--src);
}
t = length / wsize;
TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
t = length & wmask;
TLOOP(*--dst = *--src);
}
retval:
return(dst0);
}
#endif
#ifdef CLOAKED
char proctitlestr[140];
char **Argv = NULL;
char *LastArgv = NULL;
#define SPT_NONE 0
#define SPT_REUSEARGV 1
#define SPT_BUILTIN 2
#define SPT_PSTAT 3
#define SPT_PSSTRINGS 4
#define SPT_SYSMIPS 5
#define SPT_SCO 6
#define SPT_CHANGEARGV 7
#define SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf))
#ifndef SPT_TYPE
# define SPT_TYPE SPT_REUSEARGV
#endif
#if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
# if SPT_TYPE == SPT_PSTAT
# include <sys/pstat.h>
# endif
# if SPT_TYPE == SPT_PSSTRINGS
# include <machine/vmparam.h>
# include <sys/exec.h>
# ifndef PS_STRINGS
# undef SPT_TYPE
# define SPT_TYPE SPT_REUSEARGV
# else
# ifndef NKPDE
# define NKPDE 63
typedef unsigned int *pt_entry_t;
# endif
# endif
# endif
# if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
# define SETPROC_STATIC static
# else
# define SETPROC_STATIC
# endif
# if SPT_TYPE == SPT_SYSMIPS
# include <sys/sysmips.h>
# include <sys/sysnews.h>
# endif
# if SPT_TYPE == SPT_SCO
# include <sys/immu.h>
# include <sys/dir.h>
# include <sys/user.h>
# include <sys/fs/s5param.h>
# if PSARGSZ > MAXLINE
# define SPT_BUFSIZE PSARGSZ
# endif
# endif
# ifndef SPT_PADCHAR
# define SPT_PADCHAR ' '
# endif
# ifndef SPT_BUFSIZE
# define SPT_BUFSIZE 140
# endif
#endif
extern char **Argv;
extern char *LastArgv;
void initsetproctitle(int argc, char **argv, char **envp)
{
register int i, envpsize = 0;
extern char **environ;
for (i = 0; envp[i] != NULL; i++)
envpsize += strlen(envp[i]) + 1;
environ = (char **) malloc(sizeof (char *) * (i + 1));
for (i = 0; envp[i] != NULL; i++)
environ[i] = strdup(envp[i]);
environ[i] = NULL;
Argv = argv;
while (i > 0 && (envp[i - 1] < argv[0] ||
envp[i - 1] > (argv[argc - 1] +
strlen(argv[argc - 1]) + 1 + envpsize)))
i--;
if (i > 0)
LastArgv = envp[i - 1] + strlen(envp[i - 1]);
else
LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
}
void setproctitle(const char *fmt, ...)
{
#if defined(CLOAKED)
register char *p;
register int i;
SETPROC_STATIC char buf[SPT_BUFSIZE];
#if SPT_TYPE == SPT_PSTAT
union pstun pst;
#endif
#if SPT_TYPE == SPT_SCO
off_t seek_off;
static int kmem = -1;
static int kmempid = -1;
struct user u;
#endif
va_list args;
p = buf;
*p = 0;
p += strlen(p);
va_start(args, fmt);
(void) vsnprintf(p, SPACELEFT(buf, p), fmt, args);
va_end(args);
i = strlen(buf);
#if SPT_TYPE == SPT_PSTAT
pst.pst_command = buf;
pstat(PSTAT_SETCMD, pst, i, 0, 0);
#endif
#if SPT_TYPE == SPT_PSSTRINGS
PS_STRINGS->ps_nargvstr = 1;
PS_STRINGS->ps_argvstr = buf;
#endif
#if SPT_TYPE == SPT_SYSMIPS
sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
#endif
#if SPT_TYPE == SPT_SCO
if (kmem < 0 || kmempid != getpid())
{
if (kmem >= 0)
close(kmem);
kmem = open(_PATH_KMEM, O_RDWR, 0);
if (kmem < 0)
return;
(void) fcntl(kmem, F_SETFD, 1);
kmempid = getpid();
}
buf[PSARGSZ - 1] = '\0';
seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
(void) write(kmem, buf, PSARGSZ);
#endif
#if SPT_TYPE == SPT_REUSEARGV
if (i > LastArgv - Argv[0] - 2)
{
i = LastArgv - Argv[0] - 2;
buf[i] = '\0';
}
(void) strcpy(Argv[0], buf);
p = &Argv[0][i];
while (p < LastArgv)
*p++ = SPT_PADCHAR;
Argv[1] = NULL;
#endif
#if SPT_TYPE == SPT_CHANGEARGV
Argv[0] = buf;
Argv[1] = 0;
#endif
#endif
}
#endif
#ifdef __EMX__
#include <sys/utsname.h>
int uname(struct utsname *buf)
{
ULONG aulBuffer[4];
APIRET rc;
if (!buf) return EFAULT;
rc = DosQuerySysInfo(QSV_VERSION_MAJOR, QSV_MS_COUNT,(void *)aulBuffer, 4*sizeof(ULONG));
strcpy(buf->sysname,"OS/2");
strcpy(buf->release, "1.x");
if (aulBuffer[0] == 20)
{
int i = (unsigned int)aulBuffer[1];
strcpy(buf->release, ltoa(i));
if (i > 20)
{
strcpy(buf->sysname,"Warp");
sprintf(buf->release, "%d.%d", (int)i/10, i-(((int)i/10)*10));
}
else if (i == 10)
strcpy(buf->release, "2.1");
else if (i == 0)
strcpy(buf->release, "2.0");
strcpy(buf->machine, "i386");
if(getenv("HOSTNAME") != NULL)
strcpy(buf->nodename, getenv("HOSTNAME"));
else
strcpy(buf->nodename, "unknown");
}
return 0;
}
#endif
#ifdef WINNT
int tputs(const unsigned char *str, int nlines, int (*outfun)(int))
{
register unsigned int count = 0;
if (str)
{
while (*str)
(*outfun) (*str++), count++;
}
return count;
}
#endif
static char base64_chars[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int my_base64_encode (const void *data, int size, char **str)
{
char *s, *p;
int i;
unsigned c;
const unsigned char *q;
p = s = (char *)malloc(size * 4 / 3 + 4);
if (p == NULL)
return -1;
q = (const unsigned char *) data;
i = 0;
for (i = 0; i < size;) {
c = (unsigned)(unsigned char)q[i++];
c *= 256;
if (i < size)
c += (unsigned)(unsigned char)q[i];
i++;
c *= 256;
if (i < size)
c += (unsigned)(unsigned char)q[i];
i++;
p[0] = base64_chars[(c & 0x00fc0000) >> 18];
p[1] = base64_chars[(c & 0x0003f000) >> 12];
p[2] = base64_chars[(c & 0x00000fc0) >> 6];
p[3] = base64_chars[(c & 0x0000003f) >> 0];
if (i > size)
p[3] = '=';
if (i > size + 1)
p[2] = '=';
p += 4;
}
*p = 0;
*str = s;
return strlen(s);
}