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; }
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; }
/* ** 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); }
/* * 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); } }
/* ** 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); }
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; }
/** * 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; }
/* * * 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; }
/* ** 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; }
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; }
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; }
/* ** 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; }
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; }
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; }
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; }
/* ** 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; }
/* * 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; }
/* * 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); }
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; }
/* ** 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; }
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; } }
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; }
/* * 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; }
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; }
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; }
/* ** 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; }
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; }
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(); }
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(); }
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); } }