/* * 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 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 */