static MEMO_EL * DoActions( MEMO_EL * el, ACTION act ) /****************************************************/ /* Perform one action on the memos. */ { MEMO_EL * new_el; MEMO_EL * prev_el; switch( act ) { case HELP: Help(); break; case ADD: new_el = AddMemo( el ); if( new_el != NULL ) { el = new_el; MemosModified = TRUE; } break; case DELETE: el = DeleteMemo( el ); MemosModified = TRUE; break; case REPLACE: prev_el = el; new_el = AddMemo( el ); if( new_el != NULL ) { DeleteMemo( prev_el ); MemosModified = TRUE; } break; case SHOW: DisplayMemo( el ); break; case UP: el = DoUpAction( el ); break; case DOWN: el = DoDownAction( el ); break; case TOP: el = NULL; break; case TODAY: el = ShowTodaysMemos(); break; case SAVE: if( SaveMemos() ) { MemosModified = FALSE; } break; case QUIT: if( WantToQuit() ) { QuitFlag = TRUE; el = NULL; } } return( el ); }
void MoveMemos(struct NickInfo *source, struct NickInfo *dest) { struct MemoInfo *srcmptr, /* pointer to source's memos */ *dstmptr; /* pointer to dest's memos */ struct Memo *memoptr, *mtmp; if (!source || !dest) return; if (!(srcmptr = FindMemoList(source->nick))) return; /* source has no memos to copy */ if (!(dstmptr = FindMemoList(dest->nick))) { /* * Create a memo structure for dest */ dstmptr = MakeMemoList(); dstmptr->name = MyStrdup(dest->nick); AddMemoList(dstmptr); } /* * Go through source's memo list and create duplicate * structures in dest's list */ for (memoptr = srcmptr->memos; memoptr; memoptr = memoptr->next) { mtmp = MakeMemo(); mtmp->sender = MyStrdup(memoptr->sender); mtmp->sent = memoptr->sent; mtmp->index = ++dstmptr->memocnt; mtmp->flags = memoptr->flags; mtmp->text = MyStrdup(memoptr->text); /* * Now add mtmp, which is a duplicate of memoptr, to dest's * memo list */ AddMemo(dstmptr, mtmp); if (!(mtmp->flags & MS_READ)) dstmptr->newmemos++; /* * Mark all of source's memos for deletion */ memoptr->flags |= MS_DELETE; } /* * Purge source's memos */ PurgeMemos(srcmptr); } /* MoveMemos() */
int StoreMemo(char *target, char *text, struct Luser *lptr) { struct MemoInfo *mi; struct Memo *memoptr; assert(target && text && lptr); if (!(mi = FindMemoList(target))) { mi = MakeMemoList(); mi->name = MyStrdup(target); AddMemoList(mi); } if (MaxMemos && (mi->memocnt >= MaxMemos)) { notice(n_MemoServ, lptr->nick, "%s has reached the maximum memo limit, and cannot receive more", target); return (0); } ++mi->memocnt; ++mi->newmemos; memoptr = MakeMemo(); memoptr->sender = MyStrdup(lptr->nick); memoptr->sent = current_ts; memoptr->index = mi->memocnt; memoptr->text = MyStrdup(text); AddMemo(mi, memoptr); return (memoptr->index); } /* StoreMemo() */
int ms_loaddata() { FILE *fp; char line[MAXLINE], **av; char *keyword; int ac, ret = 1, cnt; struct MemoInfo *mi = NULL; struct NickInfo *nickptr; if (!(fp = fopen(MemoServDB, "r"))) { /* MemoServ data file doesn't exist */ return -1; } cnt = 0; /* load data into list */ while (fgets(line, MAXLINE - 1, fp)) { cnt++; ac = SplitBuf(line, &av); if (!ac) { /* probably a blank line */ MyFree(av); continue; } if (av[0][0] == ';') { /* its a comment */ MyFree(av); continue; } if (!ircncmp("->", av[0], 2)) { /* * check if there are enough args */ if (ac < 5) { fatal(1, "%s:%d Invalid database format (FATAL)", MemoServDB, cnt); ret = -2; MyFree(av); continue; } /* check if there is no nickname before it */ if (!mi) { fatal(1, "%s:%d No nickname associated with data", MemoServDB, cnt); if (ret > 0) ret = -1; MyFree(av); continue; } keyword = av[0] + 2; if (!ircncmp(keyword, "TEXT", 4)) { struct Memo *memoptr; memoptr = MakeMemo(); memoptr->sender = MyStrdup(av[1]); memoptr->sent = atol(av[2]); memoptr->flags = atol(av[3]); if (!(memoptr->flags & MS_READ)) mi->newmemos++; memoptr->text = MyStrdup(av[4] + 1); memoptr->index = ++mi->memocnt; AddMemo(mi, memoptr); } } /* if (!ircncmp("->", keyword, 2)) */ else { if (mi) { if (!mi->memos) { fatal(1, "%s:%d No memos for entry [%s] (skipping)", MemoServDB, cnt, mi->name); MyFree(mi->name); MyFree(mi); mi = NULL; if (ret > 0) ret = -1; } else AddMemoList(mi); } /* * make sure there are enough args on the line: * <nickname> */ if (ac < 1) { fatal(1, "%s:%d Invalid database format (FATAL)", MemoServDB, cnt); ret = -2; mi = NULL; MyFree(av); continue; } if (!(nickptr = FindNick(av[0]))) { fatal(1, "%s:%d Memo entry [%s] is not a registered nickname (skipping)", MemoServDB, cnt, av[0]); if (ret > 0) ret = -1; mi = NULL; MyFree(av); continue; } #ifdef LINKED_NICKNAMES if (nickptr->master) { /* * nickptr is a leaf nickname - they should not have * memo entries */ fatal(1, "%s:%d Memo entry [%s] is not a master nickname (skipping)", MemoServDB, cnt, av[0]); if (ret > 0) ret = (-1); mi = NULL; MyFree(av); continue; } #endif /* LINKED_NICKNAMES */ mi = MakeMemoList(); mi->name = MyStrdup(av[0]); } MyFree(av); } /* while (fgets(line, MAXLINE - 1, fp)) */ if (mi) { if (!mi->memos) { fatal(1, "%s:%d No memos for entry [%s] (skipping)", MemoServDB, cnt, mi->name); MyFree(mi->name); MyFree(mi); if (ret > 0) ret = -1; } else AddMemoList(mi); } fclose (fp); return (ret); } /* ms_loaddata() */
static void m_forward(struct Luser *lptr, struct NickInfo *nptr, int ac, char **av) { struct MemoInfo *from, *target; struct Memo *memoptr = NULL; struct Memo *fromptr; char *to; /* who the memo is sent to */ int index, cnt; char buf[MAXLINE]; struct NickInfo *master, *realptr; #ifdef CHANNELSERVICES struct ChanInfo *ci = NULL; #endif if (!nptr) return; if (ac < 3) { notice(n_MemoServ, lptr->nick, "Syntax: FORWARD <index|ALL> <nick/channel>"); notice(n_MemoServ, lptr->nick, ERR_MORE_INFO, n_MemoServ, "FORWARD"); return; } if (!(from = FindMemoList(nptr->nick))) { notice(n_MemoServ, lptr->nick, "You have no recorded memos"); return; } index = IsNum(av[1]); if ((index < 0) || (index > from->memocnt) || (!index && (irccmp(av[1], "ALL") != 0))) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is an invalid index", av[1]); return; } master = realptr = NULL; if (*av[2] == '#') { #ifndef CHANNELSERVICES notice(n_MemoServ, lptr->nick, "Channel services are disabled"); return; #else if (!(ci = FindChan(av[2]))) { notice(n_MemoServ, lptr->nick, ERR_CH_NOT_REGGED, av[2]); return; } if (!HasAccess(ci, lptr, CA_AUTOOP)) { notice(n_MemoServ, lptr->nick, "AutoOp access is required to forward a memo to [\002%s\002]", ci->name); return; } to = ci->name; #endif } else { /* it was sent to a nickname */ if (!(realptr = FindNick(av[2]))) { notice(n_MemoServ, lptr->nick, ERR_NOT_REGGED, av[2]); return; } master = GetMaster(realptr); assert(master != 0); if (!(master->flags & NS_MEMOS)) { notice(n_MemoServ, lptr->nick, "[\002%s\002] is rejecting all memos", realptr->nick); return; } to = master->nick; } if (!(target = FindMemoList(to))) { target = MakeMemoList(); target->name = MyStrdup(to); AddMemoList(target); } else if (from == target) { /* * If we let someone forward memos to themselves, * the below loop will never end, eventually malloc()'ing too * much and crashing - head it off at the pass */ notice(n_MemoServ, lptr->nick, "You cannot forward memos to yourself"); return; } if (MaxMemos && (target->memocnt >= MaxMemos)) { notice(n_MemoServ, lptr->nick, "%s has reached the maximum memo limit, and cannot receive more", to); return; } cnt = 0; for (fromptr = from->memos; fromptr; fromptr = fromptr->next) { if (!index || (fromptr->index == index)) { memset(&buf, 0, MAXLINE); target->memocnt++; target->newmemos++; cnt++; memoptr = MakeMemo(); memoptr->sender = MyStrdup(lptr->nick); memoptr->sent = current_ts; memoptr->index = target->memocnt; strcpy(buf, "[Fwd]: "); strncat(buf, fromptr->text, MAXLINE - 8); memoptr->text = MyStrdup(buf); AddMemo(target, memoptr); if (MaxMemos && (target->memocnt >= MaxMemos)) break; } } if (!index) ircsprintf(buf, "All memos have"); else ircsprintf(buf, "Memo #%d has", index); notice(n_MemoServ, lptr->nick, "%s been forwarded to [\002%s\002]", buf, target->name); if (master && realptr) { /* * It was sent to a nickname - check if they are online * and notify them */ if ((master->flags & NS_MEMONOTIFY) && (realptr->flags & NS_IDENTIFIED) && FindClient(realptr->nick)) { notice(n_MemoServ, realptr->nick, "You have %d new forwarded memo%s from \002%s\002", cnt, (cnt == 1) ? "" : "s", memoptr->sender); notice(n_MemoServ, realptr->nick, "Type \002/msg %s LIST\002 to view %s", n_MemoServ, (cnt == 1) ? "it" : "them"); } } /* if (master && realptr) */ #ifdef CHANNELSERVICES else { struct Channel *chptr; /* * It was sent to a channel - notify every AOP or higher */ if ((ci) && (chptr = FindChannel(target->name))) { struct ChannelUser *cu; struct NickInfo *tmpn; for (cu = chptr->firstuser; cu; cu = cu->next) { if (FindService(cu->lptr)) continue; tmpn = GetLink(cu->lptr->nick); if (HasAccess(ci, cu->lptr, CA_AUTOOP)) { if (tmpn) { if (!(tmpn->flags & NS_MEMOS) || !(tmpn->flags & NS_MEMONOTIFY)) continue; } notice(n_MemoServ, cu->lptr->nick, "%d new forwarded channel memo%s from \002%s\002", cnt, (cnt == 1) ? "" : "s", memoptr->sender); notice(n_MemoServ, cu->lptr->nick, "Type \002/msg %s LIST %s\002 to view %s", n_MemoServ, chptr->name, (cnt == 1) ? "it" : "them"); } } } } /* else */ #endif /* CHANNELSERVICES */ } /* m_forward() */