2014-03-08 19:56:21 -05:00
|
|
|
/*
|
|
|
|
|
|
|
|
|
|
EnergyMech, IRC bot software
|
2018-03-14 03:02:30 +01:00
|
|
|
Parts Copyright (c) 1997-2018 proton
|
2014-03-08 19:56:21 -05:00
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
#define FUNCTION_C
|
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
|
|
#include "defines.h"
|
|
|
|
|
#include "structs.h"
|
2018-03-14 03:02:30 +01:00
|
|
|
#ifdef TEST
|
|
|
|
|
#define MAIN_C
|
|
|
|
|
#endif
|
2014-03-08 19:56:21 -05:00
|
|
|
#include "global.h"
|
|
|
|
|
#include "h.h"
|
|
|
|
|
#include "text.h"
|
|
|
|
|
|
2018-03-14 03:02:30 +01:00
|
|
|
#ifndef TEST
|
|
|
|
|
|
2014-03-08 19:56:21 -05:00
|
|
|
LS char timebuf[24]; /* max format lentgh == 20+1, round up to nearest longword -> 24 */
|
|
|
|
|
LS char idlestr[36]; /* max format lentgh == 24+1, round up to nearest longword -> 28 */
|
2018-03-14 03:02:30 +01:00
|
|
|
LS const char monlist[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
|
|
|
|
LS const char daylist[7][4] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };
|
2014-03-08 19:56:21 -05:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* memory allocation routines
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
|
|
|
|
|
void *Calloc(int size)
|
|
|
|
|
{
|
|
|
|
|
aME *mmep;
|
|
|
|
|
aMEA *mp;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
#ifdef __GNUC__
|
|
|
|
|
if (mallocdoer == NULL)
|
|
|
|
|
{
|
|
|
|
|
mallocdoer = __builtin_return_address(0);
|
|
|
|
|
debug("(Calloc) mallocdoer = "mx_pfmt"\n",(mx_ptr)mallocdoer);
|
|
|
|
|
mallocdoer = NULL;
|
|
|
|
|
}
|
|
|
|
|
#endif /* GNUC */
|
|
|
|
|
|
|
|
|
|
mmep = NULL;
|
|
|
|
|
mp = mrrec;
|
|
|
|
|
while(!mmep)
|
|
|
|
|
{
|
|
|
|
|
for(i=0;i<MRSIZE;i++)
|
|
|
|
|
{
|
|
|
|
|
if (mp->mme[i].area == NULL)
|
|
|
|
|
{
|
|
|
|
|
mmep = &mp->mme[i];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!mmep)
|
|
|
|
|
{
|
|
|
|
|
if (mp->next == NULL)
|
|
|
|
|
{
|
|
|
|
|
mp->next = calloc(sizeof(aMEA),1);
|
|
|
|
|
mmep = &mp->next->mme[0];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
mp = mp->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* heap check +4 bytes
|
|
|
|
|
*/
|
|
|
|
|
if ((mmep->area = (void*)calloc(size+4,1)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
run_debug();
|
|
|
|
|
exit(1);
|
|
|
|
|
}
|
|
|
|
|
mmep->size = size;
|
|
|
|
|
mmep->when = now;
|
|
|
|
|
mmep->doer = mallocdoer;
|
|
|
|
|
mallocdoer = NULL;
|
|
|
|
|
return((void*)mmep->area+4);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Free(char **mem)
|
|
|
|
|
{
|
|
|
|
|
aME *mmep;
|
|
|
|
|
aMEA *mp;
|
|
|
|
|
int *src;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
if (*mem == NULL)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
src = (int*)((*mem)-4);
|
|
|
|
|
mmep = NULL;
|
|
|
|
|
mp = mrrec;
|
|
|
|
|
while(!mmep)
|
|
|
|
|
{
|
|
|
|
|
for(i=0;i<MRSIZE;i++)
|
|
|
|
|
{
|
|
|
|
|
if (mp->mme[i].area == src)
|
|
|
|
|
{
|
|
|
|
|
mmep = &mp->mme[i];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!mmep)
|
|
|
|
|
{
|
|
|
|
|
if (mp->next == NULL)
|
|
|
|
|
{
|
|
|
|
|
debug("(Free) PANIC: Free(0x"mx_pfmt"); Unregistered memory block\n",(mx_ptr)src);
|
|
|
|
|
run_debug();
|
2018-04-24 18:28:10 +02:00
|
|
|
/*exit(1); /* overreacting. just ignore it and accept the leak. */
|
2018-03-27 23:26:34 +02:00
|
|
|
return;
|
2014-03-08 19:56:21 -05:00
|
|
|
}
|
|
|
|
|
mp = mp->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (*src)
|
|
|
|
|
debug("Free: Heap corruption at 0x"mx_pfmt"\n",(mx_ptr)(*mem)-4);
|
|
|
|
|
mmep->area = NULL;
|
|
|
|
|
mmep->size = 0;
|
|
|
|
|
mmep->when = (time_t)0;
|
|
|
|
|
free((*mem)-4);
|
|
|
|
|
*mem = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#else /* DEBUG */
|
|
|
|
|
|
|
|
|
|
void *Calloc(int size)
|
|
|
|
|
{
|
|
|
|
|
void *tmp;
|
|
|
|
|
|
|
|
|
|
if ((tmp = (void*)calloc(size,1)) == NULL)
|
|
|
|
|
exit(1);
|
|
|
|
|
return((void*)tmp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Free() can be called with NULL's
|
|
|
|
|
*/
|
|
|
|
|
void Free(char **mem)
|
|
|
|
|
{
|
|
|
|
|
if (*mem)
|
|
|
|
|
{
|
|
|
|
|
free(*mem);
|
|
|
|
|
*mem = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* DEBUG */
|
|
|
|
|
|
2018-03-26 00:37:57 +02:00
|
|
|
Strp *make_strp(Strp **pp, const char *string)
|
|
|
|
|
{
|
|
|
|
|
set_mallocdoer(make_strp);
|
|
|
|
|
*pp = (Strp*)Calloc(sizeof(Strp) + strlen(string));
|
2018-04-04 06:04:58 +02:00
|
|
|
stringcpy((*pp)->p,string);
|
2018-03-26 00:37:57 +02:00
|
|
|
return(*pp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Strp *append_strp(Strp **pp, const char *string)
|
|
|
|
|
{
|
2018-03-27 17:28:48 +02:00
|
|
|
while((*pp) != NULL)
|
2018-03-26 00:37:57 +02:00
|
|
|
pp = &((*pp)->next);
|
|
|
|
|
make_strp(pp,string);
|
|
|
|
|
return(*pp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Strp *prepend_strp(Strp **pp, const char *string)
|
|
|
|
|
{
|
|
|
|
|
Strp *sp;
|
|
|
|
|
|
|
|
|
|
make_strp(&sp,string);
|
|
|
|
|
sp->next = *pp;
|
|
|
|
|
*pp = sp;
|
|
|
|
|
return(sp);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
/*
|
2018-04-22 02:34:04 +02:00
|
|
|
* Free() a whole linked list of any suitable type (Strp, Banlist)
|
2018-04-04 06:04:58 +02:00
|
|
|
*/
|
2018-04-22 02:34:04 +02:00
|
|
|
void purge_linklist(void **list)
|
2018-03-26 00:37:57 +02:00
|
|
|
{
|
2018-04-22 02:34:04 +02:00
|
|
|
Strp *sp,*nxt;
|
2018-03-26 00:37:57 +02:00
|
|
|
|
2018-04-22 02:34:04 +02:00
|
|
|
sp = *list;
|
2018-03-26 00:37:57 +02:00
|
|
|
while(sp)
|
|
|
|
|
{
|
|
|
|
|
nxt = sp->next;
|
|
|
|
|
Free((char**)&sp);
|
|
|
|
|
sp = nxt;
|
|
|
|
|
}
|
2018-04-22 02:34:04 +02:00
|
|
|
*list = NULL;
|
2018-03-26 00:37:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* duplicate a list of Strp
|
|
|
|
|
*/
|
|
|
|
|
void dupe_strp(Strp *sp, Strp **pp)
|
|
|
|
|
{
|
|
|
|
|
while(sp)
|
|
|
|
|
{
|
|
|
|
|
make_strp(pp,sp->p);
|
|
|
|
|
pp = &((*pp)->next);
|
|
|
|
|
sp = sp->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
Strp *e_table = NULL;
|
|
|
|
|
|
|
|
|
|
void table_buffer(const char *format, ...)
|
2014-03-08 19:56:21 -05:00
|
|
|
{
|
2018-04-04 06:04:58 +02:00
|
|
|
Strp **sp;
|
|
|
|
|
va_list msg;
|
|
|
|
|
int sz;
|
2014-03-08 19:56:21 -05:00
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
va_start(msg,format);
|
2018-04-15 03:57:44 +02:00
|
|
|
sz = sizeof(Strp) + vsprintf(globaldata,format,msg);
|
2018-04-04 06:04:58 +02:00
|
|
|
va_end(msg);
|
2014-03-08 19:56:21 -05:00
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
for(sp=&e_table;*sp;sp=&(*sp)->next)
|
|
|
|
|
;
|
2014-03-08 19:56:21 -05:00
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
set_mallocdoer(table_buffer);
|
|
|
|
|
*sp = (Strp*)Calloc(sz);
|
|
|
|
|
/* Calloc sets to zero (*sp)->next = NULL; */
|
2018-04-15 03:57:44 +02:00
|
|
|
stringcpy((*sp)->p,globaldata);
|
2014-03-08 19:56:21 -05:00
|
|
|
}
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
void table_send(const char *from, const int space)
|
2014-03-08 19:56:21 -05:00
|
|
|
{
|
2018-04-04 06:04:58 +02:00
|
|
|
char message[MAXLEN];
|
|
|
|
|
Strp *sp,*next;
|
|
|
|
|
char *src,*o,*end;
|
|
|
|
|
int i,u,g,x,z[6];
|
2014-03-08 19:56:21 -05:00
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
z[0] = z[1] = z[2] = z[3] = z[4] = z[5] = 0;
|
|
|
|
|
for(sp=e_table;sp;sp=sp->next)
|
|
|
|
|
{
|
|
|
|
|
u = i = 0;
|
|
|
|
|
src = o = sp->p;
|
|
|
|
|
while(*src)
|
|
|
|
|
{
|
|
|
|
|
if (*src == '\037' || *src == '\002')
|
|
|
|
|
u++;
|
|
|
|
|
if (*src == '\t' || *src == '\r')
|
|
|
|
|
{
|
|
|
|
|
x = (src - o) - u;
|
|
|
|
|
if (x > z[i])
|
|
|
|
|
z[i] = x;
|
|
|
|
|
i++;
|
|
|
|
|
o = src+1;
|
|
|
|
|
u = 0;
|
|
|
|
|
}
|
|
|
|
|
src++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-03-08 19:56:21 -05:00
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
for(sp=e_table;sp;sp=next)
|
|
|
|
|
{
|
|
|
|
|
next = sp->next;
|
2014-03-08 19:56:21 -05:00
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
o = message;
|
|
|
|
|
src = sp->p;
|
|
|
|
|
g = x = i = 0;
|
|
|
|
|
while(*src)
|
|
|
|
|
{
|
|
|
|
|
if (g)
|
|
|
|
|
{
|
|
|
|
|
end = src;
|
|
|
|
|
while(*end && *end != '\t' && *end != '\r')
|
|
|
|
|
end++;
|
|
|
|
|
g -= (end - src);
|
|
|
|
|
while(g-- > 0)
|
|
|
|
|
*(o++) = ' ';
|
|
|
|
|
}
|
|
|
|
|
if (*src == '\037' || *src == '\002')
|
|
|
|
|
x++;
|
|
|
|
|
if (*src == '\t' || *src == '\r')
|
|
|
|
|
{
|
|
|
|
|
if (*src == '\r')
|
|
|
|
|
g = z[i+1];
|
|
|
|
|
src++;
|
|
|
|
|
x += (z[i++] + space);
|
|
|
|
|
while(o < (message + x))
|
|
|
|
|
*(o++) = ' ';
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
*(o++) = *(src++);
|
|
|
|
|
}
|
|
|
|
|
*o = 0;
|
|
|
|
|
to_user(from,FMT_PLAIN,message);
|
2014-03-08 19:56:21 -05:00
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
Free((char**)&sp);
|
|
|
|
|
}
|
|
|
|
|
e_table = NULL;
|
2014-03-08 19:56:21 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *getuh(char *nuh)
|
|
|
|
|
{
|
|
|
|
|
char *s;
|
|
|
|
|
|
|
|
|
|
s = nuh;
|
|
|
|
|
while(*s)
|
|
|
|
|
{
|
|
|
|
|
if (*s == '!')
|
|
|
|
|
{
|
|
|
|
|
nuh = s + 1;
|
|
|
|
|
/*
|
|
|
|
|
* We have to grab everything from the first '!' since some
|
|
|
|
|
* braindamaged ircds allow '!' in the "user" part of the nuh
|
|
|
|
|
*/
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
s++;
|
|
|
|
|
}
|
|
|
|
|
return(nuh);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* caller is responsible for:
|
|
|
|
|
*
|
|
|
|
|
* src != NULL
|
|
|
|
|
* *src != NULL
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
char *get_token(char **src, const char *token_sep)
|
|
|
|
|
{
|
|
|
|
|
const char *s;
|
|
|
|
|
char *token = NULL;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* skip past any token_sep chars in the beginning
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if (0) /* is this legal C? */
|
|
|
|
|
a: ++(*src);
|
|
|
|
|
s = token_sep;
|
|
|
|
|
while(**src && *s)
|
|
|
|
|
{
|
|
|
|
|
if (*(s++) == **src)
|
|
|
|
|
goto a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (token || **src == 0)
|
|
|
|
|
return(token);
|
|
|
|
|
|
|
|
|
|
token = *src;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* find the next token_sep char
|
|
|
|
|
*/
|
|
|
|
|
do {
|
|
|
|
|
s = token_sep;
|
|
|
|
|
do {
|
|
|
|
|
if (*s == **src)
|
|
|
|
|
{
|
|
|
|
|
**src = 0;
|
|
|
|
|
goto a;
|
|
|
|
|
}
|
|
|
|
|
++s;
|
|
|
|
|
}
|
|
|
|
|
while(*s);
|
|
|
|
|
(*src)++;
|
|
|
|
|
}
|
|
|
|
|
while(**src);
|
|
|
|
|
|
|
|
|
|
return(token);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* time to string routines
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
char *logtime(time_t when)
|
|
|
|
|
{
|
|
|
|
|
struct tm *btime;
|
|
|
|
|
|
|
|
|
|
btime = localtime(&when);
|
|
|
|
|
sprintf(timebuf,"%s %i %i %02i:%02i:%02i", /* max format length: 20+1 */
|
|
|
|
|
monlist[btime->tm_mon],btime->tm_mday,btime->tm_year+1900,
|
|
|
|
|
btime->tm_hour,btime->tm_min,btime->tm_sec);
|
|
|
|
|
return(timebuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *time2str(time_t when)
|
|
|
|
|
{
|
|
|
|
|
struct tm *btime;
|
|
|
|
|
|
|
|
|
|
if (!when)
|
|
|
|
|
return(NULL);
|
|
|
|
|
|
|
|
|
|
btime = localtime(&when);
|
|
|
|
|
sprintf(timebuf,"%02i:%02i:%02i %s %02i %i", /* max format length: 20+1 */
|
|
|
|
|
btime->tm_hour,btime->tm_min,btime->tm_sec,monlist[btime->tm_mon],
|
|
|
|
|
btime->tm_mday,btime->tm_year+1900);
|
|
|
|
|
return(timebuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *time2away(time_t when)
|
|
|
|
|
{
|
|
|
|
|
struct tm *btime;
|
|
|
|
|
char ampm;
|
|
|
|
|
|
|
|
|
|
if (!when)
|
|
|
|
|
return(NULL);
|
|
|
|
|
|
|
|
|
|
btime = localtime(&when);
|
|
|
|
|
if (btime->tm_hour < 12)
|
|
|
|
|
{
|
|
|
|
|
if (btime->tm_hour == 0)
|
|
|
|
|
btime->tm_hour = 12;
|
|
|
|
|
ampm = 'a';
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (btime->tm_hour != 12)
|
|
|
|
|
btime->tm_hour -= 12;
|
|
|
|
|
ampm = 'p';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sprintf(timebuf,"%i:%02i%cm %s %s %i", /* max format length: 18+1 */
|
|
|
|
|
btime->tm_hour,btime->tm_min,ampm,daylist[btime->tm_wday],
|
|
|
|
|
monlist[btime->tm_mon],btime->tm_mday);
|
|
|
|
|
return(timebuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *time2medium(time_t when)
|
|
|
|
|
{
|
|
|
|
|
struct tm *btime;
|
|
|
|
|
|
|
|
|
|
btime = localtime(&when);
|
|
|
|
|
sprintf(timebuf,"%02i:%02i", /* max format length: 5+1 */
|
|
|
|
|
btime->tm_hour,btime->tm_min);
|
|
|
|
|
return(timebuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *time2small(time_t when)
|
|
|
|
|
{
|
|
|
|
|
struct tm *btime;
|
|
|
|
|
|
|
|
|
|
btime = localtime(&when);
|
|
|
|
|
sprintf(timebuf,"%s %02i", /* max format length: 6+1 */
|
|
|
|
|
monlist[btime->tm_mon],btime->tm_mday);
|
|
|
|
|
return(timebuf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *idle2str(time_t when, int small)
|
|
|
|
|
{
|
|
|
|
|
char *dst;
|
|
|
|
|
int n,z[4];
|
|
|
|
|
|
|
|
|
|
z[0] = when / 86400;
|
|
|
|
|
z[1] = (when -= z[0] * 86400) / 3600;
|
|
|
|
|
z[2] = (when -= z[1] * 3600) / 60;
|
|
|
|
|
z[3] = when % 60;
|
|
|
|
|
|
|
|
|
|
/* 32 : "9999 days, 24 hours, 59 minutes" */
|
|
|
|
|
/* xx : "24 hours, 59 minutes" */
|
|
|
|
|
/* xx : "59 minutes, 59 seconds" */
|
|
|
|
|
/* xx : "59 seconds" */
|
|
|
|
|
if (small)
|
|
|
|
|
{
|
|
|
|
|
char *f[] = {"day","hour","minute","second"};
|
|
|
|
|
|
|
|
|
|
*idlestr = 0;
|
|
|
|
|
for(n=0;n<4;n++)
|
|
|
|
|
{
|
|
|
|
|
if (*idlestr || z[n])
|
|
|
|
|
{
|
|
|
|
|
dst = STREND(idlestr);
|
|
|
|
|
sprintf(dst,"%s%i %s%s",(*idlestr) ? ", " : "",z[n],f[n],(z[n]==1) ? "" : "s");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
/* 18+1 (up to 9999 days) */
|
|
|
|
|
sprintf(idlestr,"%i day%s %02i:%02i:%02i",z[0],EXTRA_CHAR(z[0]),z[1],z[2],z[3]);
|
|
|
|
|
return(idlestr);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
const char *get_channel(const char *to, char **rest)
|
2014-03-08 19:56:21 -05:00
|
|
|
{
|
2018-04-04 06:04:58 +02:00
|
|
|
const char *channel;
|
2014-03-08 19:56:21 -05:00
|
|
|
|
|
|
|
|
if (*rest && ischannel(*rest))
|
|
|
|
|
{
|
|
|
|
|
channel = chop(rest);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!ischannel(to) && current->activechan)
|
|
|
|
|
channel = current->activechan->name;
|
|
|
|
|
else
|
|
|
|
|
channel = to;
|
|
|
|
|
}
|
|
|
|
|
return(channel);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
const char *get_channel2(const char *to, char **rest)
|
2014-03-08 19:56:21 -05:00
|
|
|
{
|
2018-04-04 06:04:58 +02:00
|
|
|
const char *channel;
|
2014-03-08 19:56:21 -05:00
|
|
|
|
|
|
|
|
if (*rest && (**rest == '*' || ischannel(*rest)))
|
|
|
|
|
{
|
|
|
|
|
channel = chop(rest);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!ischannel(to) && current->activechan)
|
|
|
|
|
channel = current->activechan->name;
|
|
|
|
|
else
|
|
|
|
|
channel = to;
|
|
|
|
|
}
|
|
|
|
|
return(channel);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *cluster(char *hostname)
|
|
|
|
|
{
|
|
|
|
|
char mask[NUHLEN];
|
|
|
|
|
char *p,*host;
|
|
|
|
|
char num,dot;
|
|
|
|
|
|
|
|
|
|
host = p = hostname;
|
|
|
|
|
num = dot = 0;
|
|
|
|
|
while(*p)
|
|
|
|
|
{
|
|
|
|
|
if (*p == '@')
|
|
|
|
|
{
|
|
|
|
|
host = p + 1;
|
|
|
|
|
num = dot = 0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (*p == '.')
|
|
|
|
|
dot++;
|
|
|
|
|
else
|
|
|
|
|
if (*p < '0' || *p > '9')
|
|
|
|
|
num++;
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!num && (dot == 3))
|
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
* its a numeric IP address
|
|
|
|
|
* 1.2.3.4 --> 1.2.*.*
|
|
|
|
|
*/
|
|
|
|
|
p = mask;
|
|
|
|
|
while(*host)
|
|
|
|
|
{
|
|
|
|
|
if (*host == '.')
|
|
|
|
|
{
|
|
|
|
|
if (num)
|
|
|
|
|
break;
|
|
|
|
|
num++;
|
|
|
|
|
}
|
|
|
|
|
*(p++) = *(host++);
|
|
|
|
|
}
|
2018-04-04 06:04:58 +02:00
|
|
|
stringcpy(p,".*.*");
|
2014-03-08 19:56:21 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-03-14 03:02:30 +01:00
|
|
|
/*
|
2014-03-08 19:56:21 -05:00
|
|
|
* its not a numeric mask
|
|
|
|
|
*/
|
|
|
|
|
p = mask;
|
|
|
|
|
*(p++) = '*';
|
|
|
|
|
num = (dot >= 4) ? 2 : 1;
|
|
|
|
|
while(*host)
|
|
|
|
|
{
|
|
|
|
|
if (*host == '.')
|
|
|
|
|
dot--;
|
|
|
|
|
if (dot <= num)
|
|
|
|
|
break;
|
|
|
|
|
host++;
|
|
|
|
|
}
|
2018-04-04 06:04:58 +02:00
|
|
|
stringcpy(p,host);
|
2014-03-08 19:56:21 -05:00
|
|
|
}
|
2018-04-04 06:04:58 +02:00
|
|
|
stringcpy(hostname,mask);
|
2014-03-08 19:56:21 -05:00
|
|
|
return(hostname);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* type output
|
|
|
|
|
* ~~~~ ~~~~~~
|
|
|
|
|
* 0,1 *!*user@*.host.com
|
|
|
|
|
* 2 *!*@*.host.com
|
|
|
|
|
*/
|
|
|
|
|
char *format_uh(char *userhost, int type)
|
|
|
|
|
{
|
|
|
|
|
char tmpmask[NUHLEN];
|
|
|
|
|
char *u,*h;
|
|
|
|
|
|
|
|
|
|
if (STRCHR(userhost,'*'))
|
|
|
|
|
return(userhost);
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
stringcpy(tmpmask,userhost);
|
2014-03-08 19:56:21 -05:00
|
|
|
|
|
|
|
|
h = tmpmask;
|
|
|
|
|
get_token(&h,"!"); /* discard nickname */
|
|
|
|
|
u = get_token(&h,"@");
|
|
|
|
|
|
|
|
|
|
if (*h == 0)
|
|
|
|
|
return(userhost);
|
|
|
|
|
|
|
|
|
|
if (u && (type < 2))
|
|
|
|
|
{
|
|
|
|
|
if ((type = strlen(u)) > 9)
|
|
|
|
|
u += (type - 9);
|
|
|
|
|
else
|
|
|
|
|
if (*u == '~')
|
|
|
|
|
u++;
|
|
|
|
|
}
|
|
|
|
|
sprintf(userhost,"*!*%s@%s",(u) ? u : "",cluster(h));
|
|
|
|
|
return(userhost);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* NOTE! beware of conflicts in the use of nuh_buf, its also used by find_nuh()
|
|
|
|
|
*/
|
|
|
|
|
char *nick2uh(char *from, char *userhost)
|
|
|
|
|
{
|
|
|
|
|
if (STRCHR(userhost,'!') && STRCHR(userhost,'@'))
|
|
|
|
|
{
|
2018-04-04 06:04:58 +02:00
|
|
|
stringcpy(nuh_buf,userhost);
|
2014-03-08 19:56:21 -05:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (!STRCHR(userhost,'!') && !STRCHR(userhost,'@'))
|
|
|
|
|
{
|
|
|
|
|
/* find_nuh() stores nickuserhost in nuh_buf */
|
|
|
|
|
if (find_nuh(userhost) == NULL)
|
|
|
|
|
{
|
|
|
|
|
if (from)
|
|
|
|
|
to_user(from,"No information found for %s",userhost);
|
|
|
|
|
return(NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-04-04 06:04:58 +02:00
|
|
|
stringcpy(nuh_buf,"*!");
|
2014-03-08 19:56:21 -05:00
|
|
|
if (!STRCHR(userhost,'@'))
|
2018-04-04 06:04:58 +02:00
|
|
|
stringcat(nuh_buf,"*@");
|
|
|
|
|
stringcat(nuh_buf,userhost);
|
2014-03-08 19:56:21 -05:00
|
|
|
}
|
|
|
|
|
return(nuh_buf);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deop_ban(Chan *chan, ChanUser *victim, char *mask)
|
|
|
|
|
{
|
|
|
|
|
if (!mask)
|
|
|
|
|
mask = format_uh(get_nuh(victim),FUH_USERHOST);
|
|
|
|
|
send_mode(chan,85,QM_CHANUSER,'-','o',victim);
|
|
|
|
|
send_mode(chan,90,QM_RAWMODE,'+','b',mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deop_siteban(Chan *chan, ChanUser *victim)
|
|
|
|
|
{
|
|
|
|
|
char *mask;
|
|
|
|
|
|
|
|
|
|
mask = format_uh(get_nuh(victim),FUH_HOST);
|
|
|
|
|
deop_ban(chan,victim,mask);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void screwban_format(char *userhost)
|
|
|
|
|
{
|
|
|
|
|
int sz,n,pos;
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
debug("(screwban_format) %s\n",userhost);
|
|
|
|
|
#endif /* DEBUG */
|
|
|
|
|
|
|
|
|
|
if ((sz = strlen(userhost)) < 8)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
n = RANDOM(4,sz);
|
|
|
|
|
while(--n)
|
|
|
|
|
{
|
|
|
|
|
pos = RANDOM(0,(sz - 1));
|
|
|
|
|
if (!STRCHR("?!@*",userhost[pos]))
|
|
|
|
|
{
|
|
|
|
|
userhost[pos] = (RANDOM(0,3) == 0) ? '*' : '?';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void deop_screwban(Chan *chan, ChanUser *victim)
|
|
|
|
|
{
|
|
|
|
|
char *mask;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
for(i=2;--i;)
|
|
|
|
|
{
|
|
|
|
|
mask = format_uh(get_nuh(victim),FUH_USERHOST);
|
|
|
|
|
screwban_format(mask);
|
|
|
|
|
deop_ban(chan,victim,mask);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int is_nick(const char *nick)
|
|
|
|
|
{
|
|
|
|
|
uchar *p;
|
|
|
|
|
|
|
|
|
|
p = (uchar*)nick;
|
|
|
|
|
if ((attrtab[*p] & FNICK) != FNICK)
|
|
|
|
|
return(FALSE);
|
|
|
|
|
while(*p)
|
|
|
|
|
{
|
|
|
|
|
if ((attrtab[*p] & NICK) != NICK)
|
|
|
|
|
return(FALSE);
|
|
|
|
|
p++;
|
|
|
|
|
}
|
|
|
|
|
return(TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
int asc2int(const char *anum)
|
2014-03-08 19:56:21 -05:00
|
|
|
{
|
|
|
|
|
int res = 0,neg;
|
|
|
|
|
|
|
|
|
|
errno = EINVAL;
|
|
|
|
|
|
|
|
|
|
if (!anum || !*anum)
|
|
|
|
|
return(-1);
|
|
|
|
|
|
|
|
|
|
neg = (*anum == '-') ? 1 : 0;
|
|
|
|
|
anum += neg;
|
|
|
|
|
|
|
|
|
|
while(*anum)
|
|
|
|
|
{
|
|
|
|
|
if (0 == (attrtab[(uchar)*anum] & NUM))
|
|
|
|
|
return(-1);
|
|
|
|
|
res = (res * 10) + *(anum++) - '0';
|
|
|
|
|
}
|
|
|
|
|
errno = 0;
|
|
|
|
|
return((neg) ? -res : res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int get_number(const char *rest)
|
|
|
|
|
{
|
|
|
|
|
const char *src = NULL;
|
|
|
|
|
int n = 0;
|
|
|
|
|
|
|
|
|
|
while(*rest)
|
|
|
|
|
{
|
|
|
|
|
if (*rest >= '0' && *rest <= '9')
|
|
|
|
|
n = (n * 10) + (*(src = rest) - '0');
|
|
|
|
|
else
|
|
|
|
|
if (src)
|
|
|
|
|
return(n);
|
|
|
|
|
rest++;
|
|
|
|
|
}
|
|
|
|
|
return(n);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void fix_config_line(char *text)
|
|
|
|
|
{
|
|
|
|
|
char *s,*space;
|
|
|
|
|
|
|
|
|
|
space = NULL;
|
|
|
|
|
for(s=text;*s;s++)
|
|
|
|
|
{
|
|
|
|
|
if (*s == '\t')
|
|
|
|
|
*s = ' ';
|
|
|
|
|
if (!space && *s == ' ')
|
|
|
|
|
space = s;
|
|
|
|
|
if (space && *s != ' ')
|
|
|
|
|
space = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (space)
|
|
|
|
|
*space = 0;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
#endif /* ifndef TEST */
|
2014-03-08 19:56:21 -05:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* mask matching
|
|
|
|
|
* returns 0 for match
|
|
|
|
|
* returns 1 for non-match
|
|
|
|
|
*/
|
|
|
|
|
int matches(const char *mask, const char *text)
|
|
|
|
|
{
|
|
|
|
|
const uchar *m = (uchar*)mask;
|
|
|
|
|
const uchar *n = (uchar*)text;
|
|
|
|
|
const uchar *orig = (uchar*)mask;
|
|
|
|
|
int wild,q;
|
|
|
|
|
|
|
|
|
|
q = wild = 0;
|
|
|
|
|
|
|
|
|
|
if (!m || !n)
|
|
|
|
|
return(TRUE);
|
|
|
|
|
|
|
|
|
|
loop:
|
|
|
|
|
if (!*m)
|
|
|
|
|
{
|
|
|
|
|
if (!*n)
|
|
|
|
|
return(FALSE);
|
|
|
|
|
for (m--;((*m == '?') && (m > orig));m--)
|
|
|
|
|
;
|
|
|
|
|
if ((*m == '*') && (m > orig) && (m[-1] != '\\'))
|
|
|
|
|
return(FALSE);
|
|
|
|
|
if (wild)
|
|
|
|
|
{
|
|
|
|
|
m = (uchar *)mask;
|
|
|
|
|
n = (uchar *)++text;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return(TRUE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (!*n)
|
|
|
|
|
{
|
|
|
|
|
while(*m == '*')
|
|
|
|
|
m++;
|
|
|
|
|
return(*m != 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (*m == '*')
|
|
|
|
|
{
|
|
|
|
|
while (*m == '*')
|
|
|
|
|
m++;
|
|
|
|
|
wild = 1;
|
|
|
|
|
mask = (char *)m;
|
|
|
|
|
text = (char *)n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((*m == '\\') && ((m[1] == '*') || (m[1] == '?')))
|
|
|
|
|
{
|
|
|
|
|
m++;
|
|
|
|
|
q = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
q = 0;
|
|
|
|
|
|
|
|
|
|
if ((tolowertab[(uchar)*m] != tolowertab[(uchar)*n]) && ((*m != '?') || q))
|
|
|
|
|
{
|
|
|
|
|
if (wild)
|
|
|
|
|
{
|
|
|
|
|
m = (uchar *)mask;
|
|
|
|
|
n = (uchar *)++text;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return(TRUE);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (*m)
|
|
|
|
|
m++;
|
|
|
|
|
if (*n)
|
|
|
|
|
n++;
|
|
|
|
|
}
|
|
|
|
|
goto loop;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int num_matches(const char *mask, const char *text)
|
|
|
|
|
{
|
|
|
|
|
const char *p = mask;
|
|
|
|
|
int n;
|
|
|
|
|
|
|
|
|
|
n = !matches(mask,text);
|
|
|
|
|
|
|
|
|
|
if (n)
|
|
|
|
|
{
|
|
|
|
|
do {
|
|
|
|
|
if (*p != '*')
|
|
|
|
|
n++;
|
|
|
|
|
}
|
|
|
|
|
while(*++p);
|
|
|
|
|
}
|
|
|
|
|
return(n);
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-14 03:02:30 +01:00
|
|
|
int is_safepath(const char *path, int filemustexist)
|
|
|
|
|
{
|
|
|
|
|
struct stat st;
|
|
|
|
|
char tmp[PATH_MAX];
|
|
|
|
|
const char *src;
|
|
|
|
|
char *dst;
|
2018-04-06 11:37:48 -04:00
|
|
|
int mo,dir_r,orr,oerrno;
|
2018-03-14 03:02:30 +01:00
|
|
|
|
|
|
|
|
#ifdef TEST
|
|
|
|
|
memset(&st,0,sizeof(st));
|
|
|
|
|
#endif
|
2018-04-24 18:28:10 +02:00
|
|
|
if (*(src = path) == '/') /* dont allow starting at root, only allow relative paths */
|
|
|
|
|
return(-1);
|
2018-03-14 03:02:30 +01:00
|
|
|
|
|
|
|
|
if (strlen(path) >= PATH_MAX)
|
|
|
|
|
return(-6);
|
|
|
|
|
|
|
|
|
|
orr = lstat(path,&st);
|
|
|
|
|
oerrno = errno;
|
|
|
|
|
|
|
|
|
|
if (filemustexist == FILE_MUST_EXIST && orr == -1 && errno == ENOENT)
|
|
|
|
|
return(-2);
|
|
|
|
|
if (filemustexist == FILE_MUST_NOTEXIST && orr == 0)
|
|
|
|
|
return(-3);
|
|
|
|
|
|
2018-04-24 18:28:10 +02:00
|
|
|
mo = st.st_mode; /* save mode for later */
|
2018-03-14 03:02:30 +01:00
|
|
|
dir_r = -1;
|
|
|
|
|
|
|
|
|
|
for(dst=tmp;*src;)
|
|
|
|
|
{
|
|
|
|
|
if (*src == '/')
|
|
|
|
|
{
|
|
|
|
|
*dst = 0;
|
|
|
|
|
if ((dir_r = lstat(tmp,&st)) == -1 && errno == ENOENT)
|
|
|
|
|
return(-7);
|
2018-04-24 18:28:10 +02:00
|
|
|
if (!(S_ISREG(st.st_mode) || S_ISDIR(st.st_mode))) /* disallow all except regular files and directories */
|
2018-03-14 03:02:30 +01:00
|
|
|
return(-4);
|
2018-04-24 18:28:10 +02:00
|
|
|
if (st.st_ino == parent_inode) /* disallow traversing below bots homedir */
|
2018-03-14 03:02:30 +01:00
|
|
|
return(-5);
|
|
|
|
|
}
|
|
|
|
|
if (dst == tmp + PATH_MAX-1)
|
|
|
|
|
return(-6);
|
|
|
|
|
*dst++ = *src++;
|
|
|
|
|
}
|
|
|
|
|
if (filemustexist != FILE_MUST_EXIST && orr == -1 && oerrno == ENOENT)
|
|
|
|
|
return(TRUE);
|
|
|
|
|
return (S_ISREG(mo)) ? TRUE : FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef TEST
|
|
|
|
|
|
|
|
|
|
#include "debug.c"
|
|
|
|
|
|
|
|
|
|
#define P0 "verylongexcessivelengthfilenamegibberish"
|
|
|
|
|
#define P1 P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/" P0 "/"
|
|
|
|
|
#define P2 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P1 P0
|
|
|
|
|
|
|
|
|
|
char *tostr[] = { "ZERO", "FILE_MUST_EXIST", "FILE_MAY_EXIST", "FILE_MUST_NOTEXIST" };
|
|
|
|
|
|
|
|
|
|
void testcase(const char *str, int expected, int filemustexist)
|
|
|
|
|
{
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
r = is_safepath(str,filemustexist);
|
|
|
|
|
if (r == expected)
|
|
|
|
|
{
|
|
|
|
|
debug("testcase SUCCESS: testpath %s %s -> result %i\n",
|
|
|
|
|
(strlen(str)>50) ? "(very long string)" : str,tostr[filemustexist],r);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
debug("testcase FAIL: testpath %s(%i) %s -> result %i, expected %i\n",
|
|
|
|
|
(strlen(str)>50) ? "(very long string)" : str,
|
2018-04-24 18:28:10 +02:00
|
|
|
strlen(str),tostr[filemustexist],r,expected);/*(r) ? "TRUE" : "FALSE",(expected) ? "TRUE" : "FALSE"); */
|
2018-03-14 03:02:30 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-04 06:04:58 +02:00
|
|
|
const char teststr[] = "dingchat";
|
|
|
|
|
|
|
|
|
|
void teststring(void)
|
|
|
|
|
{
|
|
|
|
|
char str[100];
|
|
|
|
|
|
|
|
|
|
stringcpy(str,teststr);
|
|
|
|
|
if (stringcmp(str,teststr))
|
|
|
|
|
debug("teststring FAIL: stringcpy(str,%s) != %s (%s)\n",teststr,teststr,str);
|
|
|
|
|
else
|
|
|
|
|
debug("teststring SUCCESS: stringcpy(str,%s) == %s\n",teststr,teststr);
|
|
|
|
|
|
|
|
|
|
stringcpy_n(str+4,"xoom",2);
|
|
|
|
|
if (stringcmp(str,"dingxo"))
|
|
|
|
|
debug("teststring FAIL: stringcpy_n(str+4,%s,2) != %s (%s)\n","xoom","dingxo",str);
|
|
|
|
|
else
|
|
|
|
|
debug("teststring SUCCESS: stringcpy_n(str+4,%s,2) == %s\n","xoom","dingxo");
|
|
|
|
|
|
|
|
|
|
stringcat(str,"free");
|
|
|
|
|
if (stringcmp(str,"dingxofree"))
|
|
|
|
|
debug("teststring FAIL: stringcat(str,%s) != %s (%s)\n","free","dingxofree",str);
|
|
|
|
|
else
|
|
|
|
|
debug("teststring SUCCESS: stringcat(str,%s) == %s\n","free","dingxofree");
|
|
|
|
|
}
|
|
|
|
|
|
2018-03-14 03:02:30 +01:00
|
|
|
int main(int argc, char **argv)
|
|
|
|
|
{
|
|
|
|
|
struct stat st;
|
|
|
|
|
int r;
|
|
|
|
|
|
|
|
|
|
dodebug = 1;
|
|
|
|
|
stat("../..",&st);
|
2018-04-24 18:28:10 +02:00
|
|
|
parent_inode = st.st_ino; /* used for is_safepath() */
|
2018-03-14 03:02:30 +01:00
|
|
|
|
|
|
|
|
debug("PATH_MAX = %i\n",PATH_MAX);
|
|
|
|
|
if (argv[1] == NULL)
|
|
|
|
|
{
|
|
|
|
|
testcase("/etc/passwd",-1,FILE_MAY_EXIST);
|
|
|
|
|
testcase("../../../../../../../../../../../etc/passwd",-5,FILE_MAY_EXIST);
|
|
|
|
|
testcase("../anyparentfile",1,FILE_MAY_EXIST);
|
|
|
|
|
testcase("../../anyparentparentfile",-5,FILE_MAY_EXIST);
|
|
|
|
|
testcase("function.c",TRUE,FILE_MUST_EXIST);
|
|
|
|
|
testcase("./function.c",TRUE,FILE_MUST_EXIST);
|
|
|
|
|
testcase("function.c",-3,FILE_MUST_NOTEXIST);
|
|
|
|
|
testcase("./function.c",-3,FILE_MUST_NOTEXIST);
|
|
|
|
|
testcase("nosuchfile",1,FILE_MAY_EXIST);
|
|
|
|
|
testcase("nosuchfile",1,FILE_MUST_NOTEXIST);
|
|
|
|
|
testcase("./nosuchfile",1,FILE_MUST_NOTEXIST);
|
|
|
|
|
testcase("../../nosuchfile",-5,FILE_MUST_NOTEXIST);
|
|
|
|
|
testcase(P2,-6,FILE_MAY_EXIST);
|
2018-04-04 06:04:58 +02:00
|
|
|
teststring();
|
2018-03-14 03:02:30 +01:00
|
|
|
exit(0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r = is_safepath(argv[1],FILE_MAY_EXIST);
|
|
|
|
|
debug("testpath %s -> result %s\n",argv[1],(r) ? "TRUE" : "FALSE");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif /* TEST */
|
|
|
|
|
|