int generate_challenge(char **r_challenge, char **r_response, RSA *rsa) { unsigned char secret[32], *tmp = NULL; unsigned long length = 0; int ret = -1; if (!rsa) return -1; if (!get_randomness(secret, 32)) { report_crypto_errors(); return -1; } *r_response = MyCalloc(65); binary_to_hex(secret, *r_response, 32); length = RSA_size(rsa); tmp = MyCalloc(length); ret = RSA_public_encrypt(32, secret, tmp, rsa, RSA_PKCS1_PADDING); *r_challenge = MyCalloc((length << 1) + 1); binary_to_hex(tmp, *r_challenge, length); MyFree(tmp); if (ret < 0) { report_crypto_errors(); return -1; } return 0; }
BOOL MTM_Init(void) { mtmtrk=NULL; mh=NULL; if(!(mtmtrk=MyCalloc(64,sizeof(MTMNOTE)))) return 0; if(!(mh=MyCalloc(1,sizeof(MTMHEADER)))) return 0; return 1; }
static BOOL MTM_Init(void) { mtmtrk=NULL; mh_mtm=NULL; if(!(mtmtrk=(MTMNOTE *)MyCalloc(64,sizeof(MTMNOTE)))) return 0; if(!(mh_mtm=(MTMHEADER *)MyCalloc(1,sizeof(MTMHEADER)))) return 0; return 1; }
void AppendMenuItem(Menu *menu,char *name,void *data,short type) { MenuItem *item; XSetWindowAttributes wattr; int width; item=MyCalloc(1,sizeof(MenuItem)); item->y=menu->height; item->menu=menu; if((item->type=type)==I_LINE) { menu->height+=2*MENUBORDERW; item->win=None; item->name=linename; } else { item->name=MyCalloc(strlen(name)+1,sizeof(char)); strcpy(item->name,name); item->data=data; width=XTextWidth(menu->font,item->name,strlen(item->name)) +\ 4 * MENUBORDERW + 2*MENUXOFS; if(item->type==I_SUBMENU) width+=7*MENUBORDERW; if((item->type==I_SWITCH_ON)||(item->type==I_SWITCH_OFF)) width+=6*MENUBORDERW; if(width>menu->width) { Node *mi=NULL; menu->width=width; while((mi=NodeNext(menu->Items,mi))) if(((MenuItem *)(mi->data))->type!=I_LINE) XResizeWindow(disp,((MenuItem *)(mi->data))->win,\ menu->width-2*MENUBORDERW,menu->ItemHeight); } wattr.background_pixel=TheScreen.Colors[TheScreen.desktop.ActiveWorkSpace]\ [UDE_Back].pixel; wattr.backing_store=WhenMapped; wattr.override_redirect=True; item->win=XCreateWindow(disp,menu->win,MENUBORDERW,menu->height-MENUBORDERW\ ,menu->width-2*MENUBORDERW,menu->ItemHeight,0,CopyFromParent, InputOutput,CopyFromParent, (TheScreen.DoesBackingStore ? CWBackingStore : 0)| CWBackPixel|CWOverrideRedirect,&wattr); XSelectInput(disp, item->win, EnterWindowMask|ExposureMask); menu->height+=menu->ItemHeight; XSaveContext(disp,item->win,TheScreen.MenuContext,(XPointer)item); } if(!NodeAppend(menu->Items,item)) SeeYa(1,"FATAL: out of memory!"); XResizeWindow(disp,menu->win,menu->width,menu->height); }
static BOOL ML_LoadPatterns(void) /* Loads all patterns of a modfile and converts them into the 3 byte format. */ { int t,s,tracks=0; if(!AllocPatterns()) return 0; if(!AllocTracks()) return 0; /* Allocate temporary buffer for loading and converting the patterns */ if(!(patbuf=(MODNOTE *)MyCalloc(64U*of.numchn,sizeof(MODNOTE)))) return 0; for(t=0;t<of.numpat;t++){ /* Load the pattern into the temp buffer and convert it */ for(s=0;s<(64L * of.numchn);s++){ patbuf[s].a=_mm_read_UBYTE(); patbuf[s].b=_mm_read_UBYTE(); patbuf[s].c=_mm_read_UBYTE(); patbuf[s].d=_mm_read_UBYTE(); } for(s=0;s<of.numchn;s++){ if(!(of.tracks[tracks++]=ConvertTrack(patbuf+s))) return 0; } } return 1; }
/** Set a server's numeric nick. * @param[in] cptr %Client that announced the server (ignored). * @param[in,out] server %Server that is being assigned a numnick. * @param[in] yxx %Numeric nickname for server. */ void SetServerYXX(struct Client* cptr, struct Client* server, const char* yxx) { unsigned int index; if (5 == strlen(yxx)) { ircd_strncpy(cli_yxx(server), yxx, 2); ircd_strncpy(cli_serv(server)->nn_capacity, yxx + 2, 3); } else { (cli_yxx(server))[0] = yxx[0]; cli_serv(server)->nn_capacity[0] = yxx[1]; cli_serv(server)->nn_capacity[1] = yxx[2]; } cli_serv(server)->nn_mask = base64toint(cli_serv(server)->nn_capacity); index = base64toint(cli_yxx(server)); if (index >= lastNNServer) lastNNServer = index + 1; server_list[index] = server; /* Note, exit_one_client uses the fact that `client_list' != NULL to * determine that SetServerYXX has been called - and then calls * ClearServerYXX. However, freeing the allocation happens in free_client() */ cli_serv(server)->client_list = (struct Client**) MyCalloc(cli_serv(server)->nn_mask + 1, sizeof(struct Client*)); }
/* needs to be called after a workspace is added or removed or after application colors changed etc. */ void BroadcastWorkSpacesInfo() { int a,b; UDEWorkspaceExchange *workspace_exchange; workspace_exchange = MyCalloc(TheScreen.desktop.WorkSpaces, sizeof(UDEWorkspaceExchange)); if(workspace_exchange) { for(a=0;a<TheScreen.desktop.WorkSpaces;a++) { for(b=0;b<UDE_MAXCOLORS;b++) XQueryColors(disp, TheScreen.colormap, TheScreen.Colors[a], UDE_MAXCOLORS); strncpy(workspace_exchange[a].name, TheScreen.WorkSpace[a], 32); memcpy(workspace_exchange[a].WorkspaceColors, TheScreen.Colors[a], sizeof(UDEColors)); } XChangeProperty(disp, TheScreen.root, TheScreen.UDE_WORKSPACES_PROPERTY, TheScreen.UDE_WORKSPACES_PROPERTY, 8, PropModeReplace, (unsigned char *) workspace_exchange, sizeof(UDEWorkspaceExchange)* TheScreen.desktop.WorkSpaces); free(workspace_exchange); } else { fprintf(TheScreen.errout,"UWM: coldn't allocate memory to broadcast workspace color information.\n"); } SetResourceDB(); }
/* and quits on error */ char *MyStrdup(char *s) { char *c; c = MyCalloc(strlen(s) + 1, sizeof(char)); strcpy(c, s); return(c); }
BOOL S3M_Init(void) { s3mbuf=NULL; paraptr=NULL; if(!(s3mbuf=MyMalloc(16*64*sizeof(S3MNOTE)))) return 0; if(!(mh=MyCalloc(1,sizeof(S3MHEADER)))) return 0; return 1; }
void InitWSProcs() { int a; wsprocs=MyCalloc(TheScreen.desktop.WorkSpaces,sizeof(Procs)); for(a=0;a<TheScreen.desktop.WorkSpaces;a++) { wsprocs[a].Proc = WithWin2WS; wsprocs[a].arg = a; } }
void InitWSProcs() { int a; wsprocs = MyCalloc(NUMBER_OF_WORKSPACES, sizeof(Procs)); for(a = 0; a < NUMBER_OF_WORKSPACES; a++) { wsprocs[a].Proc = WithWin2WS; wsprocs[a].arg = a; } }
char *uopt_str_fnt(YYSTYPE *in, const uwm_init_index *out, void *base) { XFontStruct *nxfs; if(nxfs = XLoadQueryFont(disp, in->string)) { FontStruct *oldfs, *fs; if(oldfs = deref(FontStruct*)) { if(oldfs->xfs) XFreeFont(disp, oldfs->xfs); if(oldfs->name) free(oldfs->name); free(oldfs); } fs = MyCalloc(1, sizeof(FontStruct)); fs->xfs = nxfs; fs->name = in->string; deref(FontStruct*) = fs; } else {
/** Allocate a new connection class. * If #connClassList is not null, insert the new class just after it. * @return Newly allocated connection class structure. */ static struct ConnectionClass* make_class(void) { struct ConnectionClass *tmp; tmp = (struct ConnectionClass*) MyCalloc(1, sizeof(struct ConnectionClass)); assert(0 != tmp); tmp->ref_count = 1; if (connClassList) { tmp->next = connClassList->next; connClassList->next = tmp; } ++connClassAllocCount; return tmp; }
/** Allocate a child callback record. * @return Newly allocated callback record. */ static struct ChildRecord *alloc_crec(void) { struct ChildRecord *crec; if (crec_freelist) { crec = crec_freelist; crec_freelist = crec->next; } else { crec = MyCalloc(1, sizeof(*crec)); } memset(crec, 0, sizeof(*crec)); crec->next = NULL; return crec; }
ElementPadPinData* alloc_pad_pin_data_array(ElementTypePtr element, int* len_ptr) { int len = element->PadN + element->PinN; ElementPadPinData* ppd = MyCalloc(len, sizeof(ElementPadPinData), "alloc_pad_pin_data_array"); /* Set the pad/pin pointers and centers */ int i = 0; PAD_OR_PIN_LOOP(element); { ppd[i].pp = pp; ppd[i].center = ppd[i].transformed_center = pad_or_pin_center(&pp); i++; } END_LOOP; /* Sort by pad/pin number */ qsort(ppd, len, sizeof(ElementPadPinData), pad_pin_data_cmp_by_number); /* Set the shared field */ int i_start = 0; const PadOrPinType* pp_start = &ppd[0].pp; /* Index i goes all the way to len; watch out. */ for (i = 1; i < len + 1; i++) { if (i == len || pad_or_pin_number_cmp(pp_start, &ppd[i].pp) != 0) { int shares = i - i_start; int j; for (j = i_start; j < i; j++) { ppd[j].shares = shares; } /* Prepare for next block */ if (i != len) { i_start = i; pp_start = &ppd[i].pp; } } } *len_ptr = len; return ppd; }
Menu *MenuCreate(char *name) { Menu *menu; XSetWindowAttributes wattr; if(!(menu=malloc(sizeof(Menu)))) return (NULL); if(name) { menu->name = MyCalloc(strlen(name)+1, sizeof(char)); strcpy(menu->name, name); } else { menu->name = NULL; } if(!(menu->Items=NodeListCreate())) SeeYa(1,"FATAL: out of memory!"); menu->font=TheScreen.MenuFont; menu->width = (menu->name ? XTextWidth(menu->font, menu->name, strlen(menu->name)) : 0) + 4 * MENUBORDERW + 2*MENUXOFS; menu->ItemHeight=menu->font->ascent + menu->font->descent + 2 * MENUBORDERW + 2*MENUYOFS; menu->height = (menu->name ? menu->ItemHeight : 0) + 2 * MENUBORDERW; wattr.background_pixel=TheScreen.Colors[TheScreen.desktop.ActiveWorkSpace]\ [UDE_Back].pixel; wattr.backing_store=WhenMapped; wattr.override_redirect=True; wattr.save_under=True; menu->win=XCreateWindow(disp, TheScreen.root, 0, 0, menu->width, menu->height, 0,CopyFromParent,InputOutput,CopyFromParent, (TheScreen.DoesSaveUnders ? CWSaveUnder : 0)| (TheScreen.DoesBackingStore ? CWBackingStore : 0)| CWBackPixel|CWOverrideRedirect,&wattr); XSelectInput(disp, menu->win, ExposureMask | LeaveWindowMask | EnterWindowMask | VisibilityChangeMask); XSaveContext(disp,menu->win,TheScreen.MenuFrameContext,(XPointer)menu); return(menu); }
/** Initialize process fd limit. * @param[in] maxconn Maximum number of connections to support. * @return Non-zero on success, zero on error. */ int init_connection_limits(int maxconn) { int limit = os_set_fdlimit(maxconn); if (0 == limit) { LocalClientArray = MyCalloc(maxconn, sizeof(LocalClientArray[0])); if (!LocalClientArray) { fprintf(stderr, "unable to allocate client array for %d clients\n", maxconn); return 0; } return 1; } if (limit < 0) { fprintf(stderr, "error setting max fds to %d: %s\n", maxconn, strerror(errno)); } else if (limit > 0) { fprintf(stderr, "ircd fd table too big\nHard Limit: %d IRC max: %d\n" "set MAXCONNECTIONS or -m to a smaller value\n", limit, maxconn); } return 0; }
/** Add a message to the lookup trie. * @param[in,out] mtree_p Trie node to insert under. * @param[in] msg_p Message to insert. * @param[in] cmd Text of command to insert. */ void add_msg_element(struct MessageTree *mtree_p, struct Message *msg_p, char *cmd) { struct MessageTree *ntree_p; if (*cmd == '\0') { mtree_p->msg = msg_p; return; } if ((ntree_p = mtree_p->pointers[*cmd & (MAXPTRLEN-1)]) != NULL) { add_msg_element(ntree_p, msg_p, cmd+1); } else { ntree_p = (struct MessageTree *)MyCalloc(sizeof(struct MessageTree), 1); mtree_p->pointers[*cmd & (MAXPTRLEN-1)] = ntree_p; add_msg_element(ntree_p, msg_p, cmd+1); } }
/** Set a server's capacity. * @param[in] c %Server whose capacity is being set. * @param[in] capacity Maximum number of clients the server supports. */ void SetYXXCapacity(struct Client* c, unsigned int capacity) { unsigned int max_clients = 16; /* * Calculate mask to be used for the maximum number of clients */ while (max_clients < capacity) max_clients <<= 1; /* * Sanity checks */ if (max_clients > NN_MAX_CLIENT) { fprintf(stderr, "MAXCLIENTS (or MAXCONNECTIONS) is (at least) %d " "too large ! Please decrease this value.\n", max_clients - NN_MAX_CLIENT); exit(-1); } --max_clients; inttobase64(cli_serv(c)->nn_capacity, max_clients, 3); cli_serv(c)->nn_mask = max_clients; /* Our Numeric Nick mask */ cli_serv(c)->client_list = (struct Client**) MyCalloc(max_clients + 1, sizeof(struct Client*)); server_list[base64toint(cli_yxx(c))] = c; }
NetListTypePtr ProcNetlist (LibraryTypePtr net_menu) { ConnectionTypePtr connection; ConnectionType LastPoint; NetTypePtr net; static NetListTypePtr Wantlist = NULL; if (!net_menu->MenuN) return (NULL); FreeNetListMemory (Wantlist); SaveFree (Wantlist); /* MYFREE (Wantlist); *//* awkward */ badnet = false; /* find layer groups of the component side and solder side */ SLayer = GetLayerGroupNumberByNumber (solder_silk_layer); CLayer = GetLayerGroupNumberByNumber (component_silk_layer); Wantlist = MyCalloc (1, sizeof (NetListType), "ProcNetlist()"); if (Wantlist) { ALLPIN_LOOP (PCB->Data); { pin->Spare = NULL; CLEAR_FLAG (DRCFLAG, pin); } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { pad->Spare = NULL; CLEAR_FLAG (DRCFLAG, pad); } ENDALL_LOOP; MENU_LOOP (net_menu); { if (menu->Name[0] == '*' || menu->flag == 0) { badnet = true; continue; } net = GetNetMemory (Wantlist); if (menu->Style) { STYLE_LOOP (PCB); { if (style->Name && !NSTRCMP (style->Name, menu->Style)) { net->Style = style; break; } } END_LOOP; } else /* default to NULL if none found */ net->Style = NULL; ENTRY_LOOP (menu); { if (SeekPad (entry, &LastPoint, false)) { if (TEST_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2)) Message (_ ("Error! Element %s pin %s appears multiple times in the netlist file.\n"), NAMEONPCB_NAME ((ElementTypePtr) LastPoint.ptr1), (LastPoint.type == PIN_TYPE) ? ((PinTypePtr) LastPoint.ptr2)-> Number : ((PadTypePtr) LastPoint.ptr2)->Number); else { connection = GetConnectionMemory (net); *connection = LastPoint; /* indicate expect net */ connection->menu = menu; /* mark as visited */ SET_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2); if (LastPoint.type == PIN_TYPE) ((PinTypePtr) LastPoint.ptr2)->Spare = (void *) menu; else ((PadTypePtr) LastPoint.ptr2)->Spare = (void *) menu; } } else badnet = true; /* check for more pins with the same number */ for (; SeekPad (entry, &LastPoint, true);) { connection = GetConnectionMemory (net); *connection = LastPoint; /* indicate expect net */ connection->menu = menu; /* mark as visited */ SET_FLAG (DRCFLAG, (PinTypePtr) LastPoint.ptr2); if (LastPoint.type == PIN_TYPE) ((PinTypePtr) LastPoint.ptr2)->Spare = (void *) menu; else ((PadTypePtr) LastPoint.ptr2)->Spare = (void *) menu; } } END_LOOP; } END_LOOP; } /* clear all visit marks */ ALLPIN_LOOP (PCB->Data); { CLEAR_FLAG (DRCFLAG, pin); } ENDALL_LOOP; ALLPAD_LOOP (PCB->Data); { CLEAR_FLAG (DRCFLAG, pad); } ENDALL_LOOP; return (Wantlist); }
static BOOL STM_Init(void) { stmbuf=NULL; if(!(mh_stm=(STMHEADER *)MyCalloc(1,sizeof(STMHEADER)))) return 0; return 1; }
static void do_list(struct Client *source_p, char *arg) { struct ListTask *lt = NULL; int no_masked_channels = 1; if (source_p->connection->list_task) { free_list_task(source_p); sendto_one_numeric(source_p, &me, RPL_LISTEND); return; } lt = MyCalloc(sizeof(struct ListTask)); lt->users_max = UINT_MAX; lt->created_max = UINT_MAX; lt->topicts_max = UINT_MAX; source_p->connection->list_task = lt; if (!EmptyString(arg)) { char *opt, *save = NULL; dlink_list *list = NULL; int i = 0, errors = 0; for (opt = strtoken(&save, arg, ","); opt; opt = strtoken(&save, NULL, ",")) { switch (*opt) { case '<': if ((i = atoi(opt + 1)) > 0) lt->users_max = (unsigned int)i - 1; else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->users_min = (unsigned int)i + 1; else errors = 1; break; case 'C': case 'c': switch (*++opt) { case '<': if ((i = atoi(opt + 1)) >= 0) lt->created_max = (unsigned int)(CurrentTime - 60 * i); else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->created_min = (unsigned int)(CurrentTime - 60 * i); else errors = 1; break; default: errors = 1; } break; case 'T': case 't': switch (*++opt) { case '<': if ((i = atoi(opt + 1)) >= 0) lt->topicts_min = (unsigned int)(CurrentTime - 60 * i); else errors = 1; break; case '>': if ((i = atoi(opt + 1)) >= 0) lt->topicts_max = (unsigned int)(CurrentTime - 60 * i); else errors = 1; break; case ':': if (strlcpy(lt->topic, opt + 1, sizeof(lt->topic)) == 0) errors = 1; break; default: errors = 1; } break; default: if (*opt == '!') { list = <->hide_mask; opt++; } else list = <->show_mask; if (has_wildcards(opt + !!IsChanPrefix(*opt))) { if (list == <->show_mask) no_masked_channels = 0; } else if (!IsChanPrefix(*opt)) errors = 1; if (!errors) dlinkAdd(xstrdup(opt), make_dlink_node(), list); } } if (errors) { free_list_task(source_p); sendto_one_numeric(source_p, &me, ERR_LISTSYNTAX); return; } } dlinkAdd(source_p, <->node, &listing_client_list); sendto_one_numeric(source_p, &me, RPL_LISTSTART); safe_list_channels(source_p, no_masked_channels && lt->show_mask.head != NULL); }
static BOOL XM_Init(void) { mh_xm=NULL; if(!(mh_xm=(XMHEADER *)MyCalloc(1,sizeof(XMHEADER)))) return 0; return 1; }
static BOOL MOD_Init(void) { patbuf=NULL; if(!(mh_mod=(MODULEHEADER *)MyCalloc(1,sizeof(MODULEHEADER)))) return 0; return 1; }
/* * init_netio * * This is a needed exported function which will be called to initialise * the network loop code. */ void init_netio(void) { pollfds_size = hard_fdlimit; pollfds = MyCalloc(sizeof(struct pollfd) * pollfds_size); }
} END_LOOP; DestNet->Style = SourceNet->Style; /* free the connection memory */ FreeNetMemory (SourceNet); /* remove SourceNet from its netlist */ *SourceNet = Netl->Net[--(Netl->NetN)]; /* zero out old garbage */ memset (&Netl->Net[Netl->NetN], 0, sizeof (NetType)); } static bool CheckShorts (LibraryMenuTypePtr theNet) { bool new, warn = false; PointerListTypePtr generic = MyCalloc (1, sizeof (PointerListType), "CheckShorts"); /* the first connection was starting point so * the menu is always non-null */ void **menu = GetPointerMemory (generic); *menu = theNet; ALLPIN_LOOP (PCB->Data); { if (TEST_FLAG (DRCFLAG, pin)) { warn = true; if (!pin->Spare) { Message (_("Warning! Net \"%s\" is shorted to %s pin %s\n"), &theNet->Name[2],
/*** CheckCPP will check if a preprocessor is available on the system *** *** this function will initialize MyOpen and must be run before the first *** *** call of MyOpen()!!! ***/ int CheckCPP() { int files[2], ofiles[2], ret, ok; pid_t pid; FILE *r, *w; char *cppenv; char buffer[512]; if((cppenv = getenv("CPP"))) TheScreen.cppcall = cppenv; else TheScreen.cppcall = CPP_CALL; recheck: /* ugly but undangerous in this case. */ if(pipe(files)) return(0); if(pipe(ofiles)) return(0); if(!(pid=fork())) { /* Child Process */ char *temp; temp = MyCalloc(strlen(TheScreen.cppcall) + 55, sizeof(char)); sprintf(temp, "%s -Dtest=toast - || while read t ; do echo ERROR ; done", TheScreen.cppcall); close(files[0]); close(ofiles[1]); fclose(stdout); if(STDOUT_FILENO != fcntl(files[1], F_DUPFD, STDOUT_FILENO)) exit(-1); close(files[1]); if(-1==fcntl(STDOUT_FILENO, F_SETFD, 0)) exit(-1); fclose(stdin); if(STDIN_FILENO != fcntl(ofiles[0], F_DUPFD, STDIN_FILENO)) exit(-1); close(ofiles[0]); if(-1 == fcntl(STDIN_FILENO, F_SETFD, 0)) exit(-1); execl("/bin/sh", "/bin/sh", "-c", temp, NULL); fprintf(TheScreen.errout,"UWM: couldn't start application: /bin/sh\n"); { char buf[16]; while(read(STDIN_FILENO, buf, 16)) ; } exit(-1); } close(files[1]); close(ofiles[0]); if(pid < 0) { close(files[0]); close(ofiles[1]); return(0); } if(!(r=fdopen(files[0],"r"))) { close(files[0]); return(0); } if(!(w=fdopen(ofiles[1],"w"))) { close(ofiles[1]); return(0); } fprintf(w,"preprocessor test\n"); fclose(w); ok=-1; while(fgets(buffer, 512, r)) if(strstr(buffer, "preprocessor toast")) ok = 0; waitpid(pid, &ret, 0); fclose(r); if(ret || ok) { if(cppenv) { cppenv = NULL; TheScreen.cppcall = CPP_CALL; goto recheck; } fprintf(TheScreen.errout, "UWM: looks like you don't have a working C preprocessor.\n"); TheScreen.cppcall = NULL; return(0); } return(-1); }
static void do_trace(struct Client *cptr, struct Client *sptr, int parc, char *parv[]) { int i; struct Client *acptr; struct Client *acptr2; const struct ConnectionClass* cl; char* tname; int doall; int *link_s; int *link_u; int cnt = 0; int wilds; int dow; if (parc < 2 || BadPtr(parv[1])) { /* just "TRACE" without parameters. Must be from local client */ parc = 1; acptr = &me; tname = cli_name(&me); i = HUNTED_ISME; } else if (parc < 3 || BadPtr(parv[2])) { /* No target specified. Make one before propagating. */ parc = 2; tname = parv[1]; if ((acptr = find_match_server(parv[1])) || ((acptr = FindClient(parv[1])) && !MyUser(acptr))) { if (IsUser(acptr)) parv[2] = cli_name(cli_user(acptr)->server); else parv[2] = cli_name(acptr); parc = 3; parv[3] = 0; if ((i = hunt_server_cmd(sptr, CMD_TRACE, cptr, IsServer(acptr), "%s :%C", 2, parc, parv)) == HUNTED_NOSUCH) return; } else i = HUNTED_ISME; } else { /* Got "TRACE <tname> :<target>" */ parc = 3; if (MyUser(sptr) || Protocol(cptr) < 10) acptr = find_match_server(parv[2]); else acptr = FindNServer(parv[2]); if ((i = hunt_server_cmd(sptr, CMD_TRACE, cptr, 0, "%s :%C", 2, parc, parv)) == HUNTED_NOSUCH) return; tname = parv[1]; } if (i == HUNTED_PASS) { if (!acptr) acptr = next_client(GlobalClientList, tname); else acptr = cli_from(acptr); send_reply(sptr, RPL_TRACELINK, version, debugmode, tname, acptr ? cli_name(cli_from(acptr)) : "<No_match>"); return; } doall = (parv[1] && (parc > 1)) ? !match(tname, cli_name(&me)) : 1; wilds = !parv[1] || strchr(tname, '*') || strchr(tname, '?'); dow = wilds || doall; /* Don't give (long) remote listings to lusers */ if (dow && !MyConnect(sptr) && !IsAnOper(sptr)) { send_reply(sptr, RPL_TRACEEND); return; } link_s = MyCalloc(2 * maxconnections, sizeof(link_s[0])); link_u = link_s + maxconnections; if (doall) { for (acptr = GlobalClientList; acptr; acptr = cli_next(acptr)) { if (IsUser(acptr)) link_u[cli_fd(cli_from(acptr))]++; else if (IsServer(acptr)) link_s[cli_fd(cli_from(acptr))]++; } } /* report all direct connections */ for (i = 0; i <= HighestFd; i++) { const char *conClass; if (!(acptr = LocalClientArray[i])) /* Local Connection? */ continue; if (IsInvisible(acptr) && dow && !(MyConnect(sptr) && IsOper(sptr)) && !IsAnOper(acptr) && (acptr != sptr)) continue; if (!doall && wilds && match(tname, cli_name(acptr))) continue; if (!dow && 0 != ircd_strcmp(tname, cli_name(acptr))) continue; conClass = get_client_class(acptr); switch (cli_status(acptr)) { case STAT_CONNECTING: send_reply(sptr, RPL_TRACECONNECTING, conClass, cli_name(acptr)); cnt++; break; case STAT_HANDSHAKE: send_reply(sptr, RPL_TRACEHANDSHAKE, conClass, cli_name(acptr)); cnt++; break; case STAT_ME: break; case STAT_UNKNOWN: case STAT_UNKNOWN_USER: send_reply(sptr, RPL_TRACEUNKNOWN, conClass, get_client_name(acptr, HIDE_IP)); cnt++; break; case STAT_UNKNOWN_SERVER: send_reply(sptr, RPL_TRACEUNKNOWN, conClass, "Unknown Server"); cnt++; break; case STAT_USER: /* Only opers see users if there is a wildcard but anyone can see all the opers. */ if ((IsAnOper(sptr) && (MyUser(sptr) || !(dow && IsInvisible(acptr)))) || !dow || IsAnOper(acptr)) { if (IsAnOper(acptr)) send_reply(sptr, RPL_TRACEOPERATOR, conClass, get_client_name(acptr, SHOW_IP), CurrentTime - cli_lasttime(acptr)); else send_reply(sptr, RPL_TRACEUSER, conClass, get_client_name(acptr, SHOW_IP), CurrentTime - cli_lasttime(acptr)); cnt++; } break; /* * Connection is a server * * Serv <class> <nS> <nC> <name> <ConnBy> <last> <age> * * class Class the server is in * nS Number of servers reached via this link * nC Number of clients reached via this link * name Name of the server linked * ConnBy Who established this link * last Seconds since we got something from this link * age Seconds this link has been alive * * Additional comments etc...... -Cym-<*****@*****.**> */ case STAT_SERVER: if (cli_serv(acptr)->user) { if (!cli_serv(acptr)->by[0] || !(acptr2 = findNUser(cli_serv(acptr)->by)) || (cli_user(acptr2) != cli_serv(acptr)->user)) acptr2 = NULL; send_reply(sptr, RPL_TRACESERVER, conClass, link_s[i], link_u[i], cli_name(acptr), acptr2 ? cli_name(acptr2) : "*", cli_serv(acptr)->user->username, cli_serv(acptr)->user->host, CurrentTime - cli_lasttime(acptr), CurrentTime - cli_serv(acptr)->timestamp); } else send_reply(sptr, RPL_TRACESERVER, conClass, link_s[i], link_u[i], cli_name(acptr), (*(cli_serv(acptr))->by) ? cli_serv(acptr)->by : "*", "*", cli_name(&me), CurrentTime - cli_lasttime(acptr), CurrentTime - cli_serv(acptr)->timestamp); cnt++; break; default: /* We actually shouldn't come here, -msa */ send_reply(sptr, RPL_TRACENEWTYPE, get_client_name(acptr, HIDE_IP)); cnt++; break; } } /* * Add these lines to summarize the above which can get rather long * and messy when done remotely - Avalon */ if (IsAnOper(sptr) && doall) { for (cl = get_class_list(); cl; cl = cl->next) { if (Links(cl) > 1) send_reply(sptr, RPL_TRACECLASS, ConClass(cl), Links(cl) - 1); } } send_reply(sptr, RPL_TRACEEND); MyFree(link_s); }