/* * es_seennick() * * Give lptr seen info on av[1] nick (exact match) */ static void es_seennick(struct Luser *lptr, int ac, char **av) { aSeen *seen, *recent, *saved = NULL; struct Luser *aptr; if (ac < 2) { notice(n_SeenServ, lptr->nick, "Syntax: SEENNICK <nickname>"); notice(n_SeenServ, lptr->nick, ERR_MORE_INFO, n_SeenServ, "SEENNICK"); return ; } if ((aptr = FindClient(av[1]))) { notice(n_SeenServ, lptr->nick, "%s is on IRC right now!", aptr->nick); return ; } for (seen = seenp; seen; seen = seen->prev) { if (!irccmp(seen->nick, av[1])) { seen->seen = saved; saved = seen; } } if (saved) { recent = saved; for (; saved; saved = saved->seen) { if (saved->time > recent->time) recent = saved; } if (recent->type == 1) { notice(n_SeenServ, lptr->nick, "I last saw %s (%s) %s ago, quiting: %s", recent->nick, recent->userhost, timeago(recent->time, 0), recent->msg); } else if (recent->type == 2) { notice(n_SeenServ, lptr->nick, "I last saw %s (%s) %s ago, changing nicks", recent->nick, recent->userhost, timeago(recent->time, 0)); } } else { notice(n_SeenServ, lptr->nick, "I haven't seen %s recently", av[1]); } } /* es_seennick */
/* Accepts these parameters: * a) no parameters - to display split data for all servers currently in * netsplit * b) av[1] - to display split data for current server * -kre */ static void ss_splitinfo(struct Luser *lptr, int ac, char **av) { struct Server *tmpserv; char sMsg[] = "%-30s currently in \002netsplit\002 for %s"; int issplit = 0; if (ac < 2) { for (tmpserv = ServerList; tmpserv; tmpserv = tmpserv->next) if (tmpserv->split_ts) { notice(n_StatServ, lptr->nick, sMsg, tmpserv->name, timeago(tmpserv->split_ts, 0)); issplit = 1; } } else { if ((tmpserv = FindServer(av[1]))) { if (tmpserv->split_ts) { notice(n_StatServ, lptr->nick, sMsg, tmpserv->name, timeago(tmpserv->split_ts, 0)); issplit = 1; } } else notice(n_StatServ, lptr->nick, "Invalid server %s!", av[1]); } if (!issplit) notice(n_StatServ, lptr->nick, "No split for specified server or no active splits"); }
static void ShowServerInfo(struct Server *servptr, struct Luser *lptr, int showinfo) { char str[MAXLINE + 1]; assert(servptr != 0); assert(lptr != 0); if (!showinfo) { #ifdef SPLIT_INFO if (!servptr->split_ts) #endif notice(n_StatServ, lptr->nick, "%-30s connected: %s, users: %d", servptr->name, timeago(servptr->connect_ts, 0), servptr->numusers); #ifdef SPLIT_INFO else notice(n_StatServ, lptr->nick, "%-30s currently in \002netsplit\002 for %s", servptr->name, timeago(servptr->split_ts, 0)); #endif return; } #ifdef SPLIT_INFO if (!servptr->split_ts) #endif notice(n_StatServ, lptr->nick, "Statistics for server: \002%s\002", servptr->name); #ifdef SPLIT_INFO else notice(n_StatServ, lptr->nick, "Last known statistics for server: \002%s\002", servptr->name); #endif notice(n_StatServ, lptr->nick, "Current Clients: %ld", servptr->numusers); notice(n_StatServ, lptr->nick, "Current Opers: %ld", servptr->numopers); notice(n_StatServ, lptr->nick, "Current Servers: %ld", servptr->numservs); if (servptr->maxusers_ts) { strlcpy(str, "on ", sizeof(str)); strlcat(str, ctime(&servptr->maxusers_ts), sizeof(str)); str[strlen(str) - 1] = '\0'; } else str[0] = '\0'; notice(n_StatServ, lptr->nick, "Max Clients: %ld %s", servptr->maxusers, str); if (servptr->maxopers_ts) { strlcpy(str, "on ", sizeof(str)); strlcat(str, ctime(&servptr->maxopers_ts), sizeof(str)); str[strlen(str) - 1] = '\0'; } else str[0] = '\0'; notice(n_StatServ, lptr->nick, "Max Opers: %ld %s", servptr->maxopers, str); if (servptr->maxservs_ts) { strlcpy(str, "on ", sizeof(str)); strlcat(str, ctime(&servptr->maxservs_ts), sizeof(str)); str[strlen(str) - 1] = '\0'; } else str[0] = '\0'; notice(n_StatServ, lptr->nick, "Max Servers: %ld %s", servptr->maxservs, str); notice(n_StatServ, lptr->nick, "Identd Users: %ld", servptr->numidentd); notice(n_StatServ, lptr->nick, "Non-Identd Users: %ld", servptr->numusers - servptr->numidentd); notice(n_StatServ, lptr->nick, "Resolving Hosts: %ld", servptr->numreshosts); notice(n_StatServ, lptr->nick, "Non-Resolving Hosts: %ld", servptr->numusers - servptr->numreshosts); notice(n_StatServ, lptr->nick, "Operator Kills: %ld", servptr->numoperkills); notice(n_StatServ, lptr->nick, "Server Kills: %ld", servptr->numservkills); if (servptr->ping > 0.0) { notice(n_StatServ, lptr->nick, "Current Ping: %5.4f seconds", servptr->ping); if ((servptr->maxping > 0.0) && servptr->maxping_ts) { ircsprintf(str, "on %s", ctime(&servptr->maxping_ts)); str[strlen(str) - 1] = '\0'; notice(n_StatServ, lptr->nick, "Highest Ping: %5.4f seconds %s", servptr->maxping, str); } if ((servptr->minping > 0.0) && servptr->minping_ts) { ircsprintf(str, "on %s", ctime(&servptr->minping_ts)); str[strlen(str) - 1] = '\0'; notice(n_StatServ, lptr->nick, "Lowest Ping: %5.4f seconds %s", servptr->minping, str); } } if (servptr->uplink) notice(n_StatServ, lptr->nick, "Current Hub: %s (connected for [%s])", servptr->uplink->name, timeago(servptr->connect_ts, 0)); #ifdef SPLIT_INFO else notice(n_StatServ, lptr->nick, "Currently in \002netsplit\002 for %s", servptr->name, timeago(servptr->connect_ts, 0)); #endif } /* ShowServerInfo() */
static void m_list(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *mi = NULL; struct Memo *memoptr; char status[4]; if (!nptr) return; if (ac >= 2) { if (av[1][0] == '#') { #ifdef CHANNELSERVICES struct ChanInfo *ci; #endif #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[1]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to list memos for [\002%s\002]", ci->name); return; } mi = FindMemoList(ci->name); if (!mi) { notice(n_MemoServ, lptr->nick, "There are no recorded memos for [\002%s\002]", ci->name); return; } #endif /* CHANNELSERVICES */ } } if (!mi) { if (!(mi = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } } notice(n_MemoServ, lptr->nick, "-- Listing memos for [\002%s\002] --", mi->name); notice(n_MemoServ, lptr->nick, " Idx Sender Time Sent"); for (memoptr = mi->memos; memoptr; memoptr = memoptr->next) { if (memoptr->flags & MS_DELETE) strcpy(status, "(D)"); else if (mi->name[0] != '#') { if (memoptr->flags & MS_READ) strcpy(status, "(R)"); else strcpy(status, "(N)"); } else status[0] = '\0'; notice(n_MemoServ, lptr->nick, "%3s %-3d %-18s %s ago", status, memoptr->index, memoptr->sender, timeago(memoptr->sent, 1)); } notice(n_MemoServ, lptr->nick, "-- End of list --"); } /* m_list() */
static void m_read(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *mi; int index; struct Memo *memoptr; char istr[10]; if (!nptr) return; if (ac < 2) { notice(n_MemoServ, lptr->nick, "Syntax: READ [channel] <index|all>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "READ"); return; } if (ac >= 3) { #ifdef CHANNELSERVICES struct ChanInfo *ci; #endif #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[1]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[1]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to read memos for [\002%s\002]", ci->name); return; } if (!(mi = FindMemoList(ci->name))) { notice(n_MemoServ, lptr->nick, "There are no recorded memos for [\002%s\002]", ci->name); return; } index = IsNum(av[2]); #endif /* CHANNELSERVICES */ } else { if (!(mi = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } index = IsNum(av[1]); } if ((index < 0) || (index > mi->memocnt) || (!index && (irccmp(av[(ac >= 3) ? 2 : 1], "ALL") != 0))) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is an invalid index", av[(ac >= 3) ? 2 : 1]); return; } for (memoptr = mi->memos; memoptr; memoptr = memoptr->next) { if (!index || (memoptr->index == index)) { notice(n_MemoServ, lptr->nick, "Memo #%d from %s (sent %s ago):", memoptr->index, memoptr->sender, timeago(memoptr->sent, 1)); notice(n_MemoServ, lptr->nick, memoptr->text); if (ac < 3) { /* only mark nickname memos as read - not channel memos */ if (!(memoptr->flags & MS_READ)) mi->newmemos--; memoptr->flags |= MS_READ; } } } if (index) ircsprintf(istr, "%d", index); else strcpy(istr, "ALL"); if (ac >= 3) notice(n_MemoServ, lptr->nick, "To delete, type \002/msg %s DEL %s %s", n_MemoServ, av[1], istr); else notice(n_MemoServ, lptr->nick, "To delete, type \002/msg %s DEL %s", n_MemoServ, istr); } /* m_read() */
/* SaveSettings() Save all current settings to SETPATH. Return: 1 if successful 0 if not */ int SaveSettings() { FILE *fp; struct Directive *dptr; int ii; char buffer[MAXLINE], tmp[MAXLINE], tempname[MAXLINE]; /* MMkay, this should write safe config files so that they won't get * b0rked if something happens when writing. -kre */ ircsprintf(tempname, "%s.tmp", SETPATH); if (!(fp = fopen(tempname, "w"))) { putlog(LOG1, "SaveSettings(): Unable to open %s: %s", SETPATH, strerror(errno)); return 0; } for (dptr = directives; dptr->name; dptr++) { buffer[0] = 0; for (ii = 0; ii < PARAM_MAX; ii++) { if (!dptr->param[ii].type) break; switch (dptr->param[ii].type) { case PARAM_STRING: { /* Try to write out string only if non-null, ie is set -kre */ if (*(char **)dptr->param[ii].ptr) { ircsprintf(tmp, "\"%s\" ", *(char **) dptr->param[ii].ptr); strcat(buffer, tmp); } break; } /* case PARAM_STRING */ case PARAM_TIME: { ircsprintf(tmp, "%s ", timeago(*(long *) dptr->param[ii].ptr, 4)); strcat(buffer, tmp); break; } /* case PARAM_TIME */ case PARAM_INT: case PARAM_PORT: { ircsprintf(tmp, "%d ", *(int *) dptr->param[ii].ptr); strcat(buffer, tmp); break; } case PARAM_SET: { /* * Only write out SETs if they are non null * * IMHO if dptr->param[ii].type == PARAM_SET there is no reason * to write numeric value because it is ignored in the first * way. * -kre */ if (*(int *) dptr->param[ii].ptr) { #if 0 ircsprintf(tmp, "%d ", *(int *) dptr->param[ii].ptr); strcat(buffer, tmp); #endif /* Fill in buffer.. */ strcat(buffer, " "); /* and then do continue -kre */ } else /* Any of SETs in param[] was empty, so there is no need to * write directive -kre */ buffer[0] = 0; break; } /* case PARAM_SET */ } /* switch (dptr->param[ii].type) */ } if (*buffer) fprintf(fp, "%-20s %s\n", dptr->name, buffer); } fclose(fp); rename(tempname, SETPATH); return 1; } /* SaveSettings() */
/* * es_seen() * * Give lptr seen info on av[1] wild matches (nick + userhost) * * XXX: THIS FUNCTION IS UTTER CRAP */ static void es_seen(struct Luser *lptr, int ac, char **av) { int i, count; aSeen *seen, *first = NULL, *saved = NULL, *sorted[5]; char nuhost[NICKLEN + USERLEN + HOSTLEN + 3], sendstr[256]; if (ac < 2) { notice(n_SeenServ, lptr->nick, "Syntax: SEEN <nick|hostmask>"); notice(n_SeenServ, lptr->nick, ERR_MORE_INFO, n_SeenServ, "SEEN"); return ; } if (strchr(av[1], '*') || strchr(av[1], '?')) { /* This stuff violates privacy like hell, restrict! -- jilles */ if (!IsValidAdmin(lptr)) { notice(n_SeenServ, lptr->nick, "Wildcard SEEN is restricted to admins."); return; } count = 0; for (seen = seenp; seen; seen = seen->prev) { memset(nuhost, 0, sizeof(nuhost)); strncpy(nuhost, seen->nick, NICKLEN); strcat(nuhost, "!"); strncat(nuhost, seen->userhost, USERLEN + HOSTLEN + 1); if (match(av[1], nuhost)) { seen->seen = saved; saved = seen; if (++count > MAXWILDSEEN) break; } } first = saved; if (count > MAXWILDSEEN) { notice(n_SeenServ, lptr->nick, "I found more than %d matches to your query; " "please refine it to see any output", MAXWILDSEEN); return ; } else if (count == 0) { notice(n_SeenServ, lptr->nick, "I found no matching seen records to your query"); return ; } else { for (i = 0; (i < 5) && (i < count); i++) { aSeen **pcandidate = &first; aSeen *tmp; /* pcandidate is the next candidate for the last * element. We iterate the list looking for a better * candidate (ie, a later element) */ /* We look to see if the *next* item is a candidate, * and if it is, we store the value of *our* pointer * to it. That lets us splice out the candidate at * the end. */ for (tmp = *pcandidate; tmp->seen; tmp = tmp->seen) { if (tmp->seen->time > (*pcandidate)->time) { pcandidate = &tmp->seen; } } sorted[i] = *pcandidate; /* Splice that element out of the list */ *pcandidate = (*pcandidate)->seen; } } ircsprintf(sendstr, "I found %d match(es), ", count); if (count > 5) strcat(sendstr, "here are the 5 most recent, "); strcat(sendstr, "sorted:"); count = i; for (i = 0; i < count; i++) { strcat(sendstr, " "); strcat(sendstr, sorted[i]->nick); } strcat(sendstr, ". "); if (sorted[0]->type == 1) { notice(n_SeenServ, lptr->nick, "%s %s (%s) was last seen %s ago, quiting: %s", sendstr, sorted[0]->nick, sorted[0]->userhost, timeago(sorted[0]->time, 0), sorted[0]->msg); } else if (sorted[0]->type == 2) { notice(n_SeenServ, lptr->nick, "%s %s (%s) was last seen %s ago, changing nicks", sendstr, sorted[0]->nick, sorted[0]->userhost, timeago(sorted[0]->time, 0)); } } else { es_seennick(lptr, ac, av); } } /* es_seen */