Пример #1
0
static inline int compareString(const char *a, const char *b, int blen, int flags) {
	const int start = flags & SDB_LIKE_START;
	const int end = flags & SDB_LIKE_END;
	char *aa = NULL;
	int alen, ret = 0;
	if (!a || !b || blen<0)
		return 0;
	if (flags & SDB_LIKE_BASE64) {
		aa = (char*)sdb_decode (a, &alen);
		if (!aa) return 0;
		a = (const char *)aa;
	} else {
		alen = strlen (a);
	}
	if (blen <= alen) {
		if (flags & SDB_LIKE_ICASE) {
			if (start && end) ret = (alen==blen && !mycmp (a, b, blen, 0));
			else if (start) ret = !mycmp (a, b, blen, 0);
			else if (end) ret = !mycmp (a+(alen-blen), b, blen, 0);
			else ret = !mycmp (a, b, blen, 1);
		} else {
			if (start && end) ret = (alen==blen && !strncmp (a, b, blen));
			else if (start) ret = !strncmp (a, b, blen);
			else if (end) ret = !strncmp (a+(alen-blen), b, blen);
			else ret = strstr2 (a, b, blen);
		}
	}
	free (aa);
	return ret;
}
Пример #2
0
int add_listmode(Ban **list, aClient *cptr, aChannel *chptr, char *banid)
{
	Ban *ban;
	int cnt = 0, len;

	if (MyClient(cptr))
		(void)collapse(banid);
	
	len = strlen(banid);
	if (!*list && ((len > MAXBANLENGTH) || (MAXBANS < 1)))
	{
		sendto_one(cptr, err_str(ERR_BANLISTFULL),
			me.name, cptr->name, chptr->chname, banid);
		return -1;
	}
	for (ban = *list; ban; ban = ban->next)
	{
		len += strlen(ban->banstr);
		if (MyClient(cptr))
			if ((len > MAXBANLENGTH) || (++cnt >= MAXBANS))
			{
				sendto_one(cptr, err_str(ERR_BANLISTFULL),
				    me.name, cptr->name, chptr->chname, banid);
				return -1;
			}
			else
			{
#ifdef SOCALLEDSMARTBANNING
			  /* Temp workaround added in b19. -- Syzop */
			  if (!mycmp(ban->banstr, banid) || (!strchr(banid, '\\') && !strchr(ban->banstr, '\\')))
				if (!match(ban->banstr, banid))
					return -1;
#endif
			  if (!mycmp(ban->banstr, banid))
			  	return -1;
			}
		else if (!mycmp(ban->banstr, banid))
			return -1;

	}
	ban = make_ban();
	bzero((char *)ban, sizeof(Ban));
	ban->next = *list;
	ban->banstr = (char *)MyMalloc(strlen(banid) + 1);
	(void)strcpy(ban->banstr, banid);
	ban->who = (char *)MyMalloc(strlen(cptr->name) + 1);
	(void)strcpy(ban->who, cptr->name);
	ban->when = TStime();
	*list = ban;
	return 0;
}
Пример #3
0
/*
** find_history
**      Returns 1 if a user was using the given nickname within
**   the timelimit and it's locked. Returns 0, if none found...
*/
int	find_history(char *nick, time_t timelimit)
{
	Reg     aName   *wp, *wp2;
	Reg	aLock	*lp, *lp2;
	
	wp = wp2 = &was[ww_index];
#ifdef RANDOM_NDELAY	
	timelimit = timeofday - timelimit - (lk_index % 60);
#else
	timelimit = timeofday - timelimit;
#endif
	
	do
	{
		if (wp == was)
		{
			wp = was + ww_size;
		}
		wp--;
		if (wp->ww_logout < timelimit)
		{
			return 0;
		}
		/* wp->ww_online == NULL means it's locked */
		if ((!wp->ww_online) && (!mycmp(nick, wp->ww_nick)))
		{
			return 1;
		}
	} while (wp != wp2);

	lp = lp2 = &locked[lk_index];
	do
	{
		if (lp == locked)
		{
			lp = locked + lk_size;
		}
		lp--;
		if (lp->logout < timelimit)
		{
			return 0;
		}
		if (!mycmp(nick, lp->nick))
		{
			return 1;
		}
	} while (lp != lp2);

	return (0);
}
Пример #4
0
/*
 * this takes a server name, and returns a pointer to the same string
 * (up to case) in the server name token list, adding it to the list if
 * it's not there.  care must be taken not to call this with
 * user-supplied arguments that haven't been verified to be a valid,
 * existing, servername.  use the hash in list.c for those.  -orabidoo
 */
char *find_or_add(char *name)
{
    int         hash_index;
    SCACHE     *ptr, *newptr;

    ptr = scache_hash[hash_index = hash(name)];
    while (ptr) 
    {
	if (!mycmp(ptr->name, name))
	    return (ptr->name);
	else
	    ptr = ptr->next;
    }

    /* not found -- add it */
    if ((ptr = scache_hash[hash_index])) 
    {
	newptr = scache_hash[hash_index] = (SCACHE *) MyMalloc(sizeof(SCACHE));
	strncpyzt(newptr->name, name, HOSTLEN);
	newptr->next = ptr;
	return (newptr->name);
    }
    else
    {
	ptr = scache_hash[hash_index] = (SCACHE *) MyMalloc(sizeof(SCACHE));
	strncpyzt(ptr->name, name, HOSTLEN);
	ptr->next = (SCACHE *) NULL;
	return (ptr->name);
    }
}
Пример #5
0
/*
** get_history
**      Return the current client that was using the given
**      nickname within the timelimit. Returns NULL, if no
**      one found...
*/
aClient	*get_history(char *nick, time_t timelimit)
{
	Reg	aName	*wp, *wp2;

	wp = wp2 = &was[ww_index];
	timelimit = timeofday - timelimit;

	do
	{
		if (wp == was)
		{
			wp = was + ww_size;
		}
		wp--;
		if (wp->ww_logout < timelimit)
		{
			/* no point in checking more, only old or unused 
			 * entry's left. */
			return NULL;
		}
		if (wp->ww_online == &me)
		{
			/* This one is offline */
			continue;
		}
		if (wp->ww_online && !mycmp(nick, wp->ww_nick))
		{
			return wp->ww_online;
		}
	} while (wp != wp2);

	return (NULL);
}
Пример #6
0
int main(int argc, char* argv[])
{
    char** data = NULL;
    char* buf;
    int strcnt = 0;
    size_t strsize = 10;
    int i, j;
    FILE* inf;
    FILE* outf;
    int ret = 0;
    if (argc < 3)
    {
        printf("Few args");
        return 0;
    }
    inf = fopen(argv[1], "r");
    outf = fopen(argv[2], "w");
    if (outf == NULL || inf == NULL)
    {
        printf("Invalid file names");
        return 0;
    }
    data = malloc(10 * sizeof(char*));
    data[strcnt] = NULL;
    ret = safe_gets(inf, &data[strcnt]);
    while (ret == 0)
    {
        strcnt++;
        if (strcnt + 1 == strsize)
        {   
            strsize += 10;
            data = realloc(data, strsize * sizeof(char*));
            if (data == NULL)
            printf("whats up?");
        }
        /*printf("%s", data[strcnt - 1]);*/
        data[strcnt] = NULL;
        ret = safe_gets(inf, &data[strcnt]);
        
    }
    
    for (i = 0; i < strcnt; ++i)
        for (j = i + 1; j < strcnt; ++j)
        if (mycmp(data[i], data[j]) >= 0) {
            buf = data[j];
            data[j] = data[i];
            data[i] = buf;
        }
    printf("Words: %ld\n", words);
    for (i = 0; i < strcnt; ++i){
        myputs(outf, data[i]);
        free(data[i]);
    } 
    free(data[i]);   
    free(data);
    fclose(inf);
    fclose(outf);    
    return 0;    
}
Пример #7
0
/**
 * Returns first PRL entry for given IPv6 address
 **/
struct PRLENTRY* find_internal_pdr_by_addr6(struct in6_addr *addr) {
    struct PRLENTRY* cur = prl_head;
    while (cur) {
        if (mycmp(&cur->addr6.sin6_addr, addr, sizeof(struct in6_addr)) == 0)
            return cur;
        cur = cur->next;
    }
    return NULL;
}
Пример #8
0
/*
 * * get_client_name *      Return the name of the client for various
 * tracking and *      admin purposes. The main purpose of this
 * function is to *      return the "socket host" name of the client,
 * if that *    differs from the advertised name (other than case). *
 * But, this can be used to any client structure. *
 * 
 *      Returns: *        "name[user@ip#.port]" if 'showip' is true; *
 * "name[sockethost]", if name and sockhost are different and *
 * showip is false; else *        "name". *
 * 
 * NOTE 1: *    Watch out the allocation of "nbuf", if either
 * sptr->name * or sptr->sockhost gets changed into pointers instead of *
 * directly allocated within the structure... *
 * 
 * NOTE 2: *    Function return either a pointer to the structure
 * (sptr) or *  to internal buffer (nbuf). *NEVER* use the returned
 * pointer *    to modify what it points!!!
 */
char       *
get_client_name(aClient *sptr, int showip)
{
   static char nbuf[HOSTLEN * 2 + USERLEN + 5];

   if (MyConnect(sptr)) {
      switch (showip) {
	 case TRUE:
#ifdef SHOW_UH
	    (void) ircsprintf(nbuf, "%s[%s%s@%s]",
			      sptr->name,
			      (!(sptr->flags & FLAGS_GOTID)) ? "" :
			      "(+)",
			      sptr->user ? sptr->user->username :
			      sptr->username,
			      inetntoa((char *) &sptr->ip));
#else
	    (void) sprintf(nbuf, "%s[%s@%s]",
			   sptr->name,
			   (!(sptr->flags & FLAGS_GOTID)) ? "" :
			   sptr->username,
			   inetntoa((char *) &sptr->ip));
#endif
	    break;
	 case HIDEME:
#ifdef SHOW_UH
	    (void) ircsprintf(nbuf, "%s[%s%s@%s]",
			      sptr->name,
			      (!(sptr->flags & FLAGS_GOTID)) ? "" :
			      "(+)",
			      sptr->user ? sptr->user->username :
			      sptr->username,
			      "0.0.0.0");
#else
	    (void) sprintf(nbuf, "%s[%s@%s]",
			   sptr->name,
			   (!(sptr->flags & FLAGS_GOTID)) ? "" :
			   sptr->username,
			   "0.0.0.0");
#endif
	    break;
	 default:
	    if (mycmp(sptr->name, sptr->sockhost))
#ifdef USERNAMES_IN_TRACE
	       (void) ircsprintf(nbuf, "%s[%s@%s]",
				 sptr->name,
				 sptr->user ? sptr->user->username :
				 sptr->username, sptr->sockhost);
#else
	       (void) ircsprintf(nbuf, "%s[%s]",
				 sptr->name, sptr->sockhost);
#endif
	    else
	       return sptr->name;
      }
      return nbuf;
   }
Пример #9
0
/*
** m_whowas
**      parv[0] = sender prefix
**      parv[1] = nickname queried
*/
DLLFUNC CMD_FUNC(m_whowas)
{
	aWhowas *temp;
	int  cur = 0;
	int  max = -1, found = 0;
	char *p, *nick;

	if (parc < 2)
	{
		sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
		    me.name, parv[0]);
		return 0;
	}
	if (parc > 2)
		max = atoi(parv[2]);
	if (parc > 3)
		if (hunt_server_token(cptr, sptr, MSG_WHOWAS, TOK_WHOWAS, "%s %s :%s", 3, parc,
		    parv))
			return 0;

	if (!MyConnect(sptr) && (max > 20))
		max = 20;

	p = (char *)strchr(parv[1], ',');
	if (p)
		*p = '\0';
	nick = parv[1];
	temp = WHOWASHASH[hash_whowas_name(nick)];
	found = 0;
	for (; temp; temp = temp->next)
	{
		if (!mycmp(nick, temp->name))
		{
			sendto_one(sptr, rpl_str(RPL_WHOWASUSER),
			    me.name, parv[0], temp->name,
			    temp->username,
			    (IsOper(sptr) ? temp->hostname :
			    (*temp->virthost !=
			    '\0') ? temp->virthost : temp->hostname),
			    temp->realname);
                	if (!((Find_uline(temp->servername)) && !IsOper(sptr) && HIDE_ULINES))
				sendto_one(sptr, rpl_str(RPL_WHOISSERVER), me.name,
				    parv[0], temp->name, temp->servername,
				    myctime(temp->logoff));
			cur++;
			found++;
		}
		if (max > 0 && cur >= max)
			break;
	}
	if (!found)
		sendto_one(sptr, err_str(ERR_WASNOSUCHNICK),
		    me.name, parv[0], nick);

	sendto_one(sptr, rpl_str(RPL_ENDOFWHOWAS), me.name, parv[0], parv[1]);
	return 0;
}
Пример #10
0
af::shared<int>
di::SpotFilterAgent::resolution_sort_nztt(spot_list_t masterlist,
                                     af::shared<int> parentselection){
  cmp mycmp(masterlist);
  //sort according to resolution
  af::shared<int> to_be_sorted = parentselection.deep_copy();
  std::sort<PtrTyp,cmp>(to_be_sorted.begin(),to_be_sorted.end(),mycmp);
  return to_be_sorted;
}
Пример #11
0
af::shared<int>
di::SpotFilterAgent::order_by(spot_list_t masterlist,
                              af::shared<int> parentselection,
                              std::string criterion){
  //first implementation, criterion is always intensity
  cmp_to_be_generalized mycmp(masterlist);
  //sort according to resolution
  af::shared<int> to_be_sorted = parentselection.deep_copy();
  std::sort<PtrTyp,cmp_to_be_generalized>(to_be_sorted.begin(),to_be_sorted.end(),mycmp);
  return to_be_sorted;
}
Пример #12
0
/*
** m_pong
**	parv[0] = sender prefix
**	parv[1] = origin
**	parv[2] = destination
*/
DLLFUNC int m_pong(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient *acptr;
	char *origin, *destination;

#ifdef NOSPOOF
	if (!IsRegistered(cptr))
		return m_nospoof(cptr, sptr, parc, parv);
#endif

	if (parc < 2 || *parv[1] == '\0')
	{
		sendto_one(sptr, err_str(ERR_NOORIGIN), me.name, parv[0]);
		return 0;
	}

	origin = parv[1];
	destination = parv[2];
	cptr->flags &= ~FLAGS_PINGSENT;
	sptr->flags &= ~FLAGS_PINGSENT;

	/* Remote pongs for clients? uhh... */
	if (MyClient(sptr) || !IsRegistered(sptr))
		destination = NULL;

	if (!BadPtr(destination) && mycmp(destination, me.name) != 0)
	{
		if ((acptr = find_client(destination, NULL)) ||
		    (acptr = find_server_quick(destination)))
		{
			if (!IsServer(cptr) && !IsServer(acptr))
			{
				sendto_one(sptr, err_str(ERR_NOSUCHSERVER),
				    me.name, parv[0], destination);
				return 0;
			}
			else
				sendto_one(acptr, ":%s PONG %s %s",
				    parv[0], origin, destination);
		}
		else
		{
			sendto_one(sptr, err_str(ERR_NOSUCHSERVER),
			    me.name, parv[0], destination);
			return 0;
		}
	}
#ifdef	DEBUGMODE
	else
		Debug((DEBUG_NOTICE, "PONG: %s %s", origin,
		    destination ? destination : "*"));
#endif
	return 0;
}
Пример #13
0
char	*get_client_name(aClient *sptr, int showip)
{
	static char nbuf[HOSTLEN * 2 + USERLEN + 5];

	if (MyConnect(sptr))
	    {
#ifdef UNIXPORT
		if (IsUnixSocket(sptr))
		    {
			if (showip)
				sprintf(nbuf, "%s[%s]",
					sptr->name, sptr->sockhost);
			else
				sprintf(nbuf, "%s[%s]",
					sptr->name, me.sockhost);
		    }
		else
#endif
		    {
			if (showip)
				(void)sprintf(nbuf, "%s[%.*s@%s]",
					sptr->name, USERLEN,
					(!(sptr->flags & FLAGS_GOTID)) ? "" :
					sptr->auth, sptr->user ? sptr->user->sip :
#ifdef INET6 
					      inetntop(AF_INET6,
						       (char *)&sptr->ip,
						       ipv6string, sizeof(ipv6string))
#else
					      inetntoa((char *)&sptr->ip)
#endif
					);
			else
			    {
				if (mycmp(sptr->name, sptr->sockhost))
					/* Show username for clients and
					 * ident for others.
					 */
					sprintf(nbuf, "%s[%.*s@%s]",
						sptr->name, USERLEN,
						IsPerson(sptr) ?
							sptr->user->username :
							sptr->auth,
						IsPerson(sptr) ? sptr->user->host :
						sptr->sockhost);
				else
					return sptr->name;
			    }
		    }
		return nbuf;
	    }
	return sptr->name;
}
Пример #14
0
af::shared<int>
di::SpotFilterAgent::resolution_sort(spot_list_t masterlist,
                                     af::shared<int> parentselection){
  //First update the w_spot array with calculated resolutions.
  for (spot_list_t::iterator spotptr = masterlist.begin();
       spotptr != masterlist.end(); ++spotptr) {
       double spotradius = radius(*spotptr,this);
       double theta = std::atan2(spotradius,distance)/2.0;
       spotptr->resolution = wavelength/(2.0 * std::sin(theta));
  }
  cmp mycmp(masterlist);
  //sort according to resolution
  af::shared<int> to_be_sorted = parentselection.deep_copy();
  std::sort<PtrTyp,cmp>(to_be_sorted.begin(),to_be_sorted.end(),mycmp);
  return to_be_sorted;
}
Пример #15
0
int main()
{
	int t, i, p, best, len;
	scanf("%d", &t);
	while(t--)
	{
		best = 0;
		scanf("%s", str);
		len = strlen(str);
		for(i=1; i<len; i++)
		{
			p = mycmp(best, i, len);
			if(p > 0) best = i;
		}
		printf("%d\n", best+1);
	}
	return 0;
}
Пример #16
0
/*
** m_ping
**	parv[0] = sender prefix
**	parv[1] = origin
**	parv[2] = destination
*/
DLLFUNC int  m_ping(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	aClient *acptr;
	char *origin, *destination;

	if (parc < 2 || *parv[1] == '\0')
	{
		sendto_one(sptr, err_str(ERR_NOORIGIN), me.name, parv[0]);
		return 0;
	}
	origin = parv[1];
	destination = parv[2];	/* Will get NULL or pointer (parc >= 2!!) */

	if (!MyClient(sptr))
	{
		/* I've no idea who invented this or what it is supposed to do.. */
		acptr = find_client(origin, NULL);
		if (!acptr)
			acptr = find_server_quick(origin);
		if (acptr && acptr != sptr)
			origin = cptr->name;
	}

	if (!BadPtr(destination) && mycmp(destination, me.name) != 0)
	{
		if (MyClient(sptr))
			origin = sptr->name; /* Make sure origin is not spoofed */
		if ((acptr = find_server_quick(destination)) && (acptr != &me))
			sendto_one(acptr, ":%s PING %s :%s", parv[0], origin, destination);
		else
		{
			sendto_one(sptr, err_str(ERR_NOSUCHSERVER),
			    me.name, parv[0], destination);
			return 0;
		}
	}
	else
		sendto_one(sptr, ":%s %s %s :%s", me.name,
		    IsToken(cptr) ? TOK_PONG : MSG_PONG,
		    (destination) ? destination : me.name, origin);
	return 0;
}
Пример #17
0
/*
 * del_listmode - delete a listmode (+beI) from a channel
 *                that matches the specified banid.
 */
int del_listmode(Ban **list, aChannel *chptr, char *banid)
{
	Ban **ban;
	Ban *tmp;

	if (!banid)
		return -1;
	for (ban = list; *ban; ban = &((*ban)->next))
	{
		if (mycmp(banid, (*ban)->banstr) == 0)
		{
			tmp = *ban;
			*ban = tmp->next;
			MyFree(tmp->banstr);
			MyFree(tmp->who);
			free_ban(tmp);
			return 0;
		}
	}
	return -1;
}
Пример #18
0
Файл: send.c Проект: ahf/irc
/*
 * sendpreprep: takes care of building the string according to format & args,
 *		and of adding a complete prefix if necessary
 */
static	int	vsendpreprep(aClient *to, aClient *from, char *pattern, va_list va)
{
	int	len;

	Debug((DEBUG_L10, "sendpreprep(%#x(%s),%#x(%s),%s)",
		to, to->name, from, from->name, pattern));
	if (to && from && MyClient(to) && IsPerson(from) &&
	    !strncmp(pattern, ":%s", 3))
	{
		char	*par = va_arg(va, char *);

		if (from == &anon || !mycmp(par, from->name))
		{
			len = sprintf(psendbuf, ":%s!%s@%s", from->name,
				from->user->username, from->user->host);
		}
		else
		{
			len = sprintf(psendbuf, ":%s", par);
		}

		len += vsprintf(psendbuf+len, pattern+3, va);
	}
Пример #19
0
int callback(struct CB* pcb, PTSTR path)
{
	int len = lstrlen(path);
	while(len>=0 && path[len-1] != '.') --len;
	if (!pcb->filter || !mycmp(&path[len], pcb->filter))
	{
		while (pcb->ptp[pcb->cnt].front == pcb->ptp[pcb->cnt].tail+1)		// 队列满,转下一个
			pcb->cnt = (pcb->cnt+1)%4;

		EnterCriticalSection(&cs);
		{
			lstrcpy((PTSTR)((PBYTE)*pcb->ptp[pcb->cnt].queue + pcb->ptp[pcb->cnt].tail*MAX_PATH), path);
		
			if (pcb->ptp[pcb->cnt].tail == pcb->ptp[pcb->cnt].front)		// 原先队列为空,置位
				SetEvent(pcb->ptp[pcb->cnt].hEvent);

			pcb->ptp[pcb->cnt].tail = (pcb->ptp[pcb->cnt].tail + 1) % pcb->ptp[pcb->cnt].QUEUE_SIZE;// 更新队列
		}
		LeaveCriticalSection(&cs);

		pcb->cnt = (pcb->cnt+1)%4;	// 转下一个线程
	}
	return 0;
}
Пример #20
0
/*
** m_whowas
**	parv[0] = sender prefix
**	parv[1] = nickname queried
*/
int	m_whowas(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
	Reg	aName	*wp, *wp2 = NULL;
	Reg	int	j = 0;
	Reg	anUser	*up = NULL;
	int	max = -1;
	char	*p = NULL, *nick, *s;

 	if (parc < 2)
	    {
		sendto_one(sptr, replies[ERR_NONICKNAMEGIVEN], ME, BadTo(parv[0]));
		return 1;
	    }
	if (parc > 2)
		max = atoi(parv[2]);
	if (parc > 3)
		if (hunt_server(cptr,sptr,":%s WHOWAS %s %s :%s", 3,parc,parv))
			return 3;

	parv[1] = canonize(parv[1]);
	if (!MyConnect(sptr))
		max = MIN(max, 20);

	for (s = parv[1]; (nick = strtoken(&p, s, ",")); s = NULL)
	    {
		wp = wp2 = &was[(ww_index ? ww_index : ww_size) - 1];
		j = 0;

		do {
			if (mycmp(nick, wp->ww_nick) == 0)
			    {
				up = wp->ww_user;
				sendto_one(sptr, replies[RPL_WHOWASUSER],
					   ME, BadTo(parv[0]), wp->ww_nick, up->username,
					   up->host, wp->ww_info);
				sendto_one(sptr, replies[RPL_WHOISSERVER],
					   ME, BadTo(parv[0]), wp->ww_nick, up->server,
					   myctime(wp->ww_logout));
				j++;
			    }
			if (max > 0 && j >= max)
				break;
			if (wp == was)
				wp = &was[ww_size - 1];
			else
				wp--;
		} while (wp != wp2);

		if (up == NULL)
		    {
			if (strlen(nick) > (size_t) NICKLEN)
				nick[NICKLEN] = '\0';
			sendto_one(sptr, replies[ERR_WASNOSUCHNICK], ME, BadTo(parv[0]),
				   nick);
		    }
		else
			up = NULL;

		if (p)
			p[-1] = ',';
	    }
	sendto_one(sptr, replies[RPL_ENDOFWHOWAS], ME, BadTo(parv[0]), parv[1]);
	return 2;
    }
Пример #21
0
int main(int argc,char *argv[])
{
    int c;
    int nlines=readlines(lineptr,MAXLINES);
    int result;
    if(argc>1&&strcmp(argv[1],"-d")==0)
    {
        if(nlines>=0)
        {
            //不加这个只输入一行且有标点时无法报错
            if(nlines==1)
            {
                if(mycmp(lineptr[0],lineptr[0])==-1)
                {
                    return 0;
                }
            }
            result=maopao(lineptr,nlines,(int (*)(void *,void *))mycmp);
            if(result==-1)
            {
                return 0;
            }else{
                writelines(lineptr,nlines);
            }
            return 0;
        }
    }
    if(argc>1&&strcmp(argv[1],"-f")==0)
    {
        if(nlines>=0)
        {
            maopao(lineptr,nlines,(int (*)(void *,void *))mystrcmp);
            writelines(lineptr,nlines);
            return 0;
        }
    } 
    if(argc==3||(argc==2&&(strcmp(argv[1],"-df")==0||strcmp(argv[1],"-fd")==0)))
    {
        int i;
        for(i=0;i<nlines;i++)
        {
            if(mycmp(lineptr[i],lineptr[i])==-1)
                return 0;
        }
        if(nlines>=0)
        {
            maopao(lineptr,nlines,(int (*)(void *,void *))mystrcmp);
            writelines(lineptr,nlines);
            return 0;
        }
    }

    if(nlines>=0)
    {
        maopao(lineptr,nlines,(int (*)(void *,void *))strcmp);
        writelines(lineptr,nlines);
        return 0;
    }else{
        printf("input too big to sort\n");
        return 1;
    }
}
Пример #22
0
int main() {
  char a[128] = "These";
  char b[128] = "are";
  char c[128] = "the";
  char d[128] = "test";
  char e[128] = "cases";
  char f[128] = "car";
  char g[128] = "aren";
  char h[128] = "abcdefghijklmnopqrstuvwxyzzzzzzzzzzzz";
  char i[128] = "cases";
  char j[128] = "casesss";
  char k[128] = "arent";
  char l[128] = "longwords";
  char m[128] = "neededlongwords";
  char n[128] = "lastlongwordormaybenot";

  char s[128];
  char t[128];
  char u[128];

  char v[128];
  char w[128];

  char x[128];
  char y[128];
  char z[128];
  
  printf("---mylen Testing---\n");
  printf("Test One:\n These - - - Length: 5\n Run: %d\n", mylen(a));
  printf("Test Two:\n are - - - Length: 3\n Run: %d\n", mylen(b));
  printf("Test Three:\n abcdefghijklmnopqrstuvwxyz - - - Length: 26\n Run: %d\n", mylen(h));
  printf("\n");

  printf("---mycmp Testing---\n");
  printf("Test One:\n Word 1: cases - Word 2: car\n Run: %d\n", mycmp(e, f));
  printf("Test Two:\n Word 1: cases - Word 2: cases\n Run: %d\n", mycmp(e, i));
  printf("Test Three:\n Word 1: are - Word 2: the\n Run: %d\n", mycmp(b, c));
  printf("Test Four:\n Word 1: casesss - Word 2: cases\n Run: %d\n", mycmp(j, e));
  printf("Test Five:\n Word 1: aren - Word 2: arent\n Run: %d\n", mycmp(g, k));
  printf("\n");

  printf("---mycpy Testing---\n");
  printf("Before Copying:\n");
  printf(" x: %s\n y: %s\n z: %s\n", x, y, z);
  printf("Copying:\n %s --> x\n %s --> y\n %s --> z\n", h, i, j);
  mycpy(x, h);
  mycpy(y, i);
  mycpy(z, j);
  printf("After Copying:\n");
  printf(" x: %s\n y: %s\n z: %s\n", x, y, z);
  printf("\n");

  printf("---mycpyn Testing---\n");
  printf("Before Copying:\n");
  printf(" s: %s\n t: %s\n u: %s\n", s, t, u);
  printf("Copying:\n %s - 6 --> s\n %s - 7 --> t\n %s - 10 --> u\n", l, m, n);
  mycpyn(s, l, 6);
  mycpyn(t, m, 7);
  mycpyn(u, n, 10);
  printf("After Copying:\n");
  printf(" s: %s\n t: %s\n u: %s\n", s, t, u);
  printf("\n");

  printf("---mycat Testing---\n"); 
  printf("Before Catting:\n");
  printf(" s: %s\n m: %s\n h: %s\n", s, m, h);
  printf("Catting:\n %s --> s\n %s --> m\n %s --> h\n", h, c, d);
  mycat(s, h);
  mycat(m, c);
  mycat(h, d);
  printf("After Catting:\n");
  printf(" s: %s\n m: %s\n h: %s\n", s, m, h);
  printf("\n");

  printf("---mycatn Testing---\n"); 
  printf("Before Catting:\n");
  printf(" s: %s\n m: %s\n h: %s\n", s, m, h);
  printf("Catting:\n %s - 8 --> s\n %s - 3 --> m\n %s - 2 --> h\n", h, c, d);
  mycatn(s, h, 8);
  mycatn(m, c, 3);
  mycatn(h, d, 2);
  printf("After Catting:\n");
  printf(" s: %s\n m: %s\n h: %s\n", s, m, h);
  printf("\n");
  
  printf("---mychr Testing---\n");
  printf("Test One:\n Searching in: %s\n Searching for: %c\n", e, 'e');
  printf(" Pointer: %p - Points at: %c\n", mychr(e,'e'), *mychr(e,'e'));
  printf("Test Two:\n Searching in: %s\n Searching for: %c\n", h, 't');
  printf(" Pointer: %p - Points at: %c\n", mychr(h,'t'), *mychr(h,'t'));
  printf("\n");

  printf("---mystr Testing---\n");
  printf("Test One:\n Searching in: %s\n Searching for: %s\n", n, "long");
  printf(" Pointer: %p - Points at: %s\n", mystr(n,"long"), *mystr(n,"long"));
  
  return 0;
}
Пример #23
0
/*
 * m_nick 
 * parv[0] = sender prefix 
 * parv[1] = nickname 
 * parv[2] = hopcount when new user; TS when nick change 
 * parv[3] = TS
 * ---- new user only below ---- 
 * parv[4] = umode 
 * parv[5] = username 
 * parv[6] = hostname 
 * parv[7] = server 
 * parv[8] = serviceid
 * parv[9] = IP
 * parv[10] = ircname
 * -- endif
 */
int m_nick(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    struct simBan *ban;
    aClient    *acptr, *uplink;
    Link       *lp, *lp2;
    char        nick[NICKLEN + 2];
    ts_val      newts = 0;
    int         sameuser = 0, samenick = 0;
  
    if (parc < 2)
    {
	sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
		   me.name, parv[0]);
	return 0;
    }
  
    if (!IsServer(sptr) && IsServer(cptr) && parc > 2)
	newts = atol(parv[2]);
    else if (IsServer(sptr) && parc > 3)
	newts = atol(parv[3]);
    else
	parc = 2;
    /*
     * parc == 2 on a normal client sign on (local) and a normal client 
     * nick change 
     * parc == 4 on a normal server-to-server client nick change
     * parc == 11 on a normal TS style server-to-server NICK introduction
     */
    if ((IsServer(sptr) || (parc > 4)) && (parc < 11))
    {
	/*
	 * We got the wrong number of params. Someone is trying to trick
	 * us. Kill it. -ThemBones As discussed with ThemBones, not much
	 * point to this code now sending a whack of global kills would
	 * also be more annoying then its worth, just note the problem,
	 * and continue -Dianora
	 */
	sendto_realops("IGNORING BAD NICK: %s[%s@%s] on %s (from %s)", parv[1],
		       (parc >= 6) ? parv[5] : "-",
		       (parc >= 7) ? parv[6] : "-",
		       (parc >= 8) ? parv[7] : "-", parv[0]);
	return 0;
     
    }
   
    strncpyzt(nick, parv[1], NICKLEN + 1);
    /*
     * if do_nick_name() returns a null name OR if the server sent a
     * nick name and do_nick_name() changed it in some way (due to rules
     * of nick creation) then reject it. If from a server and we reject
     * it, and KILL it. -avalon 4/4/92
     */
    if (do_nick_name(nick) == 0 || (IsServer(cptr) && strcmp(nick, parv[1])))
    {
	sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),
		   me.name, parv[0], parv[1], "Erroneous Nickname");
	
	if (IsServer(cptr))
	{
	    ircstp->is_kill++;
        sendto_realops_lev(DEBUG_LEV, "Bad Nick: %s From: %s Via: %s",
			       parv[1], parv[0],
			       get_client_name(cptr, HIDEME));
	    sendto_one(cptr, ":%s KILL %s :%s (Bad Nick)",
		       me.name, parv[1], me.name);
	    if (sptr != cptr) { /* bad nick change */     
		sendto_serv_butone(cptr, ":%s KILL %s :%s (Bad Nick)", me.name,
				   parv[0], me.name);
		sptr->flags |= FLAGS_KILLED;
		return exit_client(cptr, sptr, &me, "BadNick");
	    }
	}
	return 0;
    }
    /*
     * Check against nick name collisions.
     * 
     * Put this 'if' here so that the nesting goes nicely on the screen
     * :) We check against server name list before determining if the
     * nickname is present in the nicklist (due to the way the below
     * for loop is constructed). -avalon
     */
    do
    {
	if ((acptr = find_server(nick, NULL)))
	    if (MyConnect(sptr))
	    {
		sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name,
			   BadPtr(parv[0]) ? "*" : parv[0], nick);
		return 0;
	    }
	
	/* 
	 * acptr already has result from find_server
	 * Well. unless we have a capricious server on the net, a nick can
	 * never be the same as a server name - Dianora
	 * That's not the only case; maybe someone broke do_nick_name
	 * or changed it so they could use "." in nicks on their network 
	 * - sedition
	 */
     
	if (acptr)
	{
	    /*
	     * We have a nickname trying to use the same name as a
	     * server. Send out a nick collision KILL to remove the
	     * nickname. As long as only a KILL is sent out, there is no
	     * danger of the server being disconnected.  Ultimate way to
	     * jupiter a nick ? >;-). -avalon
	     */
	    sendto_realops_lev(SKILL_LEV, "Nick collision on %s", sptr->name);
	    ircstp->is_kill++;
	    sendto_one(cptr, ":%s KILL %s :%s (Nick Collision)", me.name, 
		       sptr->name, me.name);
	    sptr->flags |= FLAGS_KILLED;
	    return exit_client(cptr, sptr, &me, "Nick/Server collision");
	}
	
	if (!(acptr = find_client(nick, NULL)))
	    break;
     
	/*
	 * If acptr == sptr, then we have a client doing a nick change
	 * between *equivalent* nicknames as far as server is concerned
	 * (user is changing the case of his/her nickname or somesuch)
	 */
	if (acptr == sptr)
	{
	    if (strcmp(acptr->name, nick) == 0) 
		return 0;
	    else
		break;
	} /* If user is changing nick to itself no point in propogating */
     
	/*
	 * Note: From this point forward it can be assumed that acptr !=
	 * sptr (point to different client structures).
	 *
	 * If the older one is "non-person", the new entry is just 
	 * allowed to overwrite it. Just silently drop non-person, and
	 * proceed with the nick. This should take care of the "dormant
	 * nick" way of generating collisions...
	 */
	if (IsUnknown(acptr))
	{
	    if (MyConnect(acptr))
	    {
		exit_client(NULL, acptr, &me, "Overridden");
		break;
	    }
	    else if (!(acptr->user))
	    {
		sendto_realops_lev(SKILL_LEV, "Nick Collision on %s", parv[1]);
		sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",
				   me.name, acptr->name, me.name);
		acptr->flags |= FLAGS_KILLED;
		/* Having no USER struct should be ok... */
		return exit_client(cptr, acptr, &me,
				   "Got TS NICK before Non-TS USER");
	    }
	}
     
	if (!IsServer(cptr))
	{
	    /*
	     * NICK is coming from local client connection. Just send
	     * error reply and ignore the command.
	     * parv[0] is empty on connecting clients
	     */
	    sendto_one(sptr, err_str(ERR_NICKNAMEINUSE),
		       me.name, BadPtr(parv[0]) ? "*" : parv[0], nick);
	    return 0;
	}
	/*
	 * NICK was coming from a server connection. Means that the same
	 * nick is registered for different users by different server.
	 * This is either a race condition (two users coming online about
	 * same time, or net reconnecting) or just two net fragments
	 * becoming joined and having same nicks in use. We cannot have
	 * TWO users with same nick--purge this NICK from the system with
	 * a KILL... >;)
	 *
	 * Changed to something reasonable like IsServer(sptr) (true if
	 * "NICK new", false if ":old NICK new") -orabidoo
	 */
     
	if (IsServer(sptr))
	{
	    /*
	     * A new NICK being introduced by a neighbouring server (e.g.
	     * message type "NICK new" received)
	     */
	    if (!newts || !acptr->tsinfo || (newts == acptr->tsinfo))
	    {
		sendto_realops_lev(SKILL_LEV, "Nick collision on %s", parv[1]);
		ircstp->is_kill++;
		sendto_one(acptr, err_str(ERR_NICKCOLLISION),
			   me.name, acptr->name, acptr->name);
		sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",
				   me.name, acptr->name, me.name);
		acptr->flags |= FLAGS_KILLED;
		return exit_client(cptr, acptr, &me, "Nick collision");
	    }
	    else
	    {
		/* XXX This looks messed up to me XXX - Raist */
		sameuser = (acptr->user) &&
		    mycmp(acptr->user->username, parv[5]) == 0 &&
		    mycmp(acptr->user->host, parv[6]) == 0;
		if ((sameuser && newts < acptr->tsinfo) || 
		    (!sameuser && newts > acptr->tsinfo))
		{
		    return 0;
		}
		else
		{
		    sendto_realops_lev(SKILL_LEV, "Nick collision on %s",parv[1]);
		    ircstp->is_kill++;
		    sendto_one(acptr, err_str(ERR_NICKCOLLISION),
			       me.name, acptr->name, acptr->name);
		    sendto_serv_butone(sptr, ":%s KILL %s :%s (Nick Collision)",
				       me.name, acptr->name, me.name);
		    acptr->flags |= FLAGS_KILLED;
		    (void) exit_client(cptr, acptr, &me, "Nick collision");
		    break;
		}
	    }
	}
	/*
	 * * A NICK change has collided (e.g. message type * ":old NICK
	 * new". This requires more complex cleanout. * Both clients must be
	 * purged from this server, the "new" * must be killed from the
	 * incoming connection, and "old" must * be purged from all outgoing
	 * connections.
	 */
	if (!newts || !acptr->tsinfo || (newts == acptr->tsinfo) ||
	    !sptr->user)
	{
	    sendto_realops_lev(SKILL_LEV, "Nick change collision: %s", parv[1]);
	    ircstp->is_kill++;
	    sendto_one(acptr, err_str(ERR_NICKCOLLISION),
		       me.name, acptr->name, acptr->name);
	    sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",me.name,
			       sptr->name, me.name);
	    ircstp->is_kill++;
	    sendto_serv_butone(NULL, ":%s KILL %s :%s (Nick Collision)",me.name,
			       acptr->name, me.name);
	    acptr->flags |= FLAGS_KILLED;
	    (void) exit_client(NULL, acptr, &me, "Nick collision(new)");
	    sptr->flags |= FLAGS_KILLED;
	    return exit_client(cptr, sptr, &me, "Nick collision(old)");
	}
	else
	{
	    /* XXX This looks messed up XXX */
	    sameuser = mycmp(acptr->user->username, sptr->user->username) == 0
		&& mycmp(acptr->user->host, sptr->user->host) == 0;
	    if ((sameuser && newts < acptr->tsinfo) ||
		(!sameuser && newts > acptr->tsinfo)) {
		if (sameuser)
		    sendto_realops_lev(SKILL_LEV, 
				   "Nick change collision from %s to %s",
				   sptr->name, acptr->name);
		ircstp->is_kill++;
		sendto_serv_butone(cptr, ":%s KILL %s :%s (Nick Collision)", me.name,
				   sptr->name, me.name);
		sptr->flags |= FLAGS_KILLED;
		if (sameuser)
		    return exit_client(cptr, sptr, &me, "Nick collision(old)");
		else
		    return exit_client(cptr, sptr, &me, "Nick collision(new)");
	    } 
	    else
	    {
		sendto_realops_lev(SKILL_LEV, "Nick collision on %s", acptr->name);
		
		ircstp->is_kill++;
		sendto_one(acptr, err_str(ERR_NICKCOLLISION),
			   me.name, acptr->name, acptr->name);
		sendto_serv_butone(sptr, ":%s KILL %s :%s (Nick Collision)",me.name,
				   acptr->name, me.name);
		acptr->flags |= FLAGS_KILLED;
		(void) exit_client(cptr, acptr, &me, "Nick collision");
	    }
	}
    } while (0);
    
    if (IsServer(sptr))
    {
	uplink = find_server(parv[7], NULL);
	if(!uplink)
	{
	    /* if we can't find the server this nick is on, 
	     * complain loudly and ignore it. - lucas */
	    sendto_realops("Remote nick %s on UNKNOWN server %s",
			   nick, parv[7]);
	    return 0;
	}
	sptr = make_client(cptr, uplink);
	
	/* If this is on a U: lined server, it's a U: lined client. */
	if(IsULine(uplink))
	    sptr->flags|=FLAGS_ULINE;
     
	add_client_to_list(sptr);
	if (parc > 2)
	    sptr->hopcount = atoi(parv[2]);
	if (newts)
	{
	    sptr->tsinfo = newts;
	}
	else
	{
	    newts = sptr->tsinfo = (ts_val) timeofday;
	    ts_warn("Remote nick %s introduced without a TS", nick);
	}
	/* copy the nick in place */
	(void) strcpy(sptr->name, nick);
	(void) add_to_client_hash_table(nick, sptr);
	if (parc >= 10)
	{
	    int *s, flag;
	    char *m;
       
	    /* parse the usermodes -orabidoo */
	    m = &parv[4][1];
	    while (*m)
	    {
		for (s = user_modes; (flag = *s); s += 2)
		    if (*m == *(s + 1))
		    {
			if ((flag == UMODE_o) || (flag == UMODE_O))
			    Count.oper++;
			sptr->umode |= flag & SEND_UMODES;
			break;
		    }
		m++;
	    }
	    if (parc==10)
	    {
		return do_user(nick, cptr, sptr, parv[5], parv[6],
			       parv[7], strtoul(parv[8], NULL, 0),
			       "0.0.0.0", parv[9]);
	    } else if (parc==11)
	    {
		return do_user(nick, cptr, sptr, parv[5], parv[6], parv[7],
			       strtoul(parv[8], NULL, 0),
			       parv[9], parv[10]);
	    }
	}
    }
    else if (sptr->name[0])
    {
#ifdef DONT_CHECK_QLINE_REMOTE
	if (MyConnect(sptr))
	{
#endif
	    if ((ban = check_mask_simbanned(nick, SBAN_NICK)))
	    {
#ifndef DONT_CHECK_QLINE_REMOTE
		if (!MyConnect(sptr))
		    sendto_realops("Restricted nick %s from %s on %s", nick,
				   (*sptr->name != 0 && !IsServer(sptr)) ?
				   sptr->name : "<unregistered>",
				   (sptr->user == NULL) ? ((IsServer(sptr)) ?
							   parv[6] : me.name) :
				   sptr->user->server);
#endif
		
		if (MyConnect(sptr) && (!IsServer(cptr)) && (!IsOper(cptr))
		    && (!IsULine(sptr)))
		{
		    sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name,
			       BadPtr(parv[0]) ? "*" : parv[0], nick,
			       BadPtr(ban->reason) ? "Erroneous Nickname" :
			       ban->reason);
                    if (call_hooks(CHOOK_FORBID, cptr, nick, ban) != FLUSH_BUFFER)
		        sendto_realops_lev(REJ_LEV,
			    	           "Forbidding restricted nick %s from %s",
				           nick, get_client_name(cptr, FALSE));
		    return 0;
		}
	    }
#ifdef DONT_CHECK_QLINE_REMOTE
	}
#endif
	if (MyConnect(sptr))
	{
	    if (IsRegisteredUser(sptr))
	    {
	 
		/* before we change their nick, make sure they're not banned
		 * on any channels, and!! make sure they're not changing to
		 * a banned nick -sed */
		/* a little cleaner - lucas */
	 
		for (lp = sptr->user->channel; lp; lp = lp->next)
		{
		    if (can_send(sptr, lp->value.chptr, NULL))
		    { 
			sendto_one(sptr, err_str(ERR_BANNICKCHANGE), me.name,
				   sptr->name, lp->value.chptr->chname);
			return 0;
		    }
		    if (nick_is_banned(lp->value.chptr, nick, sptr) != NULL)
		    {
			sendto_one(sptr, err_str(ERR_BANONCHAN), me.name,
				   sptr->name, nick, lp->value.chptr->chname);
			return 0;
		    }
		}
#ifdef ANTI_NICK_FLOOD
		if ((sptr->last_nick_change + MAX_NICK_TIME) < NOW)
		    sptr->number_of_nick_changes = 0;
		sptr->last_nick_change = NOW;
		sptr->number_of_nick_changes++;
	 
		if (sptr->number_of_nick_changes > MAX_NICK_CHANGES && 
		    !IsAnOper(sptr))
		{
		    sendto_one(sptr,
			       ":%s NOTICE %s :*** Notice -- Too many nick "
			       "changes. Wait %d seconds before trying again.",
			       me.name, sptr->name, MAX_NICK_TIME);
		    return 0;
		}
#endif
		/* If it changed nicks, -r it */
		if ((sptr->umode & UMODE_r) && (mycmp(parv[0], nick) != 0))
		{
		    unsigned int oldumode;
		    char mbuf[BUFSIZE];

		    oldumode = sptr->umode;
		    sptr->umode &= ~UMODE_r;
		    send_umode(sptr, sptr, oldumode, ALL_UMODES, mbuf);
		}

                /* LOCAL NICKHANGE */
                /*
                 * Client just changing his/her nick. If he/she is on a
                 * channel, send note of change to all clients on that channel.
                 * Propagate notice to other servers.
                 */
                /* if the nickname is different, set the TS */
                if (mycmp(parv[0], nick))
                {
                  sptr->tsinfo = newts ? newts : (ts_val) timeofday;
                }

		sendto_common_channels(sptr, ":%s NICK :%s", parv[0], 
				       nick);
		if (sptr->user)
		{
		    add_history(sptr, 1);
			
		    sendto_serv_butone(cptr, ":%s NICK %s :%ld",
				       parv[0], nick, sptr->tsinfo);
		}
	    }
	}
	else
	{
            /* REMOTE NICKCHANGE */
            /*
             * Client just changing his/her nick. If he/she is on a
             * channel, send note of change to all clients on that channel.
             * Propagate notice to other servers.
             */
            /* if the nickname is different, set the TS */
            if (mycmp(parv[0], nick))
            {
              sptr->tsinfo = newts ? newts : (ts_val) timeofday;
            }

	    sendto_common_channels(sptr, ":%s NICK :%s", parv[0], nick);
	    if (sptr->user)
	    {
		add_history(sptr, 1);
		
		sendto_serv_butone(cptr, ":%s NICK %s :%ld",
				   parv[0], nick, sptr->tsinfo);
	    }

	    /* If it changed nicks, -r it */
	    if (mycmp(parv[0], nick))
		sptr->umode &= ~UMODE_r;

	    /*
	     * Flush the banserial for the channels the user is in, since this
	     * could be a SVSNICK induced nick change, which overrides any ban
	     * checking on the originating server.
	     */
	    flush_user_banserial(sptr);
	}
        /* Remove dccallow entries for users who don't share common channel(s) unless they only change their nick capitalization -Kobi_S */
        if(sptr->user && mycmp(parv[0], nick))
        {
            for(lp = sptr->user->dccallow; lp; lp = lp2)
            {
                lp2 = lp->next;
                if(lp->flags == DCC_LINK_ME)
                    continue;
                if(!find_shared_chan(sptr, lp->value.cptr))
                {
                    sendto_one(lp->value.cptr, ":%s %d %s :%s has been removed from "
                               "your DCC allow list for signing off",
                               me.name, RPL_DCCINFO, lp->value.cptr->name, parv[0]);
                    del_dccallow(lp->value.cptr, sptr, 1);
                }
            }
        }
    } 
    else
    {
	/* Client setting NICK the first time */
	if (MyConnect(sptr))
	{
	    if ((ban = check_mask_simbanned(nick, SBAN_NICK)))
	    {
		if (MyConnect(sptr) && (!IsServer(cptr)) && (!IsOper(cptr))
		    && (!IsULine(sptr)))
		{
		    sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name,
			       BadPtr(parv[0]) ? "*" : parv[0], nick,
			       BadPtr(ban->reason) ? "Erroneous Nickname" :
			       ban->reason);
                    if (call_hooks(CHOOK_FORBID, cptr, nick, ban) != FLUSH_BUFFER)
		        sendto_realops_lev(REJ_LEV,
				           "Forbidding restricted nick %s from %s", nick,
				           get_client_name(cptr, FALSE));
		    return 0;
		}
	    }
	}
	
	strcpy(sptr->name, nick);
	sptr->tsinfo = timeofday;
	if (sptr->user)
	{
	    /* USER already received, now we have NICK */
       
	    if (register_user(cptr, sptr, nick, sptr->user->username, NULL)
		== FLUSH_BUFFER)
		return FLUSH_BUFFER;
	}
    }

    /* Finally set new nick name. */
    if (sptr->name[0])
    {
        del_from_client_hash_table(sptr->name, sptr);
        samenick = mycmp(sptr->name, nick) ? 0 : 1;
        if (IsPerson(sptr))
        {
            if (!samenick)
                hash_check_watch(sptr, RPL_LOGOFF);
#ifdef RWHO_PROBABILITY
            probability_change(sptr->name, nick);
#endif
        }
    }
    strcpy(sptr->name, nick);
    add_to_client_hash_table(nick, sptr);
    if (IsPerson(sptr) && !samenick)
	hash_check_watch(sptr, RPL_LOGON);
    return 0;
}
Пример #24
0
int m_dkey(aClient *cptr, aClient *sptr, int parc, char *parv[])
{
    if(!(IsNegoServer(sptr) && parc > 1))
    {
        if(IsPerson(sptr))
            return 0;
        return exit_client(sptr, sptr, sptr, "Not negotiating now");
    }
#ifdef HAVE_ENCRYPTION_ON
    if(mycmp(parv[1], "START") == 0)
    {
        char keybuf[1024];

        if(parc != 2)
            return exit_client(sptr, sptr, sptr, "DKEY START failure");

        if(sptr->serv->sessioninfo_in != NULL &&
           sptr->serv->sessioninfo_out != NULL)
            return exit_client(sptr, sptr, sptr, "DKEY START duplicate?!");

        sptr->serv->sessioninfo_in = dh_start_session();
        sptr->serv->sessioninfo_out = dh_start_session();

        sendto_realops("Initiating diffie-hellman key exchange with %s",
                       sptr->name);

        dh_get_s_public(keybuf, 1024, sptr->serv->sessioninfo_in);
        sendto_one(sptr, "DKEY PUB I %s", keybuf);

        dh_get_s_public(keybuf, 1024, sptr->serv->sessioninfo_out);
        sendto_one(sptr, "DKEY PUB O %s", keybuf);
        return 0;
    }

    if(mycmp(parv[1], "PUB") == 0)
    {
        unsigned char keybuf[1024];
        size_t keylen;

        if(parc != 4 || !sptr->serv->sessioninfo_in ||
           !sptr->serv->sessioninfo_out)
            return exit_client(sptr, sptr, sptr, "DKEY PUB failure");

        if(mycmp(parv[2], "O") == 0) /* their out is my in! */
        {
            if(!dh_generate_shared(sptr->serv->sessioninfo_in, parv[3]))
                return exit_client(sptr, sptr, sptr, "DKEY PUB O invalid");
            sptr->serv->dkey_flags |= DKEY_GOTOUT;
        }
        else if(mycmp(parv[2], "I") == 0) /* their out is my in! */
        {
            if(!dh_generate_shared(sptr->serv->sessioninfo_out, parv[3]))
                return exit_client(sptr, sptr, sptr, "DKEY PUB I invalid");
            sptr->serv->dkey_flags |= DKEY_GOTIN;
        }
        else
            return exit_client(sptr, sptr, sptr, "DKEY PUB bad option");

        if(DKEY_DONE(sptr->serv->dkey_flags))
        {
            sendto_one(sptr, "DKEY DONE");
            SetRC4OUT(sptr);

            keylen = 1024;
            if(!dh_get_s_shared(keybuf, &keylen, sptr->serv->sessioninfo_in))
                return exit_client(sptr, sptr, sptr,
                                   "Could not setup encrypted session");
            sptr->serv->rc4_in = rc4_initstate(keybuf, keylen);

            keylen = 1024;
            if(!dh_get_s_shared(keybuf, &keylen, sptr->serv->sessioninfo_out))
                return exit_client(sptr, sptr, sptr,
                                   "Could not setup encrypted session");
            sptr->serv->rc4_out = rc4_initstate(keybuf, keylen);

            dh_end_session(sptr->serv->sessioninfo_in);
            dh_end_session(sptr->serv->sessioninfo_out);

            sptr->serv->sessioninfo_in = sptr->serv->sessioninfo_out = NULL;
            return 0;
        }

        return 0;
    }


    if(mycmp(parv[1], "DONE") == 0)
    {
        if(!((sptr->serv->sessioninfo_in == NULL &&
              sptr->serv->sessioninfo_out == NULL) &&
             (sptr->serv->rc4_in != NULL && sptr->serv->rc4_out != NULL)))
            return exit_client(sptr, sptr, sptr, "DKEY DONE when not done!");
        SetRC4IN(sptr);
        sendto_realops("Diffie-Hellman exchange with %s complete, connection "
                       "encrypted.", sptr->name);
        sendto_one(sptr, "DKEY EXIT");
        return RC4_NEXT_BUFFER;
    }

    if(mycmp(parv[1], "EXIT") == 0)
    {
        if(!(IsRC4IN(sptr) && IsRC4OUT(sptr)))
            return exit_client(sptr, sptr, sptr, "DKEY EXIT when not in "
                               "proper stage");
        ClearNegoServer(sptr);
        return do_server_estab(sptr);
    }
#endif
    return 0;
}
Пример #25
0
int
initconf(char *filename)
{
    int lnum = 0, blnum = 0, clear = 0;
    char line[LINE_MAX];
    char *cur = NULL;
    char *tok;
    tConf *block = NULL;
    FILE *file;
    int including = 0;

    current_file = filename;

    if(!(file = fopen(filename, "r")))
    {
        if(forked)
            sendto_realops("Unable to open config file %s", filename);
        else
            printf("Unable to open config file %s\n", filename);
        return -1;
    }

    while(!BadPtr(cur) || ((fgets(line, LINE_MAX, file) != NULL) && ++lnum
                           && (cur = line)))
    {
        cur = check_quote(cur);
        if(BadPtr(cur))
            continue;

        if (including)
        {
            if (including == 1)
            {
jmp_including:
                if (*cur == '"' || *cur == '<')
                    cur++;
                tok = cur;
                while (*cur && *cur != ' ' && *cur != '\t' && *cur != '"'
                        && *cur != '>' && *cur != ';' && *cur != '\n')
                    cur++;
                if (*cur == ';')
                    including = 0;
                else
                    including++;
                *cur++ = 0;

                if (!*tok)
                {
                    confparse_error("Bad include filename", lnum);
                    fclose(file);
                    return -1;
                }

                /* parse new file */
                if(initconf(tok) == -1)
                {
                    current_file = filename;
                    confparse_error("while processing include directive",lnum);
                    fclose(file);
                    return -1;
                }

                /* reset */
                current_file = filename;

                cur = check_quote(cur);
                if (BadPtr(cur))
                    continue;
            }
            if (including == 2)
            {
                if (*cur != ';')
                {
                    confparse_error("Missing semicolon", lnum);
                    fclose(file);
                    return -1;
                }
                including = 0;
                cur++;
                cur = check_quote(cur);
                if (BadPtr(cur))
                    continue;
            }
        }

        /* now, we should be ok to get that token.. */
        if(!block)
        {
            tok = cur;
            while((*cur != ' ') && (*cur != '\n') && (*cur != '{'))
                cur++;      /* find the whitespace following the token */
            if(*cur == '{')
                clear = 1;
            *cur = '\0';
            cur++;

            if (!mycmp("INCLUDE", tok))
            {
                if(clear)
                {
                    confparse_error("Unexpected opening bracket", lnum);
                    fclose(file);
                    return -1;
                }
                including++;
                cur = check_quote(cur);
                if (BadPtr(cur))
                    continue;
                goto jmp_including; /* XXX */
            }

            for(block = tconftab; block->tok; block++)
                if(!mycmp(block->tok, tok))
                    break;
            if(!block->tok)
            {
                confparse_error("Unknown block type", lnum);
                fclose(file);
                return -1;
            }
            blnum = lnum;
        }
        cur = check_quote(cur);
        if(BadPtr(cur))
            continue;
        if((*cur ==  '{') || clear)
            cur++;
        else
        {
            confparse_error("Junk after block name", lnum);
            fclose(file);
            return -1;
        }
        if((cur = parse_block(block, cur, file, &lnum)) == NULL)
        {
            fclose(file);
            return -1;
        }
        clear = 0;
        block = NULL;
        continue;
    }
    if(clear)
    {
        confparse_error("Unexpected EOF:  Syntax error", blnum);
        fclose(file);
        return -1;
    }
    fclose(file);
    return 1;
}
Пример #26
0
/*
** m_nick
**	parv[0] = sender prefix
**	parv[1] = nickname
**  if from new client  -taz
**	parv[2] = nick password
**  if from server:
**      parv[2] = hopcount
**      parv[3] = timestamp
**      parv[4] = username
**      parv[5] = hostname
**      parv[6] = servername
**  if NICK version 1:
**      parv[7] = servicestamp
**	parv[8] = info
**  if NICK version 2:
**	parv[7] = servicestamp
**      parv[8] = umodes
**	parv[9] = virthost, * if none
**	parv[10] = info
**  if NICKIP:
**      parv[10] = ip
**      parv[11] = info
*/
DLLFUNC CMD_FUNC(m_nick)
{
	aTKline *tklban;
	int ishold;
	aClient *acptr, *serv = NULL;
	aClient *acptrs;
	char nick[NICKLEN + 2], *s;
	Membership *mp;
	time_t lastnick = (time_t) 0;
	int  differ = 1, update_watch = 1;
	unsigned char newusr = 0, removemoder = 1;
	/*
	 * If the user didn't specify a nickname, complain
	 */
	if (parc < 2)
	{
		sendto_one(sptr, err_str(ERR_NONICKNAMEGIVEN),
		    me.name, parv[0]);
		return 0;
	}

	strncpyzt(nick, parv[1], NICKLEN + 1);

	if (MyConnect(sptr) && sptr->user && !IsAnOper(sptr))
	{
		if ((sptr->user->flood.nick_c >= NICK_COUNT) && 
		    (TStime() - sptr->user->flood.nick_t < NICK_PERIOD))
		{
			/* Throttle... */
			sendto_one(sptr, err_str(ERR_NCHANGETOOFAST), me.name, sptr->name, nick,
				(int)(NICK_PERIOD - (TStime() - sptr->user->flood.nick_t)));
			return 0;
		}
	}

	/* For a local clients, do proper nickname checking via do_nick_name()
	 * and reject the nick if it returns false.
	 * For remote clients, do a quick check by using do_remote_nick_name(),
	 * if this returned false then reject and kill it. -- Syzop
	 */
	if ((IsServer(cptr) && !do_remote_nick_name(nick)) ||
	    (!IsServer(cptr) && !do_nick_name(nick)))
	{
		sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),
		    me.name, parv[0], parv[1], "Illegal characters");

		if (IsServer(cptr))
		{
			ircstp->is_kill++;
			sendto_failops("Bad Nick: %s From: %s %s",
			    parv[1], parv[0], get_client_name(cptr, FALSE));
			sendto_one(cptr, ":%s KILL %s :%s (%s <- %s[%s])",
			    me.name, parv[1], me.name, parv[1],
			    nick, cptr->name);
			if (sptr != cptr)
			{	/* bad nick change */
				sendto_serv_butone(cptr,
				    ":%s KILL %s :%s (%s <- %s!%s@%s)",
				    me.name, parv[0], me.name,
				    get_client_name(cptr, FALSE),
				    parv[0],
				    sptr->user ? sptr->username : "",
				    sptr->user ? sptr->user->server :
				    cptr->name);
				sptr->flags |= FLAGS_KILLED;
				return exit_client(cptr, sptr, &me, "BadNick");
			}
		}
		return 0;
	}

	/* Kill quarantined opers early... */
	if (IsServer(cptr) && (sptr->from->flags & FLAGS_QUARANTINE) &&
	    (parc >= 11) && strchr(parv[8], 'o'))
	{
		ircstp->is_kill++;
		/* Send kill to uplink only, hasn't been broadcasted to the rest, anyway */
		sendto_one(cptr, ":%s KILL %s :%s (Quarantined: no global oper privileges allowed)",
			me.name, parv[1], me.name);
		sendto_realops("QUARANTINE: Oper %s on server %s killed, due to quarantine",
			parv[1], sptr->name);
		/* (nothing to exit_client or to free, since user was never added) */
		return 0;
	}

	/*
	   ** Protocol 4 doesn't send the server as prefix, so it is possible
	   ** the server doesn't exist (a lagged net.burst), in which case
	   ** we simply need to ignore the NICK. Also when we got that server
	   ** name (again) but from another direction. --Run
	 */
	/*
	   ** We should really only deal with this for msgs from servers.
	   ** -- Aeto
	 */
	if (IsServer(cptr) &&
	    (parc > 7
	    && (!(serv = (aClient *)find_server_b64_or_real(parv[6]))
	    || serv->from != cptr->from)))
	{
		sendto_realops("Cannot find server %s (%s)", parv[6],
		    backupbuf);
		return 0;
	}
	/*
	   ** Check against nick name collisions.
	   **
	   ** Put this 'if' here so that the nesting goes nicely on the screen :)
	   ** We check against server name list before determining if the nickname
	   ** is present in the nicklist (due to the way the below for loop is
	   ** constructed). -avalon
	 */
	/* I managed to f**k this up i guess --stskeeps */
	if ((acptr = find_server(nick, NULL)))
	{
		if (MyConnect(sptr))
		{
#ifdef GUEST
			if (IsUnknown(sptr))
			{
				RunHook4(HOOKTYPE_GUEST, cptr, sptr, parc, parv);
				return 0;
			}
#endif
			sendto_one(sptr, err_str(ERR_NICKNAMEINUSE), me.name,
			    BadPtr(parv[0]) ? "*" : parv[0], nick);
			return 0;	/* NICK message ignored */
		}
	}

	/*
	   ** Check for a Q-lined nickname. If we find it, and it's our
	   ** client, just reject it. -Lefler
	   ** Allow opers to use Q-lined nicknames. -Russell
	 */
	if (!stricmp("ircd", nick))
	{
		sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name,
		    BadPtr(parv[0]) ? "*" : parv[0], nick,
		    "Reserved for internal IRCd purposes");
		return 0;
	}
	if (!stricmp("irc", nick))
	{
		sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME), me.name,
		    BadPtr(parv[0]) ? "*" : parv[0], nick,
		    "Reserved for internal IRCd purposes");
		return 0;
	}
	if (MyClient(sptr)) /* local client changin nick afterwards.. */
	{
		int xx;
		spamfilter_build_user_string(spamfilter_user, nick, sptr);
		xx = dospamfilter(sptr, spamfilter_user, SPAMF_USER, NULL, 0, NULL);
		if (xx < 0)
			return xx;
	}
	if (!IsULine(sptr) && (tklban = find_qline(sptr, nick, &ishold)))
	{
		if (IsServer(sptr) && !ishold) /* server introducing new client */
		{
			acptrs =
			    (aClient *)find_server_b64_or_real(sptr->user ==
			    NULL ? (char *)parv[6] : (char *)sptr->user->
			    server);
			/* (NEW: no unregistered q:line msgs anymore during linking) */
			if (!acptrs || (acptrs->serv && acptrs->serv->flags.synced))
				sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick,
				    (*sptr->name != 0
				    && !IsServer(sptr) ? sptr->name : "<unregistered>"),
				    acptrs ? acptrs->name : "unknown server");
		}
		
		if (IsServer(cptr) && IsPerson(sptr) && !ishold) /* remote user changing nick */
		{
			sendto_snomask(SNO_QLINE, "Q:lined nick %s from %s on %s", nick,
				sptr->name, sptr->srvptr ? sptr->srvptr->name : "<unknown>");
		}

		if (!IsServer(cptr)) /* local */
		{
			if (ishold)
			{
				sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),
				    me.name, BadPtr(parv[0]) ? "*" : parv[0],
				    nick, tklban->reason);
				return 0;
			}
			if (!IsOper(cptr))
			{
				sptr->since += 4; /* lag them up */
				sendto_one(sptr, err_str(ERR_ERRONEUSNICKNAME),
				    me.name, BadPtr(parv[0]) ? "*" : parv[0],
				    nick, tklban->reason);
				sendto_snomask(SNO_QLINE, "Forbidding Q-lined nick %s from %s.",
				    nick, get_client_name(cptr, FALSE));
				return 0;	/* NICK message ignored */
			}
		}
	}
	/*
	   ** acptr already has result from previous find_server()
	 */
	if (acptr)
	{
		/*
		   ** We have a nickname trying to use the same name as
		   ** a server. Send out a nick collision KILL to remove
		   ** the nickname. As long as only a KILL is sent out,
		   ** there is no danger of the server being disconnected.
		   ** Ultimate way to jupiter a nick ? >;-). -avalon
		 */
		sendto_failops("Nick collision on %s(%s <- %s)",
		    sptr->name, acptr->from->name,
		    get_client_name(cptr, FALSE));
		ircstp->is_kill++;
		sendto_one(cptr, ":%s KILL %s :%s (%s <- %s)",
		    me.name, sptr->name, me.name, acptr->from->name,
		    /* NOTE: Cannot use get_client_name
		       ** twice here, it returns static
		       ** string pointer--the other info
		       ** would be lost
		     */
		    get_client_name(cptr, FALSE));
		sptr->flags |= FLAGS_KILLED;
		return exit_client(cptr, sptr, &me, "Nick/Server collision");
	}

	if (MyClient(cptr) && !IsOper(cptr))
		cptr->since += 3;	/* Nick-flood prot. -Donwulff */

	if (!(acptr = find_client(nick, NULL)))
		goto nickkilldone;	/* No collisions, all clear... */
	/*
	   ** If the older one is "non-person", the new entry is just
	   ** allowed to overwrite it. Just silently drop non-person,
	   ** and proceed with the nick. This should take care of the
	   ** "dormant nick" way of generating collisions...
	 */
	/* Moved before Lost User Field to fix some bugs... -- Barubary */
	if (IsUnknown(acptr) && MyConnect(acptr))
	{
		/* This may help - copying code below */
		if (acptr == cptr)
			return 0;
		acptr->flags |= FLAGS_KILLED;
		exit_client(NULL, acptr, &me, "Overridden");
		goto nickkilldone;
	}
	/* A sanity check in the user field... */
	if (acptr->user == NULL)
	{
		/* This is a Bad Thing */
		sendto_failops("Lost user field for %s in change from %s",
		    acptr->name, get_client_name(cptr, FALSE));
		ircstp->is_kill++;
		sendto_one(acptr, ":%s KILL %s :%s (Lost user field!)",
		    me.name, acptr->name, me.name);
		acptr->flags |= FLAGS_KILLED;
		/* Here's the previous versions' desynch.  If the old one is
		   messed up, trash the old one and accept the new one.
		   Remember - at this point there is a new nick coming in!
		   Handle appropriately. -- Barubary */
		exit_client(NULL, acptr, &me, "Lost user field");
		goto nickkilldone;
	}
	/*
	   ** If acptr == sptr, then we have a client doing a nick
	   ** change between *equivalent* nicknames as far as server
	   ** is concerned (user is changing the case of his/her
	   ** nickname or somesuch)
	 */
	if (acptr == sptr) {
		if (strcmp(acptr->name, nick) != 0)
		{
			/* Allows change of case in his/her nick */
			removemoder = 0; /* don't set the user -r */
			goto nickkilldone;	/* -- go and process change */
		} else
			/*
			 ** This is just ':old NICK old' type thing.
			 ** Just forget the whole thing here. There is
			 ** no point forwarding it to anywhere,
			 ** especially since servers prior to this
			 ** version would treat it as nick collision.
			 */
			return 0;	/* NICK Message ignored */
	}
	/*
	   ** Note: From this point forward it can be assumed that
	   ** acptr != sptr (point to different client structures).
	 */
	/*
	   ** Decide, we really have a nick collision and deal with it
	 */
	if (!IsServer(cptr))
	{
		/*
		   ** NICK is coming from local client connection. Just
		   ** send error reply and ignore the command.
		 */
#ifdef GUEST
		if (IsUnknown(sptr))
		{
			RunHook4(HOOKTYPE_GUEST, cptr, sptr, parc, parv);
			return 0;
		}
#endif
		sendto_one(sptr, err_str(ERR_NICKNAMEINUSE),
		    /* parv[0] is empty when connecting */
		    me.name, BadPtr(parv[0]) ? "*" : parv[0], nick);
		return 0;	/* NICK message ignored */
	}
	/*
	   ** NICK was coming from a server connection.
	   ** This means we have a race condition (two users signing on
	   ** at the same time), or two net fragments reconnecting with
	   ** the same nick.
	   ** The latter can happen because two different users connected
	   ** or because one and the same user switched server during a
	   ** net break.
	   ** If we have the old protocol (no TimeStamp and no user@host)
	   ** or if the TimeStamps are equal, we kill both (or only 'new'
	   ** if it was a "NICK new"). Otherwise we kill the youngest
	   ** when user@host differ, or the oldest when they are the same.
	   ** --Run
	   **
	 */
	if (IsServer(sptr))
	{
		/*
		   ** A new NICK being introduced by a neighbouring
		   ** server (e.g. message type "NICK new" received)
		 */
		if (parc > 3)
		{
			lastnick = TS2ts(parv[3]);
			if (parc > 5)
				differ = (mycmp(acptr->user->username, parv[4])
				    || mycmp(acptr->user->realhost, parv[5]));
		}
		sendto_failops("Nick collision on %s (%s %ld <- %s %ld)",
		    acptr->name, acptr->from->name, acptr->lastnick,
		    cptr->name, lastnick);
		/*
		   **    I'm putting the KILL handling here just to make it easier
		   ** to read, it's hard to follow it the way it used to be.
		   ** Basically, this is what it will do.  It will kill both
		   ** users if no timestamp is given, or they are equal.  It will
		   ** kill the user on our side if the other server is "correct"
		   ** (user@host differ and their user is older, or user@host are
		   ** the same and their user is younger), otherwise just kill the
		   ** user an reintroduce our correct user.
		   **    The old code just sat there and "hoped" the other server
		   ** would kill their user.  Not anymore.
		   **                                               -- binary
		 */
		if (!(parc > 3) || (acptr->lastnick == lastnick))
		{
			ircstp->is_kill++;
			sendto_serv_butone(NULL,
			    ":%s KILL %s :%s (Nick Collision)",
			    me.name, acptr->name, me.name);
			acptr->flags |= FLAGS_KILLED;
			(void)exit_client(NULL, acptr, &me,
			    "Nick collision with no timestamp/equal timestamps");
			return 0;	/* We killed both users, now stop the process. */
		}

		if ((differ && (acptr->lastnick > lastnick)) ||
		    (!differ && (acptr->lastnick < lastnick)) || acptr->from == cptr)	/* we missed a QUIT somewhere ? */
		{
			ircstp->is_kill++;
			sendto_serv_butone(cptr,
			    ":%s KILL %s :%s (Nick Collision)",
			    me.name, acptr->name, me.name);
			acptr->flags |= FLAGS_KILLED;
			(void)exit_client(NULL, acptr, &me, "Nick collision");
			goto nickkilldone;	/* OK, we got rid of the "wrong" user,
						   ** now we're going to add the user the
						   ** other server introduced.
						 */
		}

		if ((differ && (acptr->lastnick < lastnick)) ||
		    (!differ && (acptr->lastnick > lastnick)))
		{
			/*
			 * Introduce our "correct" user to the other server
			 */

			sendto_one(cptr, ":%s KILL %s :%s (Nick Collision)",
			    me.name, parv[1], me.name);
			send_umode(NULL, acptr, 0, SEND_UMODES, buf);
			sendto_one_nickcmd(cptr, acptr, buf);
			if (acptr->user->away)
				sendto_one(cptr, ":%s AWAY :%s", acptr->name,
				    acptr->user->away);
			send_user_joins(cptr, acptr);
			return 0;	/* Ignore the NICK */
		}
		return 0;
	}
	else
	{
		/*
		   ** A NICK change has collided (e.g. message type ":old NICK new").
		 */
		if (parc > 2)
			lastnick = TS2ts(parv[2]);
		differ = (mycmp(acptr->user->username, sptr->user->username) ||
		    mycmp(acptr->user->realhost, sptr->user->realhost));
		sendto_failops
		    ("Nick change collision from %s to %s (%s %ld <- %s %ld)",
		    sptr->name, acptr->name, acptr->from->name, acptr->lastnick,
		    sptr->from->name, lastnick);
		if (!(parc > 2) || lastnick == acptr->lastnick)
		{
			ircstp->is_kill += 2;
			sendto_serv_butone(NULL,	/* First kill the new nick. */
			    ":%s KILL %s :%s (Self Collision)",
			    me.name, acptr->name, me.name);
			sendto_serv_butone(cptr,	/* Tell my servers to kill the old */
			    ":%s KILL %s :%s (Self Collision)",
			    me.name, sptr->name, me.name);
			sptr->flags |= FLAGS_KILLED;
			acptr->flags |= FLAGS_KILLED;
			(void)exit_client(NULL, sptr, &me, "Self Collision");
			(void)exit_client(NULL, acptr, &me, "Self Collision");
			return 0;	/* Now that I killed them both, ignore the NICK */
		}
		if ((differ && (acptr->lastnick > lastnick)) ||
		    (!differ && (acptr->lastnick < lastnick)))
		{
			/* sptr (their user) won, let's kill acptr (our user) */
			ircstp->is_kill++;
			sendto_serv_butone(cptr,
			    ":%s KILL %s :%s (Nick collision: %s <- %s)",
			    me.name, acptr->name, me.name,
			    acptr->from->name, sptr->from->name);
			acptr->flags |= FLAGS_KILLED;
			(void)exit_client(NULL, acptr, &me, "Nick collision");
			goto nickkilldone;	/* their user won, introduce new nick */
		}
		if ((differ && (acptr->lastnick < lastnick)) ||
		    (!differ && (acptr->lastnick > lastnick)))
		{
			/* acptr (our user) won, let's kill sptr (their user),
			   ** and reintroduce our "correct" user
			 */
			ircstp->is_kill++;
			/* Kill the user trying to change their nick. */
			sendto_serv_butone(cptr,
			    ":%s KILL %s :%s (Nick collision: %s <- %s)",
			    me.name, sptr->name, me.name,
			    sptr->from->name, acptr->from->name);
			sptr->flags |= FLAGS_KILLED;
			(void)exit_client(NULL, sptr, &me, "Nick collision");
			/*
			 * Introduce our "correct" user to the other server
			 */
			/* Kill their user. */
			sendto_one(cptr, ":%s KILL %s :%s (Nick Collision)",
			    me.name, parv[1], me.name);
			send_umode(NULL, acptr, 0, SEND_UMODES, buf);
			sendto_one_nickcmd(cptr, acptr, buf);
			if (acptr->user->away)
				sendto_one(cptr, ":%s AWAY :%s", acptr->name,
				    acptr->user->away);

			send_user_joins(cptr, acptr);
			return 0;	/* their user lost, ignore the NICK */
		}

	}
	return 0;		/* just in case */
      nickkilldone:
	if (IsServer(sptr))
	{
		/* A server introducing a new client, change source */

		sptr = make_client(cptr, serv);
		add_client_to_list(sptr);
		if (parc > 2)
			sptr->hopcount = TS2ts(parv[2]);
		if (parc > 3)
			sptr->lastnick = TS2ts(parv[3]);
		else		/* Little bit better, as long as not all upgraded */
			sptr->lastnick = TStime();
		if (sptr->lastnick < 0)
		{
			sendto_realops
			    ("Negative timestamp recieved from %s, resetting to TStime (%s)",
			    cptr->name, backupbuf);
			sptr->lastnick = TStime();
		}
		newusr = 1;
	}
	else if (sptr->name[0] && IsPerson(sptr))
	{
		/*
		   ** If the client belongs to me, then check to see
		   ** if client is currently on any channels where it
		   ** is currently banned.  If so, do not allow the nick
		   ** change to occur.
		   ** Also set 'lastnick' to current time, if changed.
		 */
		if (MyClient(sptr))
		{
			for (mp = sptr->user->channel; mp; mp = mp->next)
			{
				if (!is_skochanop(sptr, mp->chptr) && is_banned(sptr, mp->chptr, BANCHK_NICK))
				{
					sendto_one(sptr,
					    err_str(ERR_BANNICKCHANGE),
					    me.name, parv[0],
					    mp->chptr->chname);
					return 0;
				}
				if (CHECK_TARGET_NICK_BANS && !is_skochanop(sptr, mp->chptr) && is_banned_with_nick(sptr, mp->chptr, BANCHK_NICK, nick))
				{
					sendto_one(sptr,
					    ":%s 437 %s %s :Cannot change to a nickname banned on channel",
					    me.name, parv[0],
					    mp->chptr->chname);
					return 0;
				}
				if (!IsOper(sptr) && !IsULine(sptr)
				    && mp->chptr->mode.mode & MODE_NONICKCHANGE
				    && !is_chanownprotop(sptr, mp->chptr))
				{
					sendto_one(sptr,
					    err_str(ERR_NONICKCHANGE),
					    me.name, parv[0],
					    mp->chptr->chname);
					return 0;
				}
			}

			if (TStime() - sptr->user->flood.nick_t >= NICK_PERIOD)
			{
				sptr->user->flood.nick_t = TStime();
				sptr->user->flood.nick_c = 1;
			} else
				sptr->user->flood.nick_c++;

			sendto_snomask(SNO_NICKCHANGE, "*** Notice -- %s (%s@%s) has changed his/her nickname to %s",
				sptr->name, sptr->user->username, sptr->user->realhost, nick);

			RunHook2(HOOKTYPE_LOCAL_NICKCHANGE, sptr, nick);
		} else {
			if (!IsULine(sptr))
				sendto_snomask(SNO_FNICKCHANGE, "*** Notice -- %s (%s@%s) has changed his/her nickname to %s",
					sptr->name, sptr->user->username, sptr->user->realhost, nick);

			RunHook3(HOOKTYPE_REMOTE_NICKCHANGE, cptr, sptr, nick);
		}
		/*
		 * Client just changing his/her nick. If he/she is
		 * on a channel, send note of change to all clients
		 * on that channel. Propagate notice to other servers.
		 */
		if (mycmp(parv[0], nick) ||
		    /* Next line can be removed when all upgraded  --Run */
		    (!MyClient(sptr) && parc > 2
		    && TS2ts(parv[2]) < sptr->lastnick))
			sptr->lastnick = (MyClient(sptr)
			    || parc < 3) ? TStime() : TS2ts(parv[2]);
		if (sptr->lastnick < 0)
		{
			sendto_realops("Negative timestamp (%s)", backupbuf);
			sptr->lastnick = TStime();
		}
		add_history(sptr, 1);
		sendto_common_channels(sptr, ":%s NICK :%s", parv[0], nick);
		sendto_serv_butone_token(cptr, parv[0], MSG_NICK, TOK_NICK,
		    "%s %ld", nick, sptr->lastnick);
		if (removemoder)
			sptr->umodes &= ~UMODE_REGNICK;
	}
	else if (!sptr->name[0])
	{
#ifdef NOSPOOF
		/*
		 * Client setting NICK the first time.
		 *
		 * Generate a random string for them to pong with.
		 */
		sptr->nospoof = getrandom32();

		if (PINGPONG_WARNING)
			sendto_one(sptr, ":%s NOTICE %s :*** If you are having problems"
			    " connecting due to ping timeouts, please"
			    " type /quote pong %X or /raw pong %X now.",
			    me.name, nick, sptr->nospoof, sptr->nospoof);

		sendto_one(sptr, "PING :%X", sptr->nospoof);
#endif /* NOSPOOF */
#ifdef CONTACT_EMAIL
		sendto_one(sptr,
		    ":%s NOTICE %s :*** If you need assistance with a"
		    " connection problem, please email " CONTACT_EMAIL
		    " with the name and version of the client you are"
		    " using, and the server you tried to connect to: %s",
		    me.name, nick, me.name);
#endif /* CONTACT_EMAIL */
#ifdef CONTACT_URL
		sendto_one(sptr,
		    ":%s NOTICE %s :*** If you need assistance with"
		    " connecting to this server, %s, please refer to: "
		    CONTACT_URL, me.name, nick, me.name);
#endif /* CONTACT_URL */

		/* Copy password to the passwd field if it's given after NICK
		 * - originally by taz, modified by Wizzu
		 */
		if ((parc > 2) && (strlen(parv[2]) <= PASSWDLEN)
		    && !(sptr->listener->umodes & LISTENER_JAVACLIENT))
		{
			if (sptr->passwd)
				MyFree(sptr->passwd);
			sptr->passwd = MyMalloc(strlen(parv[2]) + 1);
			(void)strcpy(sptr->passwd, parv[2]);
		}
		/* This had to be copied here to avoid problems.. */
		(void)strcpy(sptr->name, nick);
		if (sptr->user && IsNotSpoof(sptr))
		{
			/*
			   ** USER already received, now we have NICK.
			   ** *NOTE* For servers "NICK" *must* precede the
			   ** user message (giving USER before NICK is possible
			   ** only for local client connection!). register_user
			   ** may reject the client and call exit_client for it
			   ** --must test this and exit m_nick too!!!
			 */
#ifndef NOSPOOF
			if (USE_BAN_VERSION && MyConnect(sptr))
				sendto_one(sptr, ":IRC!IRC@%s PRIVMSG %s :\1VERSION\1",
					me.name, nick);
#endif
			sptr->lastnick = TStime();	/* Always local client */
			if (register_user(cptr, sptr, nick,
			    sptr->user->username, NULL, NULL, NULL) == FLUSH_BUFFER)
				return FLUSH_BUFFER;
			strcpy(nick, sptr->name); /* don't ask, but I need this. do not remove! -- Syzop */
			update_watch = 0;
			newusr = 1;
		}
	}
	/*
	 *  Finally set new nick name.
	 */
	if (update_watch && sptr->name[0])
	{
		(void)del_from_client_hash_table(sptr->name, sptr);
		if (IsPerson(sptr))
			hash_check_watch(sptr, RPL_LOGOFF);
	}
	(void)strcpy(sptr->name, nick);
	(void)add_to_client_hash_table(nick, sptr);
	if (IsServer(cptr) && parc > 7)
	{
		parv[3] = nick;
		do_cmd(cptr, sptr, "USER", parc - 3, &parv[3]);
		if (GotNetInfo(cptr) && !IsULine(sptr))
			sendto_fconnectnotice(sptr->name, sptr->user, sptr, 0, NULL);
	}
	else if (IsPerson(sptr) && update_watch)
		hash_check_watch(sptr, RPL_LOGON);

#ifdef NEWCHFLOODPROT
	if (sptr->user && !newusr && !IsULine(sptr))
	{
		for (mp = sptr->user->channel; mp; mp = mp->next)
		{
			aChannel *chptr = mp->chptr;
			if (chptr && !(mp->flags & (CHFL_CHANOP|CHFL_VOICE|CHFL_CHANOWNER|CHFL_HALFOP|CHFL_CHANPROT)) &&
			    chptr->mode.floodprot && do_chanflood(chptr->mode.floodprot, FLD_NICK) && MyClient(sptr))
			{
				do_chanflood_action(chptr, FLD_NICK, "nick");
			}
		}	
	}
#endif
	if (newusr && !MyClient(sptr) && IsPerson(sptr))
	{
		RunHook(HOOKTYPE_REMOTE_CONNECT, sptr);
	}

	return 0;
}
Пример #27
0
static char *
parse_block(tConf *block, char *cur, FILE *file, int *lnum)
{
    char *tok, *var, *var2;
    char line[LINE_MAX];
    tConf *b2 = NULL;
    sConf *item = NULL;
    sConf *sconftab = block->subtok;
    cVar  *vars[MAX_VALUES] = { 0 };
    int   vnum = 0, tlnum = 0, clear = 0, done = 0, skip = 0;

    if((sconftab) && (sconftab->flag == SCONFF_STRING))
    {
        /* this subtype only takes freeform variables
         * dont bother looking for tokens
         */
        int i = 0;
        while(!BadPtr(cur) || ((fgets(line, LINE_MAX, file) != NULL) &&
                               (*lnum)++ && (cur = line)))
        {
            cur = check_quote(cur);
            if(BadPtr(cur))
                continue;
            if(clear)
            {
                if(*cur != ';')
                {
                    confparse_error("Missing semicolon", *lnum);
                    free_vars(vars);
                    return NULL;
                }
                else
                    cur++;
                clear = 0;
                cur = check_quote(cur);
                if(BadPtr(cur))
                    continue;
            }
            if(done)
            {
                if(*cur != ';')
                {
                    confparse_error("Missing block end semicolon", *lnum);
                    free_vars(vars);
                    return NULL;
                }
                else
                    cur++;
                if(((*block->func) (vars, *lnum)) == -1)
                {
                    free_vars(vars);
                    return NULL;
                }
                if(BadPtr(cur))
                    *cur = '#';     /* we cant return a bad pointer because
                                     * that will pull us out of the conf read
                                     * so this will just get ignored
                                     * kludgy, but effective */
                free_vars(vars);
                return cur;
            }
            cur = check_quote(cur);
            if(BadPtr(cur))
                continue;
            if(*cur == '}')
            {
                done = 1;
                cur++;
                cur = check_quote(cur);
                if(BadPtr(cur))
                    continue;
                if(*cur != ';')
                {
                    confparse_error("Missing block end semicolon", *lnum);
                    free_vars(vars);
                    return NULL;
                }
                else
                    cur++;
                if(((*block->func) (vars, *lnum)) == -1)
                {
                    free_vars(vars);
                    return NULL;
                }
                if(BadPtr(cur))
                    *cur = '#';     /* we cant return a bad pointer because
                                     * that will pull us out of the conf read
                                     * so this will just get ignored
                                     * kludgy, but effective */
                free_vars(vars);
                return cur;
            }
            vars[vnum] = (cVar *) MyMalloc(sizeof(cVar));
            memset((char *) vars[vnum], '\0', sizeof(cVar));
            vars[vnum]->loaded = 1;
            vars[vnum]->type = NULL;
            tok = cur;
            if(*cur == '"')
            {
                i = 1;
                cur++;
            }
            var = cur;
            if(i == 1)
            {
                while(!BadPtr(cur) && (*cur != '"'))
                    cur++;
                if(BadPtr(cur))
                {
                    confparse_error("Cant find closequote", *lnum);
                    free_vars(vars);
                    return NULL;
                }
                *cur = '\0';
                cur++;
                while(!BadPtr(cur) && (*cur != ';'))
                    cur++;
            }
            else
            {
                while(!BadPtr(cur) && (*cur != ';'))
                {
                    if((*cur == ' '))
                    {
                        *cur = '\0';
                        if(vars[vnum]->loaded == 1)
                        {
                            DupString(vars[vnum]->value, var);
                            vars[vnum]->loaded = 2;
                        }
                    }
                    else if(vars[vnum]->loaded == 2)
                    {
                        confparse_error("Junk after value", *lnum);
                        free_vars(vars);
                        return NULL;
                    }
                    cur++;
                }
            }
            tlnum = *lnum;
            if(BadPtr(cur))
            {
                clear = 1;
                continue;
            }
            *cur = '\0';
            cur++;
            if(vars[vnum]->loaded == 1)
                DupString(vars[vnum]->value, var);
            vars[vnum]->loaded = 3;
            vnum++;
        }
        confparse_error("Unexpected EOF: Syntax Error", tlnum);
        free_vars(vars);
        return NULL;
    }

    while(!BadPtr(cur) || ((fgets(line, LINE_MAX, file) != NULL) && (*lnum)++
                           && (cur = line)))
    {
        cur = check_quote(cur);
        if(BadPtr(cur))
            continue;
        if(clear)
        {
            /* if we're looking for a closing semicolon, check for it first
             * if we cant find it, ignore it and hope for the best
             */
            if(*cur != ';')
            {
                confparse_error("Missing semicolon ", *lnum);
                free_vars(vars);
                return NULL;
            }
            else
                cur++;
            clear = 0;
            if(vars[vnum])
            {
                vars[vnum]->loaded = 3;
                vnum++;
            }
            item = NULL;
            cur = check_quote(cur);
            if(BadPtr(cur))
                continue;
        }
        if(done)
        {
            /* we've found the end of our block, now we're looking for the
             * closing semicolon.  if we cant find it, ignore it and
             * hope for the best
             */
            if(*cur != ';')
            {
                confparse_error("Missing block end semicolon", *lnum);
                free_vars(vars);
                return NULL;
            }
            else
                cur++;
            if(((*block->func) (vars, *lnum)) == -1)
            {
                free_vars(vars);
                return NULL;
            }
            if(BadPtr(cur))
                *cur = '#';     /* we cant return a bad pointer because
                                 * that will pull us out of the conf read
                                 * so this will just get ignored
                                 * kludgy, but effective */
            free_vars(vars);
            return cur;
        }
        if(b2 && b2->tok)
        {
            /* we've identified a nested block in a previous loop.
             * we didnt get an openquote yet, so look for that.
             * we must find this.  keep looking til we do.
             */
            if(*cur != '{')
            {
                confparse_error("Junk after nested block token", *lnum);
                free_vars(vars);
                return NULL;
            }
            cur++;
            cur = check_quote(cur);
            cur = parse_block(b2, cur, file, lnum);
            b2 = NULL;
            continue;
        }
        if(!item || !item->tok)
        {
            /* if we dont already have a specific token we're working on
             * find one here.
             */
            cur = check_quote(cur);
            if(BadPtr(cur))
                continue;
            tok = cur;
            tlnum = *lnum;
            if(*cur == '}')
            {
                /* if we've got a closebracket, then we've hit the end
                 * of our block.
                 */
                done = 1;
                cur++;
                cur = check_quote(cur);
                if(BadPtr(cur))
                    continue;
                if(*cur != ';')
                {
                    confparse_error("Missing block end semicolon", *lnum);
                    free_vars(vars);
                    return NULL;
                }
                else
                    cur++;
                if(((*block->func) (vars, *lnum)) == -1)
                {
                    free_vars(vars);
                    return NULL;
                }
                if(BadPtr(cur))
                    *cur = '#';     /* we cant return a bad pointer because
                                     * that will pull us out of the conf read
                                     * so this will just get ignored
                                     * kludgy, but effective */
                free_vars(vars);
                return cur;

            }
            /* our token ends where whitespace or a semicolon begins */
            while(!BadPtr(cur) && ((*cur != ' ') && (*cur != ';') &&
                                   (*cur != '\t') && (*cur != '\n')))
                cur++;
            if(BadPtr(cur))
            {
                confparse_error("Unterminated token", *lnum);
                free_vars(vars);
                return NULL;
            }
            else
            {
                if(*cur == ';')
                    skip = 1;
                *cur = '\0';
            }
            cur++;
            if(block->nest)
            {
                /* we allow nested stuff inside here, so check for it. */
                for(b2 = tconftab; b2->tok; b2++)
                    if(!mycmp(b2->tok, tok))
                        break;
                if(b2 && b2->tok)
                    if(!(block->nest & b2->flag))
                        b2 = NULL;
                if(b2 && b2->tok)
                {
                    /* recurse through the block we found */
                    tlnum = *lnum;
                    cur = check_quote(cur);
                    if(BadPtr(cur))
                        continue;
                    if(*cur != '{')
                    {
                        confparse_error("Junk after nested block name", *lnum);
                        free_vars(vars);
                        return NULL;
                    }
                    cur++;
                    cur = check_quote(cur);
                    cur = parse_block(b2, cur, file, lnum);
                    if(!cur)
                    {
                        free_vars(vars);
                        return NULL;
                    }
                    b2 = NULL;
                    continue;
                }
            }
            /* find our token */
            for(item = sconftab; item && item->tok; item++)
                if(!mycmp(item->tok, tok))
                    break;
            if(!item->tok)
            {
                confparse_error("Unknown token", *lnum);
                free_vars(vars);
                return NULL;
            }
            /* create our variable */
            vars[vnum] = (cVar *) MyMalloc(sizeof(cVar));
            memset((char *) vars[vnum], '\0', sizeof(cVar));
            vars[vnum]->type = item;
            vars[vnum]->loaded = 1;
        }
        if(item->var & VARTYPE_NONE)
        {
            /* we dont need to grab a variable for this type
             * just look for the closing semicolon, and move on */
            vars[vnum]->loaded = 2;
            if(!skip)
            {
                /* we've already gotten our semicolon back
                 * at the end of our token.  dont look for it. */
                cur = check_quote(cur);
                while(!BadPtr(cur) && (*cur != ';'))
                    cur++;
                if(BadPtr(cur))
                {
                    clear = 1;
                    continue;
                }
                cur++;
            }
            skip = 0;
            vars[vnum]->loaded = 3;
            vnum++;
            item = NULL;
            continue;
        }
        if(item->var & VARTYPE_STRING)
        {
            /* we're looking for a string here, so we require
             * quotes around the string...
             */
            cur = check_quote(cur);
            while(!BadPtr(cur) && (*cur != '"'))
                cur++;
            if(BadPtr(cur))
                continue;
            cur++;
            var = cur;
            while(!BadPtr(cur) && (*cur != '"'))
                cur++;
            if(BadPtr(cur))
            {
                confparse_error("Unterminated quote", *lnum);
                free_vars(vars);
                return NULL;
            }
            *cur = '\0';
            cur++;
            DupString(vars[vnum]->value, var);
            vars[vnum]->loaded = 2;
            while(!BadPtr(cur) && (*cur != ';'))
                cur++;
            if(BadPtr(cur))
            {
                clear = 1;
                continue;
            }
            cur++;
            vars[vnum]->loaded = 3;
            vnum++;
            item = NULL;
            continue;
        }
        if(item->var & VARTYPE_INT)
        {
            cur = check_quote(cur);
            var = cur;
            while(!BadPtr(cur) && ((*cur != ';') && (*cur != '\t') &&
                                   (*cur != '\n') && (*cur != ' ')))
                cur++;
            if(BadPtr(cur))
            {
                clear = 1;
                continue;
            }
            if(*cur != ';')
                clear = 1;
            *cur = '\0';
            cur++;
            var2 = var;
            while(*var)
            {
                if(IsDigit(*var))
                    var++;
                else
                {
                    confparse_error("Expecting integer value", *lnum);
                    free_vars(vars);
                    return NULL;
                }
            }
            if(!item)
                continue;
            var = var2;
            DupString(vars[vnum]->value, var);
            vars[vnum]->loaded = 3;
            vnum++;
            item = NULL;
            continue;
        }
        if(item->var & VARTYPE_NAME)
        {
            cur = check_quote(cur);
            if(!BadPtr(cur) && (*cur == '"'))
                cur++;
            var = cur;
            while(!BadPtr(cur) && (*cur != ';'))
            {
                if((*cur == ' ') || (*cur == '"') || (*cur == '\t'))
                {
                    *cur = '\0';
                    if(vars[vnum]->loaded == 1)
                    {
                        DupString(vars[vnum]->value, var);
                        vars[vnum]->loaded = 2;
                    }
                }
                cur++;
            }
            if(BadPtr(cur))
            {
                clear = 1;
                continue;
            }
            *cur = '\0';
            cur++;
            if(vars[vnum]->loaded == 1)
                DupString(vars[vnum]->value, var);
            vars[vnum]->loaded = 3;
            vnum++;
            item = NULL;
            continue;
        }
        confparse_error("Unexpected EOF:  Syntax Error", tlnum);
        free_vars(vars);
        return NULL;
    }
    confparse_error("Unexpected EOF:  Syntax Error", tlnum);
    free_vars(vars);
    return NULL;
}
Пример #28
0
void insertProbeIter(size_t NUM_ENTRIES)
{
    srand(1000);
    unlink("storefile.txt");
    unlink("logfile.txt");
    system("rm -rf stasis_log/");

    sync();

    bLSM::init_stasis();

    double delete_freq = .05;
    double update_freq = .15;

    //data generation
    typedef std::vector<std::string> key_v_t;
    const static size_t max_partition_size = 100000;
    int KEY_LEN = 100;
    std::vector<key_v_t*> *key_v_list = new std::vector<key_v_t*>;
    int list_size = NUM_ENTRIES / max_partition_size + 1;
    for(int i =0; i<list_size; i++)
    {
        key_v_t * key_arr = new key_v_t;
        if(NUM_ENTRIES < max_partition_size*(i+1))
            preprandstr(NUM_ENTRIES-max_partition_size*i, key_arr, KEY_LEN, true);
        else
            preprandstr(max_partition_size, key_arr, KEY_LEN, true);
    
        std::sort(key_arr->begin(), key_arr->end(), &mycmp);
        key_v_list->push_back(key_arr);
        printf("size partition %llu is %llu\n", (unsigned long long)i+1, (unsigned long long)key_arr->size());
    }

    key_v_t * key_arr = new key_v_t;
    
    std::vector<key_v_t::iterator*> iters;
    for(int i=0; i<list_size; i++)
    {
        iters.push_back(new key_v_t::iterator((*key_v_list)[i]->begin()));
    }

    size_t lc = 0;
    while(true)
    {
        int list_index = -1;
        for(int i=0; i<list_size; i++)
        {
            if(*iters[i] == (*key_v_list)[i]->end())
                continue;
            
            if(list_index == -1 || mycmp(**iters[i], **iters[list_index]))
                list_index = i;
        }

        if(list_index == -1)
            break;
        
        if(key_arr->size() == 0 || mycmp(key_arr->back(), **iters[list_index]))
            key_arr->push_back(**iters[list_index]);

        (*iters[list_index])++;        
        lc++;
        if(lc % max_partition_size == 0)
            printf("%llu/%llu completed.\n", (unsigned long long)lc, (unsigned long long)NUM_ENTRIES);
    }

    for(int i=0; i<list_size; i++)
    {
        (*key_v_list)[i]->clear();
        delete (*key_v_list)[i];
        delete iters[i];
    }
    key_v_list->clear();
    delete key_v_list;
    
    printf("key arr size: %llu\n", (unsigned long long)key_arr->size());

    if(key_arr->size() > NUM_ENTRIES)
        key_arr->erase(key_arr->begin()+NUM_ENTRIES, key_arr->end());
    
    NUM_ENTRIES=key_arr->size();
    
    int xid = Tbegin();

    bLSM *ltable = new bLSM(10 * 1024 * 1024, 1000, 1000, 40);
    mergeScheduler mscheduler(ltable);

    recordid table_root = ltable->allocTable(xid);

    Tcommit(xid);

    mscheduler.start();

    printf("Stage 1: Writing %llu keys\n", (unsigned long long)NUM_ENTRIES);
    
    struct timeval start_tv, stop_tv, ti_st, ti_end;
    double insert_time = 0;
    int delcount = 0, upcount = 0;
    int64_t datasize = 0;
    std::vector<pageid_t> dsp;
    std::vector<int> del_list;
    gettimeofday(&start_tv,0);
    for(size_t i = 0; i < NUM_ENTRIES; i++)
    {
        //prepare the data
        std::string ditem;
        getnextdata(ditem, 8192);

        //prepare the key
        dataTuple *newtuple = dataTuple::create((*key_arr)[i].c_str(), (*key_arr)[i].length()+1, ditem.c_str(), ditem.length()+1);
        
        datasize += newtuple->byte_length();

        gettimeofday(&ti_st,0);        
        ltable->insertTuple(newtuple);
        gettimeofday(&ti_end,0);
        insert_time += tv_to_double(ti_end) - tv_to_double(ti_st);

        dataTuple::freetuple(newtuple);

        double rval = ((rand() % 100)+.0)/100;        
        if( rval < delete_freq) //delete a key 
        {
            int del_index = i - (rand()%50); //delete one of the last inserted 50 elements
            if(del_index >= 0 && std::find(del_list.begin(), del_list.end(), del_index) == del_list.end())
            {
                delcount++;

                dataTuple *deltuple = dataTuple::create((*key_arr)[del_index].c_str(), (*key_arr)[del_index].length()+1);

                gettimeofday(&ti_st,0);        
                ltable->insertTuple(deltuple);
                gettimeofday(&ti_end,0);
                insert_time += tv_to_double(ti_end) - tv_to_double(ti_st);

                dataTuple::freetuple(deltuple);

                del_list.push_back(del_index);
                
            }            
        }
        else if(rval < delete_freq + update_freq) //update a record
        {
            int up_index = i - (rand()%50); //update one of the last inserted 50 elements
            if(up_index >= 0 && std::find(del_list.begin(), del_list.end(), up_index) == del_list.end()) 
            {//only update non-deleted elements
                getnextdata(ditem, 512);

                upcount++;
                dataTuple *uptuple = dataTuple::create((*key_arr)[up_index].c_str(), (*key_arr)[up_index].length()+1,
													   ditem.c_str(), ditem.length()+1);
                gettimeofday(&ti_st,0);        
                ltable->insertTuple(uptuple);
                gettimeofday(&ti_end,0);
                insert_time += tv_to_double(ti_end) - tv_to_double(ti_st);

                dataTuple::freetuple(uptuple);
            }            

        }
        
    }
    gettimeofday(&stop_tv,0);
    printf("insert time: %6.1f\n", insert_time);
    printf("insert time: %6.1f\n", (tv_to_double(stop_tv) - tv_to_double(start_tv)));
    printf("#deletions: %d\n#updates: %d\n", delcount, upcount);

    printf("\nTREE STRUCTURE\n");
    printf("datasize: %llu\n", (unsigned long long)datasize);

    xid = Tbegin();



    printf("Stage 2: Looking up %llu keys:\n", (unsigned long long)NUM_ENTRIES);

    int found_tuples=0;
    for(int i=NUM_ENTRIES-1; i>=0; i--)
    {        
        int ri = i;

        //get the key
        uint32_t keylen = (*key_arr)[ri].length()+1;        
        dataTuple::key_t rkey = (dataTuple::key_t) malloc(keylen);
        memcpy((byte*)rkey, (*key_arr)[ri].c_str(), keylen);

        //find the key with the given tuple
        dataTuple *dt = ltable->findTuple(xid, rkey, keylen);

        if(std::find(del_list.begin(), del_list.end(), i) == del_list.end())
        {
            assert(dt!=0);
            assert(!dt->isDelete());
            found_tuples++;
            assert(dt->rawkeylen() == (*key_arr)[ri].length()+1);
            dataTuple::freetuple(dt);
        }
        else
        {
            if(dt!=0)
            {
                assert(dt->rawkeylen() == (*key_arr)[ri].length()+1);
                assert(dt->isDelete());
                dataTuple::freetuple(dt);
            }
        }
        dt = 0;
        free(rkey);
    }
    printf("found %d\n", found_tuples);




    
    key_arr->clear();
    //data_arr->clear();
    delete key_arr;
    //delete data_arr;
    
    mscheduler.shutdown();
    printf("merge threads finished.\n");
    gettimeofday(&stop_tv,0);
    printf("run time: %6.1f\n", (tv_to_double(stop_tv) - tv_to_double(start_tv)));


    
    Tcommit(xid);
    delete ltable;
    bLSM::deinit_stasis();
}
Пример #29
0
static void
test_split(const char *n_flag)
{
#define CheckLen(x) do { \
	if (len != (x)) { \
		fprintf(stderr, "Wrong len %ld at line %d expected %d\n", (long int) len, __LINE__, (x)); \
		exit(1); \
	} \
	} while(0)

	char sql[80];
	char *buf = NULL;
	SQLLEN len;

	/* TODO test with VARCHAR too */
	sprintf(sql, "SELECT CONVERT(%sTEXT,'Prova' + REPLICATE('x',500))", n_flag);
	odbc_command(sql);

	CHKFetch("S");

	/* these 2 tests test an old severe BUG in FreeTDS */
	buf = ODBC_GET(1);
	CHKGetData(1, type, buf, 0, &len, "I");
	if (len != SQL_NO_TOTAL)
		CheckLen(505*lc);
	CHKGetData(1, type, buf, 0, &len, "I");
	if (len != SQL_NO_TOTAL)
		CheckLen(505*lc);
	buf = ODBC_GET(3*lc);
	CHKGetData(1, type, buf, 3 * lc, &len, "I");
	if (len != SQL_NO_TOTAL)
		CheckLen(505*lc);
	if (mycmp(buf, "Pr") != 0) {
		printf("Wrong data result 1\n");
		exit(1);
	}

	buf = ODBC_GET(16*lc);
	CHKGetData(1, type, buf, 16 * lc, &len, "I");
	if (len != SQL_NO_TOTAL)
		CheckLen(503*lc);
	if (mycmp(buf, "ovaxxxxxxxxxxxx") != 0) {
		printf("Wrong data result 2 res = '%s'\n", buf);
		exit(1);
	}

	buf = ODBC_GET(256*lc);
	CHKGetData(1, type, buf, 256 * lc, &len, "I");
	if (len != SQL_NO_TOTAL)
		CheckLen(488*lc);
	CHKGetData(1, type, buf, 256 * lc, &len, "S");
	CheckLen(233*lc);
	CHKGetData(1, type, buf, 256 * lc, &len, "No");

	odbc_reset_statement();

	/* test with varchar, not blob but variable */
	sprintf(sql, "SELECT CONVERT(%sVARCHAR(100), 'Other test')", n_flag);
	odbc_command(sql);

	CHKFetch("S");

	buf = ODBC_GET(7*lc);
	CHKGetData(1, type, buf, 7 * lc, NULL, "I");
	if (mycmp(buf, "Other ") != 0) {
		printf("Wrong data result 1\n");
		exit(1);
	}

	buf = ODBC_GET(5*lc);
	CHKGetData(1, type, buf, 20, NULL, "S");
	if (mycmp(buf, "test") != 0) {
		printf("Wrong data result 2 res = '%s'\n", buf);
		exit(1);
	}
	ODBC_FREE();

	odbc_reset_statement();
}
Пример #30
0
bool dbde_util_unit_minimal_8x16() {
    uint8_t image[128] = {
        0, 1, 9,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
        8, 3, 4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
        4, 5, 6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
        6, 7, 8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
        7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
        5, 6, 7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21,
        3, 4, 5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 18, 20,
        1, 2, 3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 15, 17, 19
    };
    uint8_t packed[128] = {
        3, 0, 0, 0,                // Video header
        8, 0, 0, 0, 0, 0, 0, 0,    // Height
        16, 0, 0, 0, 0, 0, 0, 0,   // Width
#ifdef DBDE_HZ_IN_INTEGER
        1, 0, 0, 0, 0, 0, 0, 0,    // Frame rate (U64)
#else
        0, 0, 0, 0, 0, 0, 240, 63, // Frame rate (double)
#endif
        2, 0, 0, 0,                // Frame header
        1, 0, 0, 0, 0, 0, 0, 0,    // Frame number
        0, 0, 0, 0, 0, 0, 0, 0,    // Unused
        2, 0, 0, 0,                // Number of uint64s of data
        4, 4,                      // Bits per block
        2, 0, 0, 0,                // Number of minimum values
        0, 8,                      // Minimum values
        8, 0, 0, 0,                // Number of packed U64s
        0x10, 0x39, 0x54, 0x76,    // Row 1 block 1
        0x38, 0x54, 0x76, 0x98,    // Row 2 block 1
        0x54, 0x76, 0x98, 0xBA,    // Row 3 block 1
        0x76, 0x98, 0xBA, 0xDC,    // Row 4 block 1
        0x87, 0xA9, 0xCB, 0xED,    // Row 5 block 1
        0x65, 0x87, 0xA9, 0xCB,    // Row 6 block 1
        0x43, 0x65, 0x87, 0xA9,    // Row 7 block 1
        0x21, 0x43, 0x65, 0x87,    // Row 8 block 1
        0x10, 0x32, 0x54, 0x76,    // Row 1 block 2
        0x32, 0x54, 0x76, 0x98,    // Row 2 block 2
        0x54, 0x76, 0x98, 0xBA,    // Row 3 block 2
        0x76, 0x98, 0xBA, 0xDC,    // Row 4 block 2
        0x87, 0xA9, 0xCB, 0xED,    // Row 5 block 2
        0x65, 0x87, 0xA9, 0xDB,    // Row 6 block 2
        0x43, 0x65, 0x87, 0xCA,    // Row 7 block 2
        0x21, 0x43, 0x75, 0xB9     // Row 8 block 2
    };
    video_header vh = (video_header){3, 8, 16, 1};
    frame_header fh = (frame_header){2, 1, 0};
    uint8_t new_im[128];
    uint8_t z0[1024];
    uint8_t new_pk[128];
    uint8_t z1[1024];
    video_header new_vh;
    frame_header new_fh;
    uint8_t *b = packed;
    new_vh = dbde_unpack_video_header(&b);
    if (b - packed != 28) { printf("Read %d bytes instead of 28 to unpack video header\n", (int)(b - packed)); exit(1); }
    if (!mycmp_vh(vh, new_vh)) { printf("Unpacked video header wrong\n"); exit(1); }
    new_fh = dbde_unpack_frame_header(&b);
    if (b - packed != 48) { printf("Read %d bytes instead of 20 to unpack frame header\n", (int)(b - packed) - 28); exit(1); }
    if (!mycmp_fh(fh, new_fh)) { printf("Unpacked frame header wrong\n"); exit(1); }
    b = packed + 28;  // Re-read frame header so we can get whole frame at once
    new_fh = dbde_unpack_frame(&b, (int)vh.width, (int)vh.height, new_im);
    if (!mycmp_fh(fh, new_fh)) { printf("Unpacked frame header wrong on second pass\n"); exit(1); }
    if (b - packed != 128) { printf("Read %d bytes instead of 128 during unpacking\n", (int)(b-packed)); exit(1); }
    if (!mycmp(image, new_im, 128)) { printf("Image data does not match\n"); exit(1); }
    b = new_pk;
    int n;
    n = dbde_pack_video_header(vh, b); b += n;
    n = dbde_pack_frame(fh.index, image, (int)vh.width, (int)vh.height, b);
    if (n != 100) { printf("Wrong number of bytes written: %d\n", n); exit(1); }
#ifdef DBDE_WRITE_MINIMAL
    FILE *fm = fopen(DBDE_WRITE_MINIMAL, "wb");
    fwrite(new_pk, 128, 1, fm);
#ifdef DBDE_MULTIPLE_MINIMAL_FRAMES
    for (int i = 1; i < DBDE_MULTIPLE_MINIMAL_FRAMES; i++) fwrite(new_pk + 28, 100, 1, fm);
#endif
    fclose(fm);
#endif
    if (!mycmp(packed, new_pk, 128)) { printf("Packed data does not match\n"); exit(1); }
}