Exemple #1
0
Relation Relation::join(Relation r2) {
	// Combine the schemes and make a new empty relation that uses the combined schemes
	Relation join_result = Relation("temp_join");
	join_result.scheme = join_scheme(r2);

	// Find which attributes they have in common to prep for the join
	std::vector<std::pair<int, int>> common_attributes = get_common_attributes(r2);

	for (Tuple t1 : this->tuples) {
		for (Tuple t2 : r2.tuples) {
			if (common_attributes.size() > 0) {
				// Check if the tuples can join
				bool join = can_join(t1, t2, common_attributes);
				if (join) {
					// Build the joined tuple and add it to the new relation
					Tuple t = join_tuples(t1, t2, common_attributes);
					join_result.tuples.insert(t);
				}
			}
			else {
				Tuple t = do_product(t1, t2);
				join_result.tuples.insert(t);
			}
		}
	}

	return join_result;
}
Exemple #2
0
static int cb_join(aClient *sptr, aChannel *chptr, char *parv[]) {
    aModeB	*p = NULL;	

    
    if (!can_join(sptr, sptr, chptr, NULL, NULL, parv))  /* test for operoverride or invite */
    {
	return HOOK_CONTINUE;
    }
 
    if (chptr->mode.extmode & EXTCMODE_BANLINK) /* mode +B set? */
    {
        if (is_banned(sptr, chptr, BANCHK_JOIN))  /* user is banned? */
	{
	    p = (aModeB *) extcmode_get_struct(chptr->mode.extmodeparam, 'B');
	    if (p && p->val)
	    { 

                sendto_one(sptr, ":%s 470 %s %s (you are banned) transferring you to %s", 
				    me.name, sptr->name, chptr->chname, p->val);

                parv[0] = sptr->name;
                parv[1] = p->val;
		do_join(sptr, sptr, 2, parv);

		return HOOK_DENY;
	    }
	}
    }
    return HOOK_CONTINUE;
}
Exemple #3
0
/*
 * m_lljoin
 *      parv[0] = sender prefix
 *      parv[1] = channel
 *      parv[2] = nick ("!nick" == cjoin)
 *      parv[3] = vchan/key (optional)
 *      parv[4] = key (optional)
 *
 * If a lljoin is received, from our uplink, join
 * the requested client to the given channel, or ignore it
 * if there is an error.
 *
 *   Ok, the way this works. Leaf client tries to join a channel, 
 * it doesn't exist so the join does a cburst request on behalf of the
 * client, and aborts that join. The cburst sjoin's the channel if it
 * exists on the hub, and sends back an LLJOIN to the leaf. Thats where
 * this is now..
 *
 */
static void ms_lljoin(struct Client *client_p,
                     struct Client *source_p,
                     int parc,
                     char *parv[])
{
  char *chname = NULL;
  char *nick = NULL;
  char *key = NULL;
  char *vkey = NULL;
  int  flags;
  int  i;
  struct Client *target_p;
  struct Channel *chptr, *vchan_chptr, *root_vchan;
#ifdef VCHANS
  int cjoin = 0;
  int  vc_ts;
  char *pvc = NULL;
#endif

  if(uplink && !IsCapable(uplink,CAP_LL))
    {
      sendto_realops_flags(FLAGS_ALL, L_ALL,
			   "*** LLJOIN requested from non LL server %s",
			   client_p->name);
      return;
    }

  chname = parv[1];
  if(chname == NULL)
    return;

  nick = parv[2];
  if(nick == NULL)
    return;

#ifdef VCHANS
  if (nick[0] == '!')
  {
    cjoin = 1;
    nick++;
  }
 
  if(parc > 4)
  {
    key = parv[4];
    vkey = parv[3];
  }
#endif
  else if(parc >3)
  {
    key = vkey = parv[3];
  }

  flags = 0;

  target_p = find_client(nick);

  if( !target_p || !target_p->user )
    return;

  if( !MyClient(target_p) )
    return;

  chptr = hash_find_channel(chname);

#ifdef VCHANS
  if (cjoin)
  {
    if(!chptr) /* Uhm, bad! */
    {
      sendto_realops_flags(FLAGS_ALL, L_ALL,
        "LLJOIN %s %s called by %s, but root chan doesn't exist!",
        chname, nick, client_p->name);
      return;
    }
    flags = CHFL_CHANOP;

    if(! (vchan_chptr = cjoin_channel(chptr, target_p, chname)))
      return;

    root_vchan = chptr;
    chptr = vchan_chptr;
  }
  else
#endif
  {
#ifdef VCHANS
    if (chptr)
    {
      vchan_chptr = select_vchan(chptr, target_p, vkey, chname);
    }
    else
#endif
    {
      chptr = vchan_chptr = get_or_create_channel(target_p, chname, NULL);
      flags = CHFL_CHANOP;
    }
   
#ifdef VCHANS
    if (vchan_chptr != chptr)
    {
      root_vchan = chptr;
      chptr = vchan_chptr;
    }
    else
#endif
      root_vchan = chptr;

    if(!chptr || !root_vchan)
      return;

    if (chptr->users == 0)
      flags = CHFL_CHANOP;
    else
      flags = 0;

    /* XXX in m_join.c :( */
    /* check_spambot_warning(target_p, chname); */

    /* They _could_ join a channel twice due to lag */
    if(chptr)
    {
      if (IsMember(target_p, chptr))    /* already a member, ignore this */
        return;
    }
    else
    {
      sendto_one(target_p, form_str(ERR_UNAVAILRESOURCE),
                 me.name, nick, root_vchan->chname);
      return;
    }

    if( (i = can_join(target_p, chptr, key)) )
    {
      sendto_one(target_p,
                 form_str(i), me.name, nick, root_vchan->chname);
      return;
    }
  }

  if ((target_p->user->joined >= ConfigChannel.max_chans_per_user) &&
      (!IsOper(target_p) || (target_p->user->joined >= 
                             ConfigChannel.max_chans_per_user*3)))
    {
      sendto_one(target_p, form_str(ERR_TOOMANYCHANNELS),
		 me.name, nick, root_vchan->chname );
      return; 
    }
  
  if(flags == CHFL_CHANOP)
    {
      chptr->channelts = CurrentTime;
      /*
       * XXX - this is a rather ugly hack.
       *
       * Unfortunately, there's no way to pass
       * the fact that it is a vchan through SJOIN...
       */
      /* Prevent users creating a fake vchan */
#ifdef VCHANS
      if (chname[0] == '#' && chname[1] == '#')
        {
          if ((pvc = strrchr(chname+3, '_')))
          {
            /*
             * OK, name matches possible vchan:
             * ##channel_blah
             */
            pvc++; /*  point pvc after last _ */
            vc_ts = atol(pvc);
            /*
             * if blah is the same as the TS, up the TS
             * by one, to prevent this channel being
             * seen as a vchan
             */
            if (vc_ts == CurrentTime)
              chptr->channelts++;
          }
        }
#endif

      sendto_one(uplink,
		 ":%s SJOIN %lu %s + :@%s",
		 me.name,
		 (unsigned long) chptr->channelts,
		 chptr->chname,
		 nick);
    }

  /* a user can create a channel with halfops..? */
#if 0
  else if ((flags == CHFL_HALFOP) && (IsCapable(uplink, CAP_HOPS)))
    {
      sendto_one(uplink,
		 ":%s SJOIN %lu %s + :%%%s",
		 me.name,
		 (unsigned long) chptr->channelts,
		 chptr->chname,
		 nick);
    }
#endif
  else
    {
      sendto_one(uplink,
		 ":%s SJOIN %lu %s + :%s",
		 me.name,
		 (unsigned long) chptr->channelts,
		 chptr->chname,
		 nick);
    }

  add_user_to_channel(chptr, target_p, flags);

#ifdef VCHANS
  if ( chptr != root_vchan )
    add_vchan_to_client_cache(target_p,root_vchan,chptr);
#endif
 
  sendto_channel_local(ALL_MEMBERS, chptr,
		       ":%s!%s@%s JOIN :%s",
		       target_p->name,
		       target_p->username,
		       target_p->host,
		       root_vchan->chname);
  
  if( flags & CHFL_CHANOP )
  {
    chptr->mode.mode |= MODE_TOPICLIMIT;
    chptr->mode.mode |= MODE_NOPRIVMSGS;
      
    sendto_channel_local(ALL_MEMBERS,chptr,
                         ":%s MODE %s +nt",
                         me.name, root_vchan->chname);
    sendto_one(uplink, 
               ":%s MODE %s +nt",
               me.name, chptr->chname);
  }

  channel_member_names(target_p, chptr, chname, 1);
}
Exemple #4
0
/*
 * m_lljoin
 *      parv[0] = sender prefix
 *      parv[1] = channel
 *      parv[2] = nick ("!nick" == cjoin)
 *      parv[3] = key (optional)
 *
 * If a lljoin is received, from our uplink, join
 * the requested client to the given channel, or ignore it
 * if there is an error.
 *
 *   Ok, the way this works. Leaf client tries to join a channel, 
 * it doesn't exist so the join does a cburst request on behalf of the
 * client, and aborts that join. The cburst sjoin's the channel if it
 * exists on the hub, and sends back an LLJOIN to the leaf. Thats where
 * this is now..
 *
 */
static void
ms_lljoin(struct Client *client_p, struct Client *source_p,
          int parc, char *parv[])
{
  char *chname = NULL;
  char *nick = NULL;
  char *key = NULL;
  int  flags;
  int  i;
  struct Client *target_p;
  struct Channel *chptr;

  if (uplink && !IsCapable(uplink,CAP_LL))
  {
      sendto_realops_flags(UMODE_ALL, L_ALL,
			   "*** LLJOIN requested from non LL server %s",
			   client_p->name);
      return;
  }

  chname = parv[1];
  if(chname == NULL)
    return;

  nick = parv[2];
  if(nick == NULL)
    return;

  if (parc >3)
    key = parv[3];

  flags = 0;

  target_p = find_person(client_p, nick);

  if (!target_p)
    return;

  if (!MyClient(target_p))
    return;

  if (!check_channel_name(chname, 0))
  {
    sendto_gnotice_flags(UMODE_DEBUG, L_ALL, me.name, &me, NULL,
                         "*** Too long or invalid channel name from %s: %s",
                         target_p->name, chname);
    return;
  }

  chptr = make_channel(chname);
  flags = CHFL_CHANOP;
   
  if(!chptr)
    return;

  if (dlink_list_length(&chptr->members) == 0)
    flags = CHFL_CHANOP;
  else
    flags = 0;

  /* XXX in m_join.c :( */
  /* check_spambot_warning(target_p, chname); */

  /* They _could_ join a channel twice due to lag */
  if(chptr)
  {
    if (IsMember(target_p, chptr))    /* already a member, ignore this */
      return;
  }
  else
  {
    sendto_one(target_p, form_str(ERR_UNAVAILRESOURCE),
               me.name, nick, chptr->chname);
    return;
  }

  if ((i = can_join(target_p, chptr, key)))
  {
    sendto_one(target_p, form_str(i),
               me.name, nick, chptr->chname);
    return;
  }

  if ((dlink_list_length(&target_p->channel) >= ConfigChannel.max_chans_per_user) &&
      (!IsOper(target_p) || (dlink_list_length(&target_p->channel) >=
                             ConfigChannel.max_chans_per_user*3)))
  {
      sendto_one(target_p, form_str(ERR_TOOMANYCHANNELS),
		 me.name, nick, chptr->chname );
      return; 
  }
  
  if (flags == CHFL_CHANOP)
  {
      chptr->channelts = CurrentTime;

      sendto_one(uplink,
		 ":%s SJOIN %lu %s + :@%s",
		 me.name,
		 (unsigned long) chptr->channelts,
		 chptr->chname,
		 nick);
  }

  sendto_one(uplink,
             ":%s SJOIN %lu %s + :%s",
	     me.name,
	     (unsigned long) chptr->channelts,
	     chptr->chname,
	     nick);

  add_user_to_channel(chptr, target_p, flags, YES);

  sendto_channel_local(ALL_MEMBERS, NO, chptr,
		       ":%s!%s@%s JOIN :%s",
		       target_p->name,
		       target_p->username,
		       target_p->host,
		       chptr->chname);
  
  if (flags & CHFL_CHANOP)
  {
    chptr->mode.mode |= MODE_TOPICLIMIT;
    chptr->mode.mode |= MODE_NOPRIVMSGS;
      
    sendto_channel_local(ALL_MEMBERS, NO, chptr,
                         ":%s MODE %s +nt",
                         me.name, chptr->chname);
    sendto_one(uplink, 
               ":%s MODE %s +nt",
               me.name, chptr->chname);
  }

  channel_member_names(target_p, chptr, 1);
}
Exemple #5
0
/*
 * m_join
 *      parv[0] = sender prefix
 *      parv[1] = channel
 *      parv[2] = channel password (key)
 */
static void
m_join(struct Client *client_p,
       struct Client *source_p,
       int parc,
       char *parv[])
{
  struct Channel *chptr = NULL;
  char  *name, *key = NULL;
  int   i, flags = 0;
  char  *p = NULL, *p2 = NULL;
  int   successful_join_count = 0; /* Number of channels successfully joined */
  
  if (*parv[1] == '\0')
    {
      sendto_one(source_p, form_str(ERR_NEEDMOREPARAMS),
                 me.name, parv[0], "JOIN");
      return;
    }

  if (parc > 2)
    {
      key = strtoken(&p2, parv[2], ",");
    }

  for (name = strtoken(&p, parv[1], ","); name;
         key = (key) ? strtoken(&p2, NULL, ",") : NULL,
         name = strtoken(&p, NULL, ","))
    {

      if(!check_channel_name(name))
      {
        sendto_one(source_p, form_str(ERR_BADCHANNAME),
	           me.name, source_p->name, (unsigned char*)name);
        continue;
      }

      /*
      ** JOIN 0 sends out a part for all channels a user
      ** has joined.
      **
      ** this should be either disabled or selectable in
      ** config file .. it's abused a lot more than it's
      ** used these days :/ --is
      */
      if (*name == '0' && !atoi(name))
      {
        if (source_p->user->channel.head == NULL)
          continue;
	  
        do_join_0(&me,source_p);
	continue;
      }
      
      /* check it begins with # or & */
      else if(!IsChannelName(name))
      {
        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
	           me.name, source_p->name, name);
	continue;
      }

      if(ConfigServerHide.disable_local_channels &&
        (*name == '&'))
      {
        sendto_one(source_p, form_str(ERR_NOSUCHCHANNEL),
	           me.name, source_p->name, name);
        continue;
      }

      /* check the length */
      if (strlen(name) > CHANNELLEN)
      {
        sendto_one(source_p, form_str(ERR_BADCHANNAME),
	           me.name, source_p->name, name);
	continue;
      }
      
      /* see if its resv'd */
      if(find_channel_resv(name) && 
         (!IsOper(source_p) || !ConfigChannel.no_oper_resvs))
	{
	  sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
		     me.name, source_p->name, name);
          sendto_realops_flags(UMODE_SPY, L_ALL,
                   "User %s (%s@%s) is attempting to join locally juped channel %s",
                   source_p->name, source_p->username, source_p->host, name);
	  continue;
	}

      /* look for the channel */
      if((chptr = hash_find_channel(name)) != NULL)
	{
	  if(IsMember(source_p, chptr))
            return;

	  if(splitmode && !IsOper(source_p) && (*name != '&') && 
             ConfigChannel.no_join_on_split)
	  {
	    sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
                       me.name, source_p->name, name);
	    continue;
	  }

	  if (chptr->users == 0)
	    flags = CHFL_CHANOP;
	  else
	    flags = 0;
	}
      else
	{
	  if(splitmode && !IsOper(source_p) && (*name != '&') && 
            (ConfigChannel.no_create_on_split || ConfigChannel.no_join_on_split))
	  {
	    sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
	               me.name, source_p->name, name);
	    continue;
	  }
	  
	  flags = CHFL_CHANOP;
	}

      if ((source_p->user->joined >= ConfigChannel.max_chans_per_user) &&
         (!IsOper(source_p) || (source_p->user->joined >=
	                        ConfigChannel.max_chans_per_user*3)))
	{
	  sendto_one(source_p, form_str(ERR_TOOMANYCHANNELS),
		     me.name, parv[0], name);
	  if(successful_join_count)
	    source_p->localClient->last_join_time = CurrentTime;
	  return;
	}

      if(flags == 0)        /* if channel doesn't exist, don't penalize */
	successful_join_count++;

      if(chptr == NULL)     /* If I already have a chptr, no point doing this */
	{
	  chptr = get_or_create_channel(source_p, name, NULL);
	}
      
      if(chptr == NULL)
	{
	  sendto_one(source_p, form_str(ERR_UNAVAILRESOURCE),
		     me.name, parv[0], name);
	  if(successful_join_count > 0)
	    successful_join_count--;
	  continue;
	}

    if (!IsOper(source_p))
     check_spambot_warning(source_p, name);
      
      /* can_join checks for +i key, bans etc */
      if ( (i = can_join(source_p, chptr, key)) )
	{
	  sendto_one(source_p,
		     form_str(i), me.name, parv[0], name);
	  if(successful_join_count > 0)
	    successful_join_count--;
	  continue;
	}

      /* add the user to the channel */
      add_user_to_channel(chptr, source_p, flags);

      /* we send the user their join here, because we could have to
       * send a mode out next.
       */
      sendto_channel_local(ALL_MEMBERS, chptr, ":%s!%s@%s JOIN :%s",
			   source_p->name,
			   source_p->username,
			   source_p->host,
			   chptr->chname);

      /* if theyre joining opped (ie, new chan or joining one thats
       * persisting) then set timestamp to current, set +nt and
       * broadcast the sjoin with its old modes, or +nt.
       */
      if (flags & CHFL_CHANOP)
	{
          char mbuf[MODEBUFLEN];
          char pbuf[MODEBUFLEN];

	  chptr->channelts = CurrentTime;
          chptr->mode.mode |= MODE_TOPICLIMIT;
          chptr->mode.mode |= MODE_NOPRIVMSGS;

	  sendto_channel_local(ONLY_CHANOPS, chptr, ":%s MODE %s +nt",
			       me.name, chptr->chname);

          if(*chptr->chname == '#')
          {
            channel_modes(chptr, source_p, mbuf, pbuf);

            strlcat(mbuf, " ", sizeof(mbuf));

            if(pbuf[0] != '\0')
              strlcat(mbuf, pbuf, sizeof(mbuf));

            /* note: mbuf here will have a trailing space.  we add one above,
             * and channel_modes() will leave a trailing space on pbuf if
             * its used --fl
             */
	    sendto_server(client_p, chptr, NOCAPS, NOCAPS,
                          ":%s SJOIN %lu %s %s:@%s",
                          me.name, (unsigned long) chptr->channelts, 
                          chptr->chname, mbuf, parv[0]);
          }

          /* drop our +beI modes */
          free_channel_list(&chptr->banlist);
          free_channel_list(&chptr->exceptlist);
          free_channel_list(&chptr->invexlist);
	}
      else 
	{
	  sendto_server(client_p, chptr, NOCAPS, NOCAPS,
                        ":%s SJOIN %lu %s + :%s",
                        me.name, (unsigned long) chptr->channelts,
                        chptr->chname, parv[0]);
        }

      del_invite(chptr, source_p);
      
      if (chptr->topic != NULL)
	{
	  sendto_one(source_p, form_str(RPL_TOPIC), me.name,
		     parv[0], chptr->chname, chptr->topic);

          sendto_one(source_p, form_str(RPL_TOPICWHOTIME),
                     me.name, parv[0], chptr->chname,
                     chptr->topic_info,
                     chptr->topic_time);
	}

      channel_member_names(source_p, chptr, chptr->chname, 1);

      if(successful_join_count)
	source_p->localClient->last_join_time = CurrentTime;
    }
}