/******************************************************************************
* This file is part of a software distribution, which is furnished under the *
* terms of a license. Use of this software by any means is subject to this *
* license and signifies the acceptance of the licensing terms stated *
* therein. Please see the file LICENSE in the top-level directory of this *
* software distribution for detailed copyright disclaimers and licensing *
* terms. *
******************************************************************************
* Copryight (c) by Andreas S. Wetzel - All rights reserved. *
******************************************************************************/
/* $Id: subr.c,v 1.5 2002/06/23 23:29:37 mickey Exp $ */
#include <vchat.h>
#include <proto_common.h>
#include <fcntl.h>
#include <signal.h>
#if HAVE_SYS_SELECT_H
#include <sys/select.h>
#endif
/*** Externals ***/
extern int in_chat_window;
extern ED *ed;
extern VP vp;
extern VCONN sconn;
extern VTCAP vtcap;
extern VTIMER vtimer;
/*
* void history_init(void);
*
* Initialize command history buffer.
*/
void history_init(void)
{
if(vp.history_lines > 0)
{
++vp.history_lines;
if((vp.history = (u_char **)calloc(vp.history_lines, sizeof(u_char *))) == NULL)
{
/*** FAILURE: Disable command history ***/
vp.history_lines = 0;
}
}
else
{
vp.history = NULL;
vp.history_lines = 0;
}
vp.history_start = 0;
vp.history_current = 0;
vp.history_next = 0;
vp.history_cycle = 0;
}
/*
* void history_exit(void);
*
* Free all buffers used for the command history
*/
void history_exit(void)
{
int i;
u_char *ptr;
if(vp.history != NULL)
{
for(i = 0; i < vp.history_lines; i++)
{
ptr = vp.history[i];
if(ptr != NULL)
{
free(ptr);
}
}
free(vp.history);
}
}
/*
* void history_save(u_char *text);
*
* Store the commandline pointed to by <text> at the
* next buffer position in the command history.
*/
void history_save(u_char *text)
{
size_t size = strlen(text) + 1;
u_char *newbuf;
/*
* If command history is disabled, there is
* nothing left to to in here.
*/
if(!vp.history_lines)
return;
/*
* Allocate a new buffer to store the text into.
* If this fails the history will be unmodified.
*/
if((newbuf = (u_char *)calloc(1, size)) == NULL)
{
return;
}
/*
* If the buffer to which vp.history_next points
* was already used then free the buffer at first.
*/
if(vp.history[vp.history_next] != NULL)
{
free(vp.history[vp.history_next]);
}
/*
* Store the text into the newly allocated buffer
* and store address of new buffer in the history vector
*/
strncpy(newbuf, text, size);
vp.history[vp.history_next++] = newbuf;
/*
* Set the index to the next buffer
*/
if(vp.history_next >= vp.history_lines)
{
/*
* History buffer has filled up, enable cycling
*/
vp.history_cycle = 1;
vp.history_next = 0;
}
vp.history_current = vp.history_next;
/*
* If the cycle history flag is set, then
* move the starting position up one place.
*/
if(vp.history_cycle)
{
if(++vp.history_start >= vp.history_lines)
vp.history_start = 0;
}
}
/*
* void vsleep(u_long sec, u_long usec);
*
* Suspend program execution for <sec> seconds
* plus <usec> microseconds.
*/
void vsleep(u_long sec, u_long usec)
{
int ret;
struct timeval tm;
struct timeval start;
struct timeval end;
struct timeval elapsed;
struct timeval remain;
tm.tv_sec = sec;
tm.tv_usec = usec;
restart:
timestamp(&start);
ret = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &tm);
timestamp(&end);
if(ret == -1 && errno != EINTR)
return;
BCOPY(diff_t(&start, &end), &elapsed, sizeof(struct timeval));
BCOPY(diff_t(&elapsed, &tm), &remain, sizeof(struct timeval));
if(remain.tv_sec >= 0 && remain.tv_usec >= 0)
{
tm = remain;
goto restart;
}
}
/*
* void str_lower(char *s);
*
* Convert the string pointed to by <s> into lowercase
*/
void str_lower(char *s)
{
while(*s != '\0')
{
*s = (*s >= 'A' && *s <= 'Z') ? *s + 0x20 : *s;
++s;
}
}
/*
* char *pr_timer(time_t tim);
*
* Return a pointer to a sring representing the date/time from <tim>
*/
char *pr_timer(time_t tim)
{
static char prt[30];
strftime((char *)&prt, 30, "%a %R", localtime(&tim));
return(prt);
}
/*
* void pbc_enable(void);
*
* Enable put-back-cursor timer event
*/
void pbc_enable(void)
{
vtimer.pbc_timer = vp.cursordelay;
vp.vclock_pbc_enable = 0xff;
}
/*
* void pbc_disable(void);
*
* Disable put-back-cursor timer event
*/
void pbc_disable(void)
{
vtimer.pbc_timer = vp.vclock_pbc_enable = 0;
}
/*
* void line_update(void);
*
* Clear and redraw the current input line pointed to by
* the global ED *ed pointer.
*/
void line_update(void)
{
char *cptr;
char *endp;
/*
* Prevent us from being interrupted
*/
vlock(LOCK, (V_IO | V_TIMER | V_WINCH));
/*
* Print the prompt (if any)
*/
mv(1, vtcap.rows);
in_chat_window = 0;
if(ed->prompt)
cprintf(input, "%s", ed->prompt);
/*
* Redraw input line
*/
if(!(ed->flags & ED_NO_ECHO))
{
endp = (ed->margin + (vtcap.cols - ed->offset));
for(cptr = ed->margin; cptr < endp && *cptr != '\0'; cptr++)
putchar(*cptr);
if(cptr < endp)
{
if(vtcap.clear2eol)
tputs(vtcap.clear2eol, 1, (void *)outc);
else if(vtcap.clear2eod)
tputs(vtcap.clear2eod, 1, (void *)outc);
}
if(ED_SCRPOS != ((endp - ed->margin) + ed->offset))
mv(ED_SCRPOS, vtcap.rows);
}
else
{
/*
* Clear the line remaining right of the prompt
*/
if(vtcap.clear2eol)
tputs(vtcap.clear2eol, 1, (void *)outc);
else if(vtcap.clear2eod)
tputs(vtcap.clear2eod, 1, (void *)outc);
}
vlock(UNLOCK, (V_IO | V_TIMER | V_WINCH));
}
/*
* void nop(void)
*
* Simply do nothing - this is used for unknown keys in input_line();
*/
void nop(void)
{
/* PENG! */
}
/*
* int escape_str(u_char *str, u_char *buf, size_t len);
*
* Read input from the string pointed to by <str> escaping
* all occurances of a CSI or space character with a CSI
* character. At most <len> bytes of output will be written
* to the buffer pointed to by <buf>.
*/
int escape_str(u_char *str, u_char *buf, size_t len)
{
int cnt = 0;
if(str == NULL || buf == NULL)
return(0);
for(;;)
{
if(*str == '\0')
{
*buf = '\0';
return(cnt);
}
else if(*str == CSI)
{
if(cnt < (len -1))
{
*buf++ = CSI;
++cnt;
}
else
{
*buf = '\0';
return(cnt);
}
if(cnt < (len -1))
{
*buf++ = CSI;
++cnt;
}
else
{
*buf = '\0';
return(cnt);
}
++str;
}
else if(*str == ' ')
{
if(cnt < (len -1))
{
*buf++ = CSI;
++cnt;
}
else
{
*buf = '\0';
return(cnt);
}
if(cnt < (len - 1))
{
*buf++ = ' ';
++cnt;
}
else
{
*buf = '\0';
return(cnt);
}
++str;
}
else
{
if(cnt < (len - 1))
{
*buf++ = *str++;
++cnt;
}
else
{
*buf = '\0';
return(cnt);
}
}
}
}
/*
* int netmask_bits(struct in_addr netmask);
*
* Get the number of mask bits in the specified netmask
*/
int netmask_bits(struct in_addr netmask)
{
u_int32_t mask = ntohl(netmask.s_addr);
int bits = 0;
int flg = 0;
int i;
for(i = 0; i < (CHAR_BIT * sizeof(u_int32_t)); i++)
{
if(mask & 0x00000001)
{
flg = 1;
++bits;
}
else
{
if(flg)
return(-1);
}
mask = (mask >> 1);
}
return(bits);
}
/*
* void netmask_create(int bits, struct in_addr *netmask);
*
* Create a netmask with the number of <bits> specified, and store
* it into the in_addr struct pointed to by <netmask>.
*/
void netmask_create(int bits, struct in_addr *netmask)
{
netmask->s_addr = htonl(~0 << ((CHAR_BIT * sizeof(u_int32_t)) - bits));
}
/*
* int permission_mask(char *privname, u_int32_t *maskptr);
*
* Store the binary representation for the permission named
* by the <privname> parameter into the permission mask pointed
* to by the <maskptr> parameter. Returns 0 if successfull or
* -1 in case the specified permission name was invalid.
*/
int permission_mask(char *permname, u_int32_t *maskptr)
{
str_lower(permname);
if(!strcmp(permname, "add"))
*maskptr = AUTH_ADD;
else if(!strcmp(permname, "delete"))
*maskptr = AUTH_DELETE;
else if(!strcmp(permname, "chacc"))
*maskptr = AUTH_CHACCPERM;
else if(!strcmp(permname, "chmod"))
*maskptr = AUTH_CHMODPERM;
else if(!strcmp(permname, "kill"))
*maskptr = AUTH_KILL;
else if(!strcmp(permname, "bcast"))
*maskptr = AUTH_BROADCAST;
else if(!strcmp(permname, "acl"))
*maskptr = AUTH_ACL;
else if(!strcmp(permname, "query"))
*maskptr = AUTH_QUERY;
else if(!strcmp(permname, "sopt"))
*maskptr = AUTH_SOPT;
else if(!strcmp(permname, "fix"))
*maskptr = AUTH_FIXCHAN;
else if(!strcmp(permname, "status"))
*maskptr = AUTH_STATUS;
else if(!strcmp(permname, "exclude"))
*maskptr = AUTH_EXCLUDE;
else
return(-1);
return(0);
}
/*
* int clopt_mask(char *optname, u_int32_t *maskptr);
*
* Store the binary representation for the client option named
* by the <optname> parameter into the client option mask pointed
* to by the <maskptr> parameter. Returns 0 if successfull or
* -1 in case the specified client option name was invalid.
*/
int clopt_mask(char *optname, u_int32_t *maskptr)
{
str_lower(optname);
if(!strcmp(optname, "wakeup"))
*maskptr = CL_OPT_WAKEUP;
else if(!strcmp(optname, "sgnmsg"))
*maskptr = CL_OPT_SGNMSG;
else if(!strcmp(optname, "prvecho"))
*maskptr = CL_OPT_PRVECHO;
else
return(-1);
return(0);
}
/*
* int svopt_mask(char *optname, u_int32_t *maskptr);
*
* Store the binary representation for the server option named
* by the <optname> parameter into the server option mask pointed
* to by the <maskptr> parameter. Returns 0 if successfull or
* -1 in case the specified server option name was invalid.
*/
int svopt_mask(char *optname, u_int32_t *maskptr)
{
str_lower(optname);
if(!strcmp(optname, "show_ip"))
*maskptr = SV_OPT_SHOW_IP;
else if(!strcmp(optname, "mail_inv"))
*maskptr = SV_OPT_MAIL_INV;
else if(!strcmp(optname, "reg_only"))
*maskptr = SV_OPT_REG_ONLY;
else if(!strcmp(optname, "flood_guard"))
*maskptr = SV_OPT_FLOOD_GUARD;
else
return(-1);
return(0);
}
syntax highlighted by Code2HTML, v. 0.9.1