/*
* by Dirk Meyer (dinoex)
* Copyright (C) 2004-2007 Dirk Meyer
*
* By using this file, you agree to the terms and conditions set
* forth in the GNU General Public License. More information is
* available in the README file.
*
* If you received this file without documentation, it can be
* downloaded from http://iroffer.dinoex.net/
*
* $Id: dinoex_admin.c,v 1.2 2007/07/08 09:11:18 dinoex Exp $
*
*/
/* include the headers */
#include "iroffer_config.h"
#include "iroffer_defines.h"
#include "iroffer_headers.h"
#include "iroffer_globals.h"
#include "dinoex_utilities.h"
#include "dinoex_admin.h"
#include "dinoex_misc.h"
#include <ctype.h>
void
#ifdef __GNUC__
__attribute__ ((format(printf, 2, 3)))
#endif
a_respond(const userinput * const u, const char *format, ...);
void a_respond(const userinput * const u, const char *format, ...)
{
va_list args;
updatecontext();
va_start(args, format);
switch (u->method)
{
case method_console:
vioutput(CALLTYPE_NORMAL, OUT_S, COLOR_NO_COLOR, format, args);
break;
case method_dcc:
vwritedccchat(u->chat, 1, format, args);
break;
case method_out_all:
vioutput(CALLTYPE_NORMAL, OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, format, args);
break;
case method_fd:
{
ssize_t retval;
char tempstr[maxtextlength];
int llen;
llen = vsnprintf(tempstr,maxtextlength-3,format,args);
if ((llen < 0) || (llen >= maxtextlength-3))
{
outerror(OUTERROR_TYPE_WARN,"string too long!");
tempstr[0] = '\0';
llen = 0;
}
if (!gdata.xdcclistfileraw)
{
removenonprintablectrl(tempstr);
}
#if defined(_OS_CYGWIN)
tempstr[llen++] = '\r';
#endif
tempstr[llen++] = '\n';
tempstr[llen] = '\0';
retval = write(u->fd, tempstr, strlen(tempstr));
if (retval < 0)
{
outerror(OUTERROR_TYPE_WARN_LOUD,"Write failed: %s", strerror(errno));
}
}
break;
case method_msg:
vprivmsg(u->snick, format, args);
break;
default:
break;
}
va_end(args);
}
int hide_locked(const userinput * const u, const xdcc *xd)
{
if (gdata.hidelockedpacks == 0)
return 0;
if (xd->lock == NULL)
return 0;
switch (u->method)
{
case method_fd:
case method_xdl_channel:
case method_xdl_user_privmsg:
case method_xdl_user_notice:
return 1;
default:
break;
}
return 0;
}
int a_xdl_space(void)
{
int i,s;
xdcc *xd;
i = 0;
xd = irlist_get_head(&gdata.xdccs);
while(xd)
{
i = max2(i,xd->gets);
xd = irlist_get_next(xd);
}
s = 5;
if (i < 10000) s = 4;
if (i < 1000) s = 3;
if (i < 100) s = 2;
if (i < 10) s = 1;
return s;
}
int a_xdl_left(void)
{
int n;
int l;
n = irlist_size(&gdata.xdccs);
l = 5;
if (n < 10000) l = 4;
if (n < 1000) l = 3;
if (n < 100) l = 2;
if (n < 10) l = 1;
return l;
}
int reorder_new_groupdesc(const char *group, const char *desc)
{
xdcc *xd;
int k;
updatecontext();
k = 0;
xd = irlist_get_head(&gdata.xdccs);
while(xd)
{
if (xd->group != NULL)
{
if (strcasecmp(xd->group,group) == 0)
{
k++;
/* delete all matching entires */
if (xd->group_desc != NULL)
mydelete(xd->group_desc);
/* write only the first entry */
if (k == 1)
{
if (desc && strlen(desc))
{
xd->group_desc = mystrdup(desc);
}
}
}
}
xd = irlist_get_next(xd);
}
return k;
}
int reorder_groupdesc(const char *group)
{
xdcc *xd;
xdcc *firstxd;
xdcc *descxd;
int k;
updatecontext();
k = 0;
firstxd = NULL;
descxd = NULL;
xd = irlist_get_head(&gdata.xdccs);
while(xd)
{
if (xd->group != NULL)
{
if (strcasecmp(xd->group,group) == 0)
{
k++;
if (xd->group_desc != NULL)
{
if (descxd == NULL)
{
descxd = xd;
}
else
{
/* more than one desc */
mydelete(xd->group_desc);
}
}
/* check only the first entry */
if (k == 1)
{
firstxd = xd;
}
}
}
xd = irlist_get_next(xd);
}
if (k == 0)
return k;
if (descxd == NULL)
return k;
if (descxd == firstxd)
return k;
firstxd->group_desc = descxd->group_desc;
descxd->group_desc = NULL;
return k;
}
int add_default_groupdesc(const char *group)
{
xdcc *xd;
xdcc *firstxd;
int k;
updatecontext();
k = 0;
firstxd = NULL;
xd = irlist_get_head(&gdata.xdccs);
while(xd)
{
if (xd->group != NULL)
{
if (strcasecmp(xd->group,group) == 0)
{
k++;
if (xd->group_desc != NULL)
return 0;
/* check only the first entry */
if (k == 1)
{
firstxd = xd;
}
}
}
xd = irlist_get_next(xd);
}
if (k != 1)
return k;
firstxd->group_desc = mystrdup(group);
return k;
}
void strtextcpy(char *d, const char *s)
{
const char *x;
char *w;
char ch;
size_t l;
if (d == NULL)
return;
if (s == NULL)
return;
/* ignore path */
x = strrchr(s, '/');
if (x != NULL)
x ++;
else
x = s;
strcpy(d,x);
/* ignore extension */
w = strrchr(d, '.');
if (w != NULL)
*w = 0;
l = strlen(d);
if ( l < 8 )
return;
w = d + l - 1;
ch = *w;
switch (ch) {
case '}':
w = strrchr(d, '{');
if (w != NULL)
*w = 0;
break;
case ')':
w = strrchr(d, '(');
if (w != NULL)
*w = 0;
break;
case ']':
w = strrchr(d, '[');
if (w != NULL)
*w = 0;
break;
}
/* strip numbers */
x = d;
w = d;
for (;;) {
ch = *(x++);
*w = ch;
if (ch == 0)
break;
if (isalpha(ch))
w++;
}
}
int invalid_group(const userinput * const u, const char *arg)
{
if (!arg || !strlen(arg))
{
a_respond(u, "Try Specifying a Group");
return 1;
}
return 0;
}
int invalid_pwd(const userinput * const u, const char *arg)
{
if (!arg || !strlen(arg))
{
a_respond(u, "Try Specifying a Password");
return 1;
}
return 0;
}
int invalid_announce(const userinput * const u, const char *arg)
{
if (!arg || !strlen(arg))
{
a_respond(u, "Try Specifying a Message (e.g. NEW)");
return 1;
}
return 0;
}
int invalid_pack(const userinput * const u, int num)
{
if (num < 1 || num > irlist_size(&gdata.xdccs))
{
a_respond(u, "Try Specifying a Valid Pack Number");
return 1;
}
return 0;
}
static int a_set_group(const userinput * const u, xdcc *xd, int num, const char *group)
{
const char *new;
char *tmpdesc;
char *tmpgroup;
int rc;
updatecontext();
if (num == 0) num = number_of_pack(xd);
new = "MAIN";
if (group && strlen(group))
new = group;
if (xd->group != NULL)
{
a_respond(u, "GROUP: [Pack %i] Old: %s New: %s",
num, xd->group, new);
/* keep group info for later work */
tmpgroup = xd->group;
xd->group = NULL;
tmpdesc = xd->group_desc;
xd->group_desc = NULL;
if (tmpdesc != NULL)
{
if (tmpgroup != NULL)
reorder_new_groupdesc(tmpgroup,tmpdesc);
mydelete(tmpdesc);
}
if (tmpgroup != NULL)
mydelete(tmpgroup);
}
else
{
a_respond(u, "GROUP: [Pack %i] New: %s",
num, new);
}
if (group != new)
return 0;
xd->group = mystrdup(group);
reorder_groupdesc(group);
rc = add_default_groupdesc(group);
if (rc == 1)
a_respond(u, "New GROUPDESC: %s",group);
return rc;
}
void a_xdlock(const userinput * const u)
{
char *tempstr;
int i;
int l;
int s;
xdcc *xd;
updatecontext();
tempstr = mycalloc(maxtextlength);
l = a_xdl_left();
s = a_xdl_space();
i = 1;
xd = irlist_get_head(&gdata.xdccs);
while(xd)
{
if (xd->lock != NULL)
{
u_xdl_pack(u,tempstr,i,l,s,xd);
a_respond(u," \2^-\2%*sPassword: %s", s, "", xd->lock);
}
i++;
xd = irlist_get_next(xd);
}
mydelete(tempstr);
}
void a_chlimit(const userinput * const u)
{
int num = 0;
int val = 0;
xdcc *xd;
updatecontext();
if (u->arg1) num = atoi(u->arg1);
if (invalid_pack(u, num) != 0)
return;
if (!u->arg2 || !strlen(u->arg2)) {
a_respond(u,"Try Specifying a daily Downloadlimit");
return;
}
xd = irlist_get_nth(&gdata.xdccs, num-1);
val = atoi(u->arg2);
a_respond(u, "CHLIMIT: [Pack %i] Old: %d New: %d",
num,xd->dlimit_max,val);
xd->dlimit_max = val;
if (val == 0)
xd->dlimit_used = 0;
else
xd->dlimit_used = xd->gets + xd->dlimit_max;
write_statefile();
xdccsavetext();
}
void a_chlimitinfo(const userinput * const u)
{
int num = 0;
xdcc *xd;
updatecontext();
if (u->arg1) num = atoi(u->arg1);
if (invalid_pack(u, num) != 0)
return;
xd = irlist_get_nth(&gdata.xdccs, num-1);
if (!u->arg2 || !strlen(u->arg2))
{
a_respond(u, "DLIMIT: [Pack %i] descr removed", num);
mydelete(xd->dlimit_desc);
xd->dlimit_desc = NULL;
}
else
{
a_respond(u, "DLIMIT: [Pack %i] descr: %s", num, u->arg2e);
xd->dlimit_desc = mystrdup(u->arg2e);
}
write_statefile();
xdccsavetext();
}
void a_lock(const userinput * const u)
{
int num = 0;
xdcc *xd;
updatecontext();
if (u->arg1) num = atoi(u->arg1);
if (invalid_pack(u, num) != 0)
return;
if (invalid_pwd(u, u->arg2) != 0)
return;
xd = irlist_get_nth(&gdata.xdccs, num-1);
a_respond(u, "LOCK: [Pack %i] Password: %s", num, u->arg2);
xd->lock = mystrdup(u->arg2);
write_statefile();
xdccsavetext();
}
void a_unlock(const userinput * const u)
{
int num = 0;
xdcc *xd;
updatecontext();
if (u->arg1) num = atoi(u->arg1);
if (invalid_pack(u, num) != 0)
return;
xd = irlist_get_nth(&gdata.xdccs, num-1);
a_respond(u, "UNLOCK: [Pack %i]", num);
mydelete(xd->lock);
xd->lock = NULL;
write_statefile();
xdccsavetext();
}
void a_lockgroup(const userinput * const u)
{
xdcc *xd;
int n;
updatecontext();
if (invalid_group(u, u->arg1) != 0)
return;
if (invalid_pwd(u, u->arg2) != 0)
return;
n = 0;
xd = irlist_get_head(&gdata.xdccs);
while(xd)
{
n++;
if (xd->group != NULL)
{
if (strcasecmp(xd->group,u->arg1) == 0)
{
a_respond(u, "LOCK: [Pack %i] Password: %s", n, u->arg2);
xd->lock = mystrdup(u->arg2);
}
}
xd = irlist_get_next(xd);
}
write_statefile();
xdccsavetext();
}
void a_unlockgroup(const userinput * const u)
{
xdcc *xd;
int n;
updatecontext();
if (invalid_group(u, u->arg1) != 0)
return;
n = 0;
xd = irlist_get_head(&gdata.xdccs);
while(xd)
{
n++;
if (xd->group != NULL)
{
if (strcasecmp(xd->group,u->arg1) == 0)
{
a_respond(u, "UNLOCK: [Pack %i]", n);
mydelete(xd->lock);
xd->lock = NULL;
}
}
xd = irlist_get_next(xd);
}
write_statefile();
xdccsavetext();
}
void a_groupdesc(const userinput * const u)
{
int k;
updatecontext();
if (invalid_group(u, u->arg1) != 0)
return;
if (u->arg2e && strlen(u->arg2e))
{
a_respond(u, "New GROUPDESC: %s",u->arg2e);
}
else
{
a_respond(u, "Removed GROUPDESC");
}
k = reorder_new_groupdesc(u->arg1,u->arg2e);
if (k == 0)
return;
write_statefile();
xdccsavetext();
}
void a_group(const userinput * const u)
{
xdcc *xd;
const char *new;
int num = 0;
updatecontext();
if (u->arg1) num = atoi(u->arg1);
if (invalid_pack(u, num) != 0)
return;
xd = irlist_get_nth(&gdata.xdccs, num-1);
new = u->arg2;
if (!u->arg2 || !strlen(u->arg2))
{
if (xd->group == NULL)
{
a_respond(u,"Try Specifying a Group");
return;
}
new = NULL;
}
else
{
if (gdata.groupsincaps)
caps(u->arg2);
}
a_set_group(u, xd, num, new);
write_statefile();
xdccsavetext();
}
void a_regroup(const userinput * const u)
{
xdcc *xd;
const char *g;
int k;
updatecontext();
if (invalid_group(u, u->arg1) != 0)
return;
if (invalid_group(u, u->arg2) != 0)
return;
if (gdata.groupsincaps)
caps(u->arg1);
k = 0;
xd = irlist_get_head(&gdata.xdccs);
while(xd)
{
if (xd->group != NULL)
g = xd->group;
else
g = "main";
if (strcasecmp(g,u->arg1) == 0)
{
k++;
if (xd->group != NULL)
mydelete(xd->group);
xd->group = mystrdup(u->arg2);
}
xd = irlist_get_next(xd);
}
if (k == 0)
return;
a_respond(u, "GROUP: Old: %s New: %s", u->arg1, u->arg2);
if (strcasecmp(u->arg1,"main") == 0)
add_default_groupdesc(u->arg2);
write_statefile();
xdccsavetext();
}
void a_amsg(const userinput * const u)
{
channel_t *ch;
updatecontext ();
if (invalid_announce(u, u->arg1e) != 0)
return;
ch = irlist_get_head(&gdata.channels);
while(ch) {
if (ch->flags & CHAN_ONCHAN)
privmsg_slow(ch->name, "%s", u->arg1e);
ch = irlist_get_next(ch);
}
a_respond(u,"Announced [%s]",u->arg1e);
}
void a_hop(const userinput * const u)
{
channel_t *ch;
updatecontext();
/* part & join channels */
ch = irlist_get_head(&gdata.channels);
while(ch)
{
if ((!u->arg1) || (!strcasecmp(u->arg1,ch->name)))
{
writeserver(WRITESERVER_NORMAL, "PART %s", ch->name);
clearmemberlist(ch);
ch->flags &= ~CHAN_ONCHAN;
joinchannel(ch);
}
ch = irlist_get_next(ch);
}
}
void a_identify(const userinput * const u)
{
updatecontext();
if (!gdata.nickserv_pass)
{
a_respond(u,"No nickserv_pass set!");
return;
}
identify_needed(1);
a_respond(u,"nickserv identify send.");
}
void a_holdqueue(const userinput * const u)
{
int val;
int i;
updatecontext();
if (gdata.holdqueue)
{
val = 0;
}
else
{
val = 1;
}
if (u->arg1) val = atoi(u->arg1);
gdata.holdqueue = val;
a_respond(u,"HOLDQUEUE now %d", val);
if (val != 0)
return;
for (i=0; i<100; i++)
{
if (!gdata.exiting &&
irlist_size(&gdata.mainqueue) &&
(irlist_size(&gdata.trans) < min2(MAXTRANS,gdata.slotsmax)))
{
sendaqueue(0);
}
}
}
/* End of File */
syntax highlighted by Code2HTML, v. 0.9.1