Beispiel #1
0
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() */