예제 #1
0
/* remove_unknown()
 *
 * inputs       -
 * output       -
 * side effects -
 */
static void
parse_remove_unknown(struct Client *client_p, const char *lsender, char *lbuffer)
{
  /*
   * Do kill if it came from a server because it means there is a ghost
   * user on the other server which needs to be removed. -avalon
   * Tell opers about this. -Taner
   */
  /*
   * '[0-9]something'  is an ID      (KILL/SQUIT depending on its length)
   * 'nodots'          is a nickname (KILL)
   * 'no.dot.at.start' is a server   (SQUIT)
   */
  if ((IsDigit(*lsender) && strlen(lsender) <= IRC_MAXSID) || strchr(lsender, '.'))
  {
    sendto_realops_flags(UMODE_DEBUG, L_ADMIN, SEND_NOTICE,
                         "Unknown prefix (%s) from %s, Squitting %s",
                         lbuffer, client_get_name(client_p, SHOW_IP), lsender);
    sendto_realops_flags(UMODE_DEBUG, L_OPER, SEND_NOTICE,
                         "Unknown prefix (%s) from %s, Squitting %s",
                         lbuffer, client_get_name(client_p, MASK_IP), lsender);
    sendto_one(client_p, ":%s SQUIT %s :(Unknown prefix (%s) from %s)",
               me.id, lsender, lbuffer, client_p->name);
  }
  else
    sendto_one(client_p, ":%s KILL %s :%s (Unknown Client)",
               me.id, lsender, me.name);
}
예제 #2
0
파일: event.c 프로젝트: n4cht/kwm
/** PropertyNotify handle event
 * \param ev XPropertyEvent pointer
*/
static void
propertynotify(XPropertyEvent *ev)
{
     Client *c;
     Systray *s;
     Window trans;
     XWMHints *h;

     if(ev->state == PropertyDelete)
          return;

     if((s = systray_find(ev->window)))
     {
          systray_state(s);
          systray_update();
     }

     if((c = client_gb_win(ev->window)))
     {
          switch(ev->atom)
          {
          case XA_WM_TRANSIENT_FOR:
               XGetTransientForHint(dpy, c->win, &trans);
               if((c->flags & TileFlag || c->flags & MaxFlag))
                    if(((c->flags & HintFlag && (client_gb_win(trans) != NULL)))
                              || (!(c->flags & HintFlag && (client_gb_win(trans) != NULL))))
                         arrange(c->screen, True);
               break;
          case XA_WM_NORMAL_HINTS:
               client_size_hints(c);
               break;
          case XA_WM_HINTS:
               if((h = XGetWMHints(dpy, c->win)) && (h->flags & XUrgencyHint) && c != sel)
               {
                    client_urgent(c, True);
                    XFree(h);
               }
               break;
          case XA_WM_NAME:
               client_get_name(c);
               break;
          default:
               if(ev->atom == net_atom[net_wm_name])
                    client_get_name(c);
               break;
          }
     }

     return;
}
예제 #3
0
파일: event.c 프로젝트: kidanger/wmfs
static void
event_propertynotify(XEvent *e)
{
     XPropertyEvent *ev = &e->xproperty;
     XWMHints *h;
     struct client *c;
     struct _systray *s;

     if(ev->state == PropertyDelete)
          return;

     if((c = client_gb_win(ev->window)))
     {
          switch(ev->atom)
          {
               case XA_WM_TRANSIENT_FOR:
                    break;

               case XA_WM_NORMAL_HINTS:
                    client_get_sizeh(c);
                    break;

               case XA_WM_HINTS:
                    if((h = XGetWMHints(EVDPY(e), c->win))
                       && (h->flags & XUrgencyHint)
                       && c->tag != W->screen->seltag)
                    {
                         c->tag->flags |= TAG_URGENT;
                         infobar_elem_screen_update(c->screen, ElemTag);
                         XFree(h);
                    }

                    break;

               default:
                    if(ev->atom == XA_WM_NAME || ev->atom == W->net_atom[net_wm_name])
                         client_get_name(c);
                    break;
          }
     }
     else if((s = systray_find(ev->window)))
     {
          systray_state(s);
          systray_update();
     }
}
예제 #4
0
/*
 * parse a buffer.
 *
 * NOTE: parse() should not be called recusively by any other functions!
 */
void
parse(struct Client *client_p, char *pbuffer, char *bufend)
{
  struct Client *from = client_p;
  struct Message *message = NULL;
  char *para[MAXPARA + 2];  /* <command> + <parameters> + NULL */
  char *ch = NULL;
  char *s = NULL;
  unsigned int numeric = 0;
  unsigned int parc = 0;
  unsigned int paramcount;

  if (IsDead(client_p))
    return;

  assert(client_p->connection);
  assert(client_p->connection->fd);
  assert(client_p->connection->fd->flags.open);


  assert((bufend - pbuffer) < IRCD_BUFSIZE);

  for (ch = pbuffer; *ch == ' '; ++ch)  /* Skip spaces */
    ;

  if (*ch == ':')
  {
    /*
     * Copy the prefix to 'sender' assuming it terminates
     * with SPACE (or NULL, which is an error, though).
     */
    const char *const sender = ++ch;

    if ((s = strchr(ch, ' ')))
    {
      *s = '\0';
      ch = ++s;
    }

    if (*sender && IsServer(client_p))
    {
      if ((from = hash_find_id(sender)) == NULL)
        from = hash_find_client(sender);

      /*
       * Hmm! If the client corresponding to the prefix is not found--what is
       * the correct action??? Now, I will ignore the message (old IRC just
       * let it through as if the prefix just wasn't there...) --msa
       */
      if (from == NULL)
      {
        ++ServerStats.is_unpf;
        parse_remove_unknown(client_p, sender, pbuffer);
        return;
      }

      if (from->from != client_p)
      {
        ++ServerStats.is_wrdi;
        sendto_realops_flags(UMODE_DEBUG, L_ADMIN, SEND_NOTICE,
                             "Fake direction: dropped message from %s[%s] via %s",
                             from->name, from->from->name,
                             client_get_name(client_p, SHOW_IP));
        sendto_realops_flags(UMODE_DEBUG, L_OPER, SEND_NOTICE,
                             "Fake direction: dropped message from %s[%s] via %s",
                             from->name, from->from->name,
                             client_get_name(client_p, MASK_IP));
        return;
      }
    }

    while (*ch == ' ')
      ++ch;
  }

  if (*ch == '\0')
  {
    ++ServerStats.is_empt;
    return;
  }

  /*
   * Extract the command code from the packet. Point s to the end
   * of the command code and calculate the length using pointer
   * arithmetic. Note: only need length for numerics and *all*
   * numerics must have parameters and thus a space after the command
   * code. -avalon
   */

  /* EOB is 3 characters long but is not a numeric */
  if (*(ch + 3) == ' ' &&  /* Ok, let's see if it's a possible numeric */
      IsDigit(*ch) && IsDigit(*(ch + 1)) && IsDigit(*(ch + 2)))
  {
    numeric = (*ch - '0') * 100 + (*(ch + 1) - '0') * 10 + (*(ch + 2) - '0');
    paramcount = 2;  /* Destination, and the rest of it */
    ++ServerStats.is_num;
    s = ch + 3;  /* I know this is ' ' from above if */
    *s++ = '\0';  /* Blow away the ' ', and point s to next part */
  }
  else
  {
    if ((s = strchr(ch, ' ')))
      *s++ = '\0';

    if ((message = find_command(ch)) == NULL)
    {
      /*
       * Note: Give error message *only* to recognized
       * persons. It's a nightmare situation to have
       * two programs sending "Unknown command"'s or
       * equivalent to each other at full blast....
       * If it has got to person state, it at least
       * seems to be well behaving. Perhaps this message
       * should never be generated, though...  --msa
       * Hm, when is the buffer empty -- if a command
       * code has been found ?? -Armin
       */
      if (*pbuffer)
        if (IsClient(from))
          sendto_one_numeric(from, &me, ERR_UNKNOWNCOMMAND, ch);

      ++ServerStats.is_unco;
      return;
    }

    assert(message->cmd);

    paramcount = message->args_max;

    size_t length = bufend - ((s) ? s : ch);
    message->bytes += length;
  }

  /*
   * Must the following loop really be so devious? On surface it
   * splits the message to parameters from blank spaces. But, if
   * paramcount has been reached, the rest of the message goes into
   * this last parameter (about same effect as ":" has...) --msa
   */

  /* Note initially true: s == NULL || *(s - 1) == '\0' !! */

  para[parc] = ch;

  if (message && (message->flags & MFLG_EXTRA))
  {
    /*
     * XXX: This will have to go away after the command handler rewrite
     */
    para[++parc] = message->extra;
  }

  if (s)
  {
    if (paramcount > MAXPARA)
      paramcount = MAXPARA;

    while (true)
    {
       while (*s == ' ')
         *s++ = '\0';

       if (*s == '\0')
         break;

       if (*s == ':')
       {
         /* The rest is single parameter--can include blanks also. */
         para[++parc] = s + (numeric == 0);  /* Keep the colon if it's a numeric */
         break;
       }

       para[++parc] = s;

       if (parc >= paramcount)
         break;

       while (*s && *s != ' ')
         ++s;
    }
  }

  para[++parc] = NULL;

  if (message)
    parse_handle_command(message, from, parc, para);
  else
    parse_handle_numeric(numeric, from, parc, para);
}