Ejemplo n.º 1
0
void sig_handler_common_tt(int sig, void *sc_ptr)
{
	struct sigcontext *sc = sc_ptr;
	struct tt_regs save_regs, *r;
	struct signal_info *info;
	int save_errno = errno, is_user;

	unprotect_kernel_mem();

	r = &TASK_REGS(get_current())->tt;
	save_regs = *r;
	is_user = user_context(SC_SP(sc));
	r->sc = sc;
	if(sig != SIGUSR2) 
		r->syscall = -1;

	change_sig(SIGUSR1, 1);
	info = &sig_info[sig];
	if(!info->is_irq) unblock_signals();

	(*info->handler)(sig, (union uml_pt_regs *) r);

	if(is_user){
		interrupt_end();
		block_signals();
		change_sig(SIGUSR1, 0);
		set_user_mode(NULL);
	}
	*r = save_regs;
	errno = save_errno;
	if(is_user) protect_kernel_mem();
}
Ejemplo n.º 2
0
/*! \brief MODE command handler
 *
 * \param source_p Pointer to allocated Client struct from which the message
 *                 originally comes from.  This can be a local or remote client.
 * \param parc     Integer holding the number of supplied arguments.
 * \param parv     Argument vector where parv[0] .. parv[parc-1] are non-NULL
 *                 pointers.
 * \note Valid arguments for this command are:
 *      - parv[0] = command
 *      - parv[1] = channel or nick name
 *      - parv[2] = modes to be added or removed
 */
static int
m_mode(struct Client *source_p, int parc, char *parv[])
{
  struct Channel *chptr = NULL;

  if (EmptyString(parv[1]))
  {
    sendto_one_numeric(source_p, &me, ERR_NEEDMOREPARAMS, "MODE");
    return 0;
  }

  /* Now, try to find the channel in question */
  if (!IsChanPrefix(*parv[1]))
  {
    /* If here, it has to be a non-channel name */
    set_user_mode(source_p, parc, parv);
    return 0;
  }

  if ((chptr = hash_find_channel(parv[1])) == NULL)
  {
    sendto_one_numeric(source_p, &me, ERR_NOSUCHCHANNEL, parv[1]);
    return 0;
  }

  /* Now known the channel exists */
  if (parc < 3)
  {
    char modebuf[MODEBUFLEN] = "";
    char parabuf[MODEBUFLEN] = "";

    channel_modes(chptr, source_p, modebuf, parabuf);
    sendto_one_numeric(source_p, &me, RPL_CHANNELMODEIS, chptr->name, modebuf, parabuf);
    sendto_one_numeric(source_p, &me, RPL_CREATIONTIME, chptr->name, chptr->creationtime);
    return 0;
  }

  /*
   * bounce all modes from people we deop on sjoin
   * servers have always gotten away with murder,
   * including telnet servers *g* - Dianora
   */
  if (IsServer(source_p) || HasFlag(source_p, FLAGS_SERVICE))
    set_channel_mode(source_p, chptr, NULL, parc - 2, parv + 2);
  else
  {
    struct Membership *member = find_channel_link(source_p, chptr);

    /* Finish the flood grace period... */
    if (MyClient(source_p) && !IsFloodDone(source_p))
      if (!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0')))
        flood_endgrace(source_p);

    set_channel_mode(source_p, chptr, member, parc - 2, parv + 2);
  }

  return 0;
}
Ejemplo n.º 3
0
int
ms_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Channel *chptr = 0;
  struct ModeBuf mbuf;
  struct Membership *member = 0;

  if (parc < 3)
    return need_more_params(sptr, "MODE");

  if (IsLocalChannel(parv[1]))
    return 0;

  if (!(chptr = FindChannel(parv[1])))
    return set_user_mode(cptr, sptr, parc, parv);

  ClrFlag(sptr, FLAG_TS8);

  if (IsServer(sptr)) {
    if (cli_uworld(sptr))
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to clients */
		    MODEBUF_DEST_SERVER  | /* Send mode to servers */
		    MODEBUF_DEST_HACK4));  /* Send a HACK(4) message */
    else
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to clients */
		    MODEBUF_DEST_SERVER  | /* Send mode to servers */
		    MODEBUF_DEST_HACK3));  /* Send a HACK(3) message */

    mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
	       (MODE_PARSE_SET    | /* Set the mode */
		MODE_PARSE_STRICT | /* Interpret it strictly */
		MODE_PARSE_FORCE), NULL); /* And force it to be accepted */
  } else {
    if (!IsChannelService(sptr) && (!(member = find_member_link(chptr, sptr)) || (!IsChanOp(member) && !IsHalfOp(member)))) {
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_SERVER |  /* Send mode to server */
		    MODEBUF_DEST_HACK2  |  /* Send a HACK(2) message */
		    MODEBUF_DEST_DEOP   |  /* Deop the source */
		    MODEBUF_DEST_BOUNCE)); /* And bounce the MODE */
      mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
		 (MODE_PARSE_STRICT |  /* Interpret it strictly */
		  MODE_PARSE_BOUNCE), member); /* And bounce the MODE */
    } else {
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to clients */
		    MODEBUF_DEST_SERVER)); /* Send mode to servers */
      mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
		 (MODE_PARSE_SET    | /* Set the mode */
		  MODE_PARSE_STRICT | /* Interpret it strictly */
		  MODE_PARSE_FORCE), member); /* And force it to be accepted */
    }
  }

  return modebuf_flush(&mbuf);
}
Ejemplo n.º 4
0
void sig_handler_common_tt(int sig, void *sc_ptr)
{
	struct sigcontext *sc = sc_ptr;
	struct tt_regs save_regs, *r;
	struct signal_info *info;
	int save_errno = errno, is_user;

	unprotect_kernel_mem();

	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
	 * handler.  This can happen in copy_user, and if SEGV is disabled,
	 * the process will die.
	 */
	if(sig == SIGSEGV)
		change_sig(SIGSEGV, 1);

	/* This is done because to allow SIGSEGV to be delivered inside a SEGV
	 * handler.  This can happen in copy_user, and if SEGV is disabled,
	 * the process will die.
	 */
	if(sig == SIGSEGV)
		change_sig(SIGSEGV, 1);

	r = &TASK_REGS(get_current())->tt;
	save_regs = *r;
	is_user = user_context(SC_SP(sc));
	r->sc = sc;
	if(sig != SIGUSR2) 
		r->syscall = -1;

	info = &sig_info[sig];
	if(!info->is_irq) unblock_signals();

	(*info->handler)(sig, (union uml_pt_regs *) r);

	if(is_user){
		interrupt_end();
		block_signals();
		set_user_mode(NULL);
	}
	*r = save_regs;
	errno = save_errno;
	if(is_user) protect_kernel_mem();
}
Ejemplo n.º 5
0
void finish_fork_handler(int sig)
{
 	UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
	suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);

	force_flush_all();
	if(current->thread.prev_sched != NULL)
		schedule_tail(current->thread.prev_sched);
	current->thread.prev_sched = NULL;

	enable_timer();
	change_sig(SIGVTALRM, 1);
	local_irq_enable();
	if(current->mm != current->parent->mm)
		protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
			       1, 0, 1);
	task_protections((unsigned long) current_thread);

	free_page(current->thread.temp_stack);
	local_irq_disable();
	change_sig(SIGUSR1, 0);
	set_user_mode(current);
}
Ejemplo n.º 6
0
/*
 * m_mode - MODE command handler
 * parv[0] - sender
 * parv[1] - channel
 */
static void
m_mode(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  struct Channel *chptr = NULL;
  struct Membership *member;
  static char modebuf[MODEBUFLEN];
  static char parabuf[MODEBUFLEN];

  if (parv[1][0] == '\0')
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               me.name, source_p->name, "MODE");
    return;
  }

  /* Now, try to find the channel in question */
  if (!IsChanPrefix(parv[1][0]))
  {
    /* if here, it has to be a non-channel name */
    set_user_mode(client_p, source_p, parc, parv);
    return;
  }

  if (!check_channel_name(parv[1]))
  { 
    sendto_one(source_p, form_str(ERR_BADCHANNAME),
               me.name, source_p->name, parv[1]);
    return;
  }

  chptr = hash_find_channel(parv[1]);

  if (chptr == NULL)
  {
      /* if chptr isn't found locally, it =could= exist
       * on the uplink. So ask.
       */
      
      /* LazyLinks */
      /* only send a mode upstream if a local client sent this request
       * -davidt
       */
      if (MyClient(source_p) && !ServerInfo.hub && uplink &&
	   IsCapable(uplink, CAP_LL))
	{
	  sendto_one(uplink, ":%s MODE %s %s",
                     ID_or_name(source_p, uplink),
		     parv[1], (parv[2] ? parv[2] : ""));
	  return;
	}
      else
	{
	  sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
		     me.name, parv[0], parv[1]);
	  return;
	}
    }

  /* Now known the channel exists */
  if (parc < 3)
  {
    channel_modes(chptr, source_p, modebuf, parabuf);
    sendto_one(source_p, form_str(RPL_CHANNELMODEIS),
               me.name, parv[0], parv[1], modebuf, parabuf);
    sendto_one(source_p, form_str(RPL_CREATIONTIME),
               me.name, parv[0], parv[1], chptr->channelts);
  }
  /* bounce all modes from people we deop on sjoin
   * servers have always gotten away with murder,
   * including telnet servers *g* - Dianora
   *
   * XXX Is it worth the bother to make an ms_mode() ? - Dianora
   */
  else if (IsServer(source_p))
  {
    set_channel_mode(client_p, source_p, chptr, NULL, parc - 2, parv + 2,
                     chptr->chname);
  }
  else
  {
    member = find_channel_link(source_p, chptr);

    if (!has_member_flags(member, CHFL_DEOPPED))
    {
      /* Finish the flood grace period... */
      if (MyClient(source_p) && !IsFloodDone(source_p))
      {
        if (!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0')))
          flood_endgrace(source_p);
      }

      set_channel_mode(client_p, source_p, chptr, member, parc - 2, parv + 2,
                       chptr->chname);
    }
  }
}
Ejemplo n.º 7
0
int
m_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Channel *chptr = 0;
  unsigned int hoflags  = 0;
  struct ModeBuf mbuf;
  struct Membership *member = 0;

  if (parc < 2)
    return need_more_params(sptr, "MODE");

  clean_channelname(parv[1]);

  if (!(chptr = FindChannel(parv[1])))
    return set_user_mode(cptr, sptr, parc, parv);

  ClrFlag(sptr, FLAG_TS8);

  member = find_member_link(chptr, sptr);

  if (parc < 3) {
    char modebuf[MODEBUFLEN];
    char parabuf[MODEBUFLEN];

    *modebuf = *parabuf = '\0';
    modebuf[1] = '\0';
    channel_modes(sptr, modebuf, parabuf, sizeof(parabuf), chptr);
    send_reply(sptr, RPL_CHANNELMODEIS, chptr->chname, modebuf, parabuf);
    send_reply(sptr, RPL_CREATIONTIME, chptr->chname, chptr->creationtime);
    return 0;
  }

  if ((!member && !IsChannelService(sptr)) ||
      (member && !IsChanOp(member) && !IsHalfOp(member))) {
    if (IsLocalChannel(chptr->chname) && HasPriv(sptr, PRIV_MODE_LCHAN)) {
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to channel */
		    MODEBUF_DEST_HACK4));  /* Send HACK(4) notice */
      mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
		 (MODE_PARSE_SET |    /* Set the mode */
		  MODE_PARSE_FORCE), NULL); /* Force it to take */
      return modebuf_flush(&mbuf);
    } else
      mode_parse(0, cptr, sptr, chptr, parc - 2, parv + 2,
		 (member ? MODE_PARSE_NOTOPER : MODE_PARSE_NOTMEMBER), NULL);
    return 0;
  }

  modebuf_init(&mbuf, sptr, cptr, chptr,
	       (MODEBUF_DEST_CHANNEL | /* Send mode to channel */
		MODEBUF_DEST_SERVER)); /* Send mode to servers */

  if (member && IsChanOp(member))
    hoflags = MODE_PARSE_SET; /* set unconditionally */
  else if (member && IsHalfOp(member))
    hoflags = MODE_PARSE_ISHALFOP|MODE_PARSE_SET|MODE_PARSE_NOTOPER; /* allowed to +v */
  else
    hoflags = MODE_PARSE_NOTOPER;
  mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2, hoflags, member);
  return modebuf_flush(&mbuf);
}
Ejemplo n.º 8
0
int
ms_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Channel *chptr = 0;
  struct ModeBuf mbuf;
  struct Membership *member;

  if (parc < 3)
    return need_more_params(sptr, "MODE");

  if (IsLocalChannel(parv[1]))
    return 0;

  if (!(chptr = FindChannel(parv[1])))
  {
    struct Client *acptr;

    acptr = FindUser(parv[1]);
    if (!acptr)
    {
      return 0;
    }
    else if (sptr != acptr)
    {
      sendwallto_group_butone(&me, WALL_WALLOPS, 0, 
                              "MODE for User %s from %s!%s", parv[1],
                              cli_name(cptr), cli_name(sptr));
      return 0;
    }
    return set_user_mode(cptr, sptr, parc, parv, ALLOWMODES_ANY);
  }

  ClrFlag(sptr, FLAG_TS8);

  if (IsServer(sptr)) {
    if (find_conf_byhost(cli_confs(cptr), cli_name(sptr), CONF_UWORLD))
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to clients */
		    MODEBUF_DEST_SERVER  | /* Send mode to servers */
		    MODEBUF_DEST_HACK4));  /* Send a HACK(4) message */
    else if (!feature_bool(FEAT_OPLEVELS))
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to clients */
		    MODEBUF_DEST_SERVER  | /* Send mode to servers */
		    MODEBUF_DEST_HACK3));  /* Send a HACK(3) message */
    else
      /* Servers need to be able to op people who join using the Apass
       * or upass, as well as people joining a zannel, therefore we do
       * not generate HACK3 when oplevels are on. */
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to clients */
		    MODEBUF_DEST_SERVER));   /* Send mode to servers */

    mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
	       (MODE_PARSE_SET    | /* Set the mode */
		MODE_PARSE_STRICT | /* Interpret it strictly */
		MODE_PARSE_FORCE),  /* And force it to be accepted */
	        NULL);
  } else {
    if (!(member = find_member_link(chptr, sptr)) || !IsChanOp(member)) {
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_SERVER |  /* Send mode to server */
		    MODEBUF_DEST_HACK2  |  /* Send a HACK(2) message */
		    MODEBUF_DEST_DEOP   |  /* Deop the source */
		    MODEBUF_DEST_BOUNCE)); /* And bounce the MODE */
      mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
		 (MODE_PARSE_STRICT |  /* Interpret it strictly */
		  MODE_PARSE_BOUNCE),  /* And bounce the MODE */
		  member);
    } else {
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to clients */
		    MODEBUF_DEST_SERVER)); /* Send mode to servers */
      mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
		 (MODE_PARSE_SET    | /* Set the mode */
		  MODE_PARSE_STRICT | /* Interpret it strictly */
		  MODE_PARSE_FORCE),  /* And force it to be accepted */
		  member);
    }
  }

  return modebuf_flush(&mbuf);
}
Ejemplo n.º 9
0
int
m_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv[])
{
  struct Channel *chptr = 0;
  struct ModeBuf mbuf;
  struct Membership *member;

  if (parc < 2)
    return need_more_params(sptr, "MODE");

  if (!IsChannelName(parv[1]) || !(chptr = FindChannel(parv[1])))
  {
    struct Client *acptr;

    acptr = FindUser(parv[1]);
    if (!acptr)
    {
      send_reply(sptr, ERR_NOSUCHCHANNEL, parv[1]);
      return 0;
    }
    else if (sptr != acptr)
    {
      send_reply(sptr, ERR_USERSDONTMATCH);
      return 0;
    }
    return set_user_mode(cptr, sptr, parc, parv, ALLOWMODES_ANY);
  }

  ClrFlag(sptr, FLAG_TS8);

  member = find_member_link(chptr, sptr);

  if (parc < 3) {
    char modebuf[MODEBUFLEN];
    char parabuf[MODEBUFLEN];

    *modebuf = *parabuf = '\0';
    modebuf[1] = '\0';
    channel_modes(sptr, modebuf, parabuf, sizeof(parabuf), chptr, member);
    send_reply(sptr, RPL_CHANNELMODEIS, chptr->chname, modebuf, parabuf);
    send_reply(sptr, RPL_CREATIONTIME, chptr->chname, chptr->creationtime);
    return 0;
  }

  if (!member || !IsChanOp(member)) {
    if (IsLocalChannel(chptr->chname) && HasPriv(sptr, PRIV_MODE_LCHAN)) {
      modebuf_init(&mbuf, sptr, cptr, chptr,
		   (MODEBUF_DEST_CHANNEL | /* Send mode to channel */
		    MODEBUF_DEST_HACK4));  /* Send HACK(4) notice */
      mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2,
		 (MODE_PARSE_SET |    /* Set the mode */
		  MODE_PARSE_FORCE),  /* Force it to take */
		  member);
      return modebuf_flush(&mbuf);
    } else
      mode_parse(0, cptr, sptr, chptr, parc - 2, parv + 2,
		 (member ? MODE_PARSE_NOTOPER : MODE_PARSE_NOTMEMBER), member);
    return 0;
  }

  modebuf_init(&mbuf, sptr, cptr, chptr,
	       (MODEBUF_DEST_CHANNEL | /* Send mode to channel */
		MODEBUF_DEST_SERVER)); /* Send mode to servers */
  mode_parse(&mbuf, cptr, sptr, chptr, parc - 2, parv + 2, MODE_PARSE_SET, member);
  return modebuf_flush(&mbuf);
}
Ejemplo n.º 10
0
/*
 * m_mode - MODE command handler
 * parv[0] - sender
 * parv[1] - channel
 */
static void
m_mode(struct Client *client_p, struct Client *source_p,
       int parc, char *parv[])
{
  struct Channel *chptr = NULL;
  struct Membership *member;
  static char modebuf[MODEBUFLEN];
  static char parabuf[MODEBUFLEN];

  if (EmptyString(parv[1]))
  {
    sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
               me.name, source_p->name, "MODE");
    return;
  }

  /* Now, try to find the channel in question */
  if (!IsChanPrefix(*parv[1]))
  {
    /* if here, it has to be a non-channel name */
    set_user_mode(client_p, source_p, parc, parv);
    return;
  }

  if ((chptr = hash_find_channel(parv[1])) == NULL)
  {
    sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
	       ID_or_name(&me, source_p->from),
	       ID_or_name(source_p, source_p->from),
	       parv[1]);
    return;
  }

  /* Now known the channel exists */
  if (parc < 3)
  {
    channel_modes(chptr, source_p, modebuf, parabuf);
    sendto_one(source_p, form_str(RPL_CHANNELMODEIS),
               me.name, source_p->name, chptr->chname, modebuf, parabuf);
    sendto_one(source_p, form_str(RPL_CREATIONTIME),
               me.name, source_p->name, chptr->chname, chptr->channelts);
  }
  /* bounce all modes from people we deop on sjoin
   * servers have always gotten away with murder,
   * including telnet servers *g* - Dianora
   *
   * XXX Is it worth the bother to make an ms_mode() ? - Dianora
   */
  else if (IsServer(source_p))
  {
    set_channel_mode(client_p, source_p, chptr, NULL, parc - 2, parv + 2,
                     chptr->chname);
  }
  else
  {
    member = find_channel_link(source_p, chptr);

    if (!has_member_flags(member, CHFL_DEOPPED))
    {
      /* Finish the flood grace period... */
      if (MyClient(source_p) && !IsFloodDone(source_p))
      {
        if (!((parc == 3) && (parv[2][0] == 'b') && (parv[2][1] == '\0')))
          flood_endgrace(source_p);
      }

      set_channel_mode(client_p, source_p, chptr, member, parc - 2, parv + 2,
                       chptr->chname);
    }
  }
}
Ejemplo n.º 11
0
void do_oper(struct Client* cptr, struct Client* sptr, struct ConfItem* aconf)
{
  struct Flags old_mode = cli_flags(sptr);
  char*        modes;
  char*        parv[2];
  char*        join[3];
  char         chan[CHANNELLEN-1];
  char*        ajoinchan;
  char*        ajoinnotice;
  unsigned int snomask = 0;

  parv[0] = cli_name(sptr);
  parv[1] = NULL;

  SetOper(sptr);
  client_set_privs(sptr, aconf);
  ClearOper(sptr);

  snomask = ConfSnoMask(aconf) & SNO_ALL;
  snomask |= aconf->snomask & SNO_ALL;

  ajoinchan = ConfAjoinChan(aconf);
  ajoinnotice = ConfAjoinNotice(aconf);

  if (MyUser(sptr)) {
    SetLocOp(sptr);
    if (HasPriv(sptr, PRIV_PROPAGATE))
    {
      ClearLocOp(sptr);
      SetOper(sptr);
      if (HasPriv(sptr, PRIV_ADMIN))
        SetAdmin(sptr);
      if (!IsHideOper(sptr) && !IsChannelService(sptr) && !IsBot(sptr))
        ++UserStats.opers;
    }
    cli_handler(sptr) = OPER_HANDLER;

    SetFlag(sptr, FLAG_WALLOP);
    SetFlag(sptr, FLAG_SERVNOTICE);
    SetFlag(sptr, FLAG_DEBUG);

    if (snomask)
      set_snomask(sptr, snomask, SNO_ADD);
    else
      set_snomask(sptr, feature_int(FEAT_SNOMASK_OPERDEFAULT), SNO_ADD);
    cli_max_sendq(sptr) = 0; /* Get the sendq from the oper's class */
    cli_max_recvq(sptr) = 0; /* Get the recvq from the oper's class */
    cli_lag_min(sptr) = -2; /* Get the fake lag minimum from the oper's class */
    cli_lag_factor(sptr) = -2; /* Get the fake lag factor from the oper's class */
    send_umode_out(sptr, sptr, &old_mode, HasPriv(sptr, PRIV_PROPAGATE));
  } else {
    client_send_privs(&me, sptr, sptr);

    if (HasPriv(sptr, PRIV_PROPAGATE)) {
      modes = (HasPriv(sptr, PRIV_ADMIN) ? "aowsg" : "owsg");
    } else {
      modes = "Owsg";
    }

    sendcmdto_one(&me, CMD_MODE, sptr, "%s %s", cli_name(sptr), modes);
  }

  modes = ConfUmode(aconf);
  if (modes) {
    if (MyUser(sptr)) {
      char *umodev[] = { NULL, NULL, NULL, NULL };
      umodev[1] = cli_name(sptr);
      umodev[2] = modes;
      old_mode = cli_flags(sptr);
      set_user_mode(sptr, sptr, 3, umodev, ALLOWMODES_ANY);
      send_umode(NULL, sptr, &old_mode, HasPriv(sptr, PRIV_PROPAGATE));
      if ((cli_snomask(sptr) != feature_int(FEAT_SNOMASK_OPERDEFAULT)) &&
          HasFlag(sptr, FLAG_SERVNOTICE))
        send_reply(sptr, RPL_SNOMASK, cli_snomask(sptr), cli_snomask(sptr));
    } else {
      if (snomask)
        sendcmdto_one(&me, CMD_MODE, sptr, "%s %s+s +%d", cli_name(sptr), modes, snomask);
      else
        sendcmdto_one(&me, CMD_MODE, sptr, "%s %s", cli_name(sptr), modes);
    }
  }

  send_reply(sptr, RPL_YOUREOPER);

  if ((feature_int(FEAT_HOST_HIDING_STYLE) == 1) ||
      (feature_int(FEAT_HOST_HIDING_STYLE) == 3))
    hide_hostmask(sptr);

  if (!EmptyString(ajoinchan))
  {
    if (!EmptyString(ajoinnotice))
      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, ajoinnotice);

    ircd_strncpy(chan, ajoinchan, CHANNELLEN-1);
    join[0] = cli_name(sptr);
    join[1] = chan;
    join[2] = NULL;
    m_join(sptr, sptr, 2, join);
  }

  if (!EmptyString(aconf->autojoinchan))
  {
    if (!EmptyString(aconf->autojoinnotice))
      sendcmdto_one(&me, CMD_NOTICE, sptr, "%C :%s", sptr, aconf->autojoinnotice);

    ircd_strncpy(chan, aconf->autojoinchan, CHANNELLEN-1);
    join[0] = cli_name(sptr);
    join[1] = chan;
    join[2] = NULL;
    m_join(sptr, sptr, 2, join);
  }

  sendto_opmask_butone_global((MyUser(sptr) ? &me : NULL), SNO_OLDSNO,
     "%s (%s@%s) is now operator (%c)",
     cli_name(sptr), cli_user(sptr)->username, cli_user(sptr)->realhost,
     IsOper(sptr) ? 'O' : 'o');

  if (feature_bool(FEAT_OPERMOTD))
    m_opermotd(sptr, sptr, 1, parv);

  log_write(LS_OPER, L_INFO, 0, "OPER (%s) by (%#C)", aconf->name, sptr);
}