adv_error mouseb_event_init(int mouseb_id) { unsigned i; adv_bool eacces = 0; struct event_location map[EVENT_MOUSE_DEVICE_MAX]; unsigned mac; log_std(("mouseb:event: mouseb_event_init(id:%d)\n", mouseb_id)); #if defined(USE_SVGALIB) /* close the SVGALIB mouse device. SVGALIB always call mouse_init(), also */ /* if mouse input is not requested */ if (os_internal_svgalib_get()) { mouse_close(); } #endif log_std(("mouseb:event: opening mouse from 0 to %d\n", EVENT_MOUSE_DEVICE_MAX)); mac = event_locate(map, EVENT_MOUSE_DEVICE_MAX, &eacces); event_state.mac = 0; for(i=0;i<mac;++i) { int f; if (event_state.mac >= EVENT_MOUSE_MAX) continue; f = event_open(map[i].file, event_state.map[event_state.mac].evtype_bitmask, sizeof(event_state.map[event_state.mac].evtype_bitmask)); if (f == -1) { if (errno == EACCES) { eacces = 1; } continue; } if (!event_is_mouse(f, event_state.map[event_state.mac].evtype_bitmask)) { log_std(("mouseb:event: not a mouse on device %s\n", map[i].file)); event_close(f); continue; } if (mouseb_setup(&event_state.map[event_state.mac], f) != 0) { event_close(f); continue; } ++event_state.mac; } if (!event_state.mac) { if (eacces) error_set("No mouse found. Check the /dev/input/event* permissions.\n"); else error_set("No mouse found.\n"); return -1; } return 0; }
adv_error joystickb_event_init(int joystickb_id) { unsigned i; adv_bool eacces = 0; struct event_location map[EVENT_JOYSTICK_DEVICE_MAX]; unsigned mac; log_std(("josytickb:event: joystickb_event_init(id:%d)\n", joystickb_id)); log_std(("joystickb:event: opening joystick from 0 to %d\n", EVENT_JOYSTICK_DEVICE_MAX)); event_state.counter = 0; mac = event_locate(map, EVENT_JOYSTICK_DEVICE_MAX, &eacces); event_state.mac = 0; for(i=0;i<mac;++i) { int f; if (event_state.mac >= EVENT_JOYSTICK_MAX) continue; f = event_open(map[i].file, event_state.map[event_state.mac].evtype_bitmask, sizeof(event_state.map[event_state.mac].evtype_bitmask)); if (f == -1) { if (errno == EACCES) { eacces = 1; } continue; } if (!event_is_joystick(f, event_state.map[event_state.mac].evtype_bitmask)) { log_std(("joystickb:event: not a joystick on device %s\n", map[i].file)); event_close(f); continue; } if (joystickb_setup(&event_state.map[event_state.mac], f) != 0) { event_close(f); continue; } ++event_state.mac; } if (!event_state.mac) { if (eacces) error_set("No joystick found. Check the /dev/input/event* permissions.\n"); else error_set("No joystick found.\n"); return -1; } return 0; }
/* complete the connection to the IRC server */ static unsigned int connectirc2(res_addrinfo_t *remote) { int retval; int family; if (remote->ai_reset) gnetwork->serv_resolv.next = 0; family = remote->ai_addr.sa_family; gnetwork->ircserver = socket(family, remote->ai_socktype, remote->ai_protocol); if (gnetwork->ircserver < 0) { outerror(OUTERROR_TYPE_WARN_LOUD, "Socket Error: %s", strerror(errno)); return 1; } if (gdata.debug > 0) { char *msg; msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &(remote->ai_addr)); ioutput(OUT_S, COLOR_YELLOW, "Connecting to %s", msg); mydelete(msg); } if (bind_irc_vhost(family, gnetwork->ircserver) != 0) { outerror(OUTERROR_TYPE_WARN_LOUD, "Couldn't Bind To Virtual Host"); event_close(gnetwork->ircserver); return 1; } if (set_socket_nonblocking(gnetwork->ircserver, 1) < 0 ) outerror(OUTERROR_TYPE_WARN, "Couldn't Set Non-Blocking"); alarm(CTIMEOUT); retval = connect(gnetwork->ircserver, &(remote->ai_addr), remote->ai_addrlen); if ( (retval < 0) && !((errno == EINPROGRESS) || (errno == EAGAIN)) ) { outerror(OUTERROR_TYPE_WARN_LOUD, "Connection to Server Failed: %s", strerror(errno)); alarm(0); event_close(gnetwork->ircserver); return 1; } alarm(0); if (gdata.debug > 0) { ioutput(OUT_S, COLOR_YELLOW, "ircserver socket = %d", gnetwork->ircserver); } gnetwork->lastservercontact=gdata.curtime; /* good */ gnetwork->serverstatus = SERVERSTATUS_TRYING; return 0; }
static int stop_workers(lsx_thread_state_t *state) { int n; for (n = 0; n < state->count ; ++n) state->pth[n].done = sox_true; if (fire_and_wait_workers(state, sox_true) < 0) return -1; for (n = 0; n < state->count; ++n) { per_thread_state_t *ts = &state->pth[n]; if (ts->evpro) event_close(ts->evpro); if (ts->evcon) event_close(ts->evcon); memset(ts, 0, sizeof(per_thread_state_t)); } return 0; }
/* * Tests that the L3 bank handling is correct. We fixed it in commit e9aaac1. */ static int l3_bank_test(void) { struct event event; char *p; int i; p = malloc(MALLOC_SIZE); FAIL_IF(!p); event_init(&event, 0x84918F); FAIL_IF(event_open(&event)); for (i = 0; i < MALLOC_SIZE; i += 0x10000) p[i] = i; event_read(&event); event_report(&event); FAIL_IF(event.result.running == 0); FAIL_IF(event.result.enabled == 0); event_close(&event); free(p); return 0; }
void regmac_event(struct SQDB *sqdb, unsigned event_type, const unsigned char *bssid, const unsigned char *mac_address, unsigned frame_type, struct NetFrame *frame) { struct SQDB_SubStation *sta; struct SQDB_AccessPoint *ap; struct SQDB_Event *event; time_t timestamp = sqdb->kludge.time_stamp; pixie_enter_critical_section(sqdb->cs); ap = sqdb_create_bssid(sqdb, bssid); sta = sqdb_lookup_substation(sqdb, mac_address, bssid); /* If the existing event doesn't match this, then we need to close it */ if (sta->current_event && sta->current_event->type != event_type) { event_close(sqdb, sta->current_event); } /* If there is no current event, create one */ if (sta->current_event == NULL) event_new(sqdb, sta, ap, sqdb->kludge.time_stamp, event_type); event = sta->current_event; /* update latest time */ if (event->time_last < timestamp) event->time_last = timestamp; /* Do different logic, depending on the event type */ event_update_packet(event, frame_type, frame); pixie_leave_critical_section(sqdb->cs); }
/* Tests that fork clears EBB state */ int fork_cleanup(void) { pid_t pid; event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); FAIL_IF(event_open(&event)); ebb_enable_pmc_counting(1); setup_ebb_handler(standard_ebb_callee); ebb_global_enable(); FAIL_IF(ebb_event_enable(&event)); mtspr(SPRN_MMCR0, MMCR0_FC); mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); /* Don't need to actually take any EBBs */ pid = fork(); if (pid == 0) exit(child()); /* Child does the actual testing */ FAIL_IF(wait_for_child(pid)); /* After fork */ event_close(&event); return 0; }
void setupdccchataccept(dccchat_t *chat) { SIGNEDSOCK int addrlen; char *msg; updatecontext(); addrlen = sizeof(struct sockaddr_in); if ((chat->con.clientsocket = accept(chat->con.listensocket, &(chat->con.remote.sa), &addrlen)) < 0) { outerror(OUTERROR_TYPE_WARN,"Accept Error, Aborting: %s",strerror(errno)); event_close(chat->con.listensocket); chat->con.clientsocket = FD_UNUSED; chat->con.listensocket = FD_UNUSED; return; } ir_listen_port_connected(chat->con.localport); event_close(chat->con.listensocket); chat->con.listensocket = FD_UNUSED; ioutput(OUT_S|OUT_L|OUT_D, COLOR_MAGENTA, "DCC CHAT connection received, authenticating"); if (set_socket_nonblocking(chat->con.clientsocket, 1) < 0 ) { outerror(OUTERROR_TYPE_WARN,"Couldn't Set Non-Blocking"); } if (is_in_badip(&(chat->con.remote))) { shutdowndccchat(chat, 0); return; } chat->status = DCCCHAT_AUTHENTICATING; chat->con.connecttime = gdata.curtime; chat->con.lastcontact = gdata.curtime; ir_boutput_init(&chat->boutput, chat->con.clientsocket, 0); msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &(chat->con.remote.sa)); chat->con.remoteaddr = mystrdup(msg); mydelete(msg); setup_chat_banner(chat); }
void mouseb_event_done(void) { unsigned i; log_std(("mouseb:event: mouseb_event_done()\n")); for(i=0;i<event_state.mac;++i) event_close(event_state.map[i].f); event_state.mac = 0; }
void joystickb_event_done(void) { unsigned i; log_std(("josytickb:event: joystickb_event_done()\n")); for(i=0;i<event_state.mac;++i) event_close(event_state.map[i].f); event_state.mac = 0; }
/* close an TCP connection safely */ void shutdown_close(int handle) { /* * cygwin close() is broke, if outstanding data is present * it will block until the TCP connection is dead, sometimes * upto 10-20 minutes, calling shutdown() first seems to help */ shutdown(handle, SHUT_RDWR); event_close(handle); }
/* close all telnet interfaces */ void telnet_close_listen(void) { unsigned int i; for (i=0; i<MAX_VHOSTS; ++i) { if (telnet_listen[i] != FD_UNUSED) { event_close(telnet_listen[i]); telnet_listen[i] = FD_UNUSED; } } }
static int no_handler_test(void) { struct event event; u64 val; int i; SKIP_IF(!ebb_is_supported()); event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); event.attr.exclude_kernel = 1; event.attr.exclude_hv = 1; event.attr.exclude_idle = 1; FAIL_IF(event_open(&event)); FAIL_IF(ebb_event_enable(&event)); val = mfspr(SPRN_EBBHR); FAIL_IF(val != 0); /* Make sure it overflows quickly */ sample_period = 1000; mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); /* Spin to make sure the event has time to overflow */ for (i = 0; i < 1000; i++) mb(); dump_ebb_state(); /* We expect to see the PMU frozen & PMAO set */ val = mfspr(SPRN_MMCR0); FAIL_IF(val != 0x0000000080000080); event_close(&event); dump_ebb_state(); /* The real test is that we never took an EBB at 0x0 */ return 0; }
int back_to_back_ebbs(void) { struct event event; event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); event.attr.exclude_kernel = 1; event.attr.exclude_hv = 1; event.attr.exclude_idle = 1; FAIL_IF(event_open(&event)); setup_ebb_handler(ebb_callee); FAIL_IF(ebb_event_enable(&event)); sample_period = 5; ebb_freeze_pmcs(); mtspr(SPRN_PMC1, pmc_sample_period(sample_period)); ebb_global_enable(); ebb_unfreeze_pmcs(); while (ebb_state.stats.ebb_count < NUMBER_OF_EBBS) FAIL_IF(core_busy_loop()); ebb_global_disable(); ebb_freeze_pmcs(); count_pmc(1, sample_period); dump_ebb_state(); event_close(&event); FAIL_IF(ebb_state.stats.ebb_count != NUMBER_OF_EBBS); return 0; }
void t_establishcon (transfer * const t) { SIGNEDSOCK int addrlen; updatecontext(); addrlen = (t->con.family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); if ((t->con.clientsocket = accept(t->con.listensocket, &t->con.local.sa, &addrlen)) < 0) { int errno2 = errno; outerror(OUTERROR_TYPE_WARN, "Accept Error, Aborting: %s", strerror(errno)); t_closeconn(t, "Connection Error, Try Again", errno2); return; } ir_listen_port_connected(t->con.localport); event_close(t->con.listensocket); t->con.listensocket = FD_UNUSED; t_setup_send(t); }
/* Tests we can setup an EBB on our child - if it's expecting it */ int ebb_on_willing_child(void) { union pipe read_pipe, write_pipe; struct event event; pid_t pid; FAIL_IF(pipe(read_pipe.fds) == -1); FAIL_IF(pipe(write_pipe.fds) == -1); pid = fork(); if (pid == 0) { /* NB order of pipes looks reversed */ exit(victim_child(write_pipe, read_pipe)); } /* Signal the child to setup its EBB handler */ FAIL_IF(sync_with_child(read_pipe, write_pipe)); /* Child is running now */ event_init_named(&event, 0x1001e, "cycles"); event_leader_ebb_init(&event); event.attr.exclude_kernel = 1; event.attr.exclude_hv = 1; event.attr.exclude_idle = 1; FAIL_IF(event_open_with_pid(&event, pid)); FAIL_IF(ebb_event_enable(&event)); /* Child show now take EBBs and then exit */ FAIL_IF(wait_for_child(pid)); event_close(&event); return 0; }
/* accept incoming connection */ static void l_setup_accept(upload * const l) { SIGNEDSOCK int addrlen; char *msg; updatecontext(); addrlen = sizeof(l->con.remote); if ((l->con.clientsocket = accept(l->con.listensocket, &(l->con.remote.sa), &addrlen)) < 0) { outerror(OUTERROR_TYPE_WARN, "Accept Error, Aborting: %s", strerror(errno)); l->con.clientsocket = FD_UNUSED; l_closeconn(l, "Connection Lost", 0); return; } ir_listen_port_connected(l->con.localport); event_close(l->con.listensocket); l->con.listensocket = FD_UNUSED; ioutput(OUT_S|OUT_L|OUT_D, COLOR_MAGENTA, "DCC SEND connection received"); ir_setsockopt(l->con.clientsocket); notice(l->nick, "DCC Send Accepted, Connecting..."); msg = mymalloc(maxtextlength); my_getnameinfo(msg, maxtextlength -1, &(l->con.remote.sa)); mydelete(l->con.remoteaddr); l->con.remoteaddr = mystrdup(msg); mydelete(msg); l->con.remoteport = get_port(&(l->con.remote)); l->con.connecttime = gdata.curtime; l->con.lastcontact = gdata.curtime; l->ul_status = UPLOAD_STATUS_GETTING; }
static void mainloop (void) { /* data is persistant across calls */ static struct timeval timestruct; static int changequartersec, changesec, changemin, changehour; static time_t lasttime, lastmin, lasthour, last4sec, last5sec, last20sec; static time_t lastautoadd; static time_t last3min, last2min, lastignoredec; static int first_loop = 1; static ir_uint64 last250ms; userinput *pubplist; userinput *urehash; ir_uint64 xdccsent; unsigned int i; int highests; unsigned int ss; upload *ul; transfer *tr; channel_t *ch; xdcc *xd; dccchat_t *chat; updatecontext(); gnetwork = NULL; if (first_loop) { /* init if first time called */ FD_ZERO(&gdata.readset); FD_ZERO(&gdata.writeset); changehour=changemin=changesec=changequartersec=0; gettimeofday(×truct, NULL); last250ms = gdata.curtimems; gdata.curtimems = timeval_to_ms(×truct); ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "Startup" " running: %ld ms", (long)(gdata.curtimems - last250ms)); gdata.curtime = timestruct.tv_sec; lasttime=gdata.curtime; last250ms = gdata.curtimems; lastmin=(lasttime/60)-1; lasthour=(lasttime/60/60)-1; last4sec = last5sec = last20sec = last2min = last3min = lasttime; lastignoredec = lasttime; for (ss=0; ss<gdata.networks_online; ss++) { gdata.networks[ss].lastnotify = lasttime; gdata.networks[ss].lastslow = lasttime; gdata.networks[ss].server_input_line[0] = '\0'; } gdata.cursendptr = 0; lastautoadd = gdata.curtime + 60; first_loop = 0; } updatecontext(); FD_ZERO(&gdata.readset); FD_ZERO(&gdata.writeset); FD_ZERO(&gdata.execset); highests = 0; #ifdef USE_CURL fetch_multi_fdset(&gdata.readset, &gdata.writeset, &gdata.execset, &highests); #endif /* USE_CURL */ highests = irc_select(highests); if (!gdata.background) { FD_SET(fileno(stdin), &gdata.readset); highests = max2(highests, fileno(stdin)); } highests = chat_select_fdset(highests); highests = t_select_fdset(highests, changequartersec); highests = l_select_fdset(highests, changequartersec); #ifndef WITHOUT_TELNET highests = telnet_select_fdset(highests); #endif /* WITHOUT_TELNET */ #ifndef WITHOUT_HTTP highests = h_select_fdset(highests, changequartersec); #endif /* WITHOUT_HTTP */ if (gdata.md5build.file_fd != FD_UNUSED) { assert(gdata.md5build.xpack); FD_SET(gdata.md5build.file_fd, &gdata.readset); highests = max2(highests, gdata.md5build.file_fd); } updatecontext(); if (gdata.debug > 81) { select_dump("try", highests); } if (gdata.attop) gotobot(); tostdout_write(); gettimeofday(×truct, NULL); gdata.selecttimems = timeval_to_ms(×truct); if (ir_kqueue_select(highests+1, &gdata.readset, &gdata.writeset, &gdata.execset) < 0) { if (errno != EINTR) { outerror(OUTERROR_TYPE_WARN,"Select returned an error: %s",strerror(errno)); usleep(10000); /* prevent fast spinning */ } /* data is undefined on error, zero and continue */ FD_ZERO(&gdata.readset); FD_ZERO(&gdata.writeset); FD_ZERO(&gdata.execset); } if (gdata.debug > 81) { select_dump("got", highests); } /*----- one second check ----- */ updatecontext(); if (gettimeofday(×truct, NULL) < 0) { outerror(OUTERROR_TYPE_CRASH,"gettimeofday() failed! %s\n",strerror(errno)); } gdata.curtimems = timeval_to_ms(×truct); gdata.curtime = timestruct.tv_sec; if (gdata.curtimems > gdata.selecttimems + 1000) outerror(OUTERROR_TYPE_WARN, "Iroffer was blocked for %lims", (long)(gdata.curtimems - gdata.selecttimems)); /* adjust for drift and cpu usage */ if ((gdata.curtimems > (last250ms+1000)) || (gdata.curtimems < last250ms)) { /* skipped forward or backwards, correct */ last250ms = gdata.curtimems-250; } if (gdata.curtimems >= (last250ms+250)) { changequartersec = 1; /* note bandwidth limiting requires no drift! */ last250ms += 250; } else { changequartersec = 0; } changesec = 0; if (gdata.curtime != lasttime) { if (gdata.curtime < lasttime - MAX_WAKEUP_WARN) { outerror(OUTERROR_TYPE_WARN, "System Time Changed Backwards %lim %lis!!\n", (long)(lasttime-gdata.curtime)/60, (long)(lasttime-gdata.curtime)%60); } if (gdata.curtime > lasttime + MAX_WAKEUP_WARN) { outerror(OUTERROR_TYPE_WARN, "System Time Changed Forward or Mainloop Skipped %lim %lis!!\n", (long)(gdata.curtime-lasttime)/60, (long)(gdata.curtime-lasttime)%60); if (gdata.debug > 0) { dump_slow_context(); } } if (gdata.curtime > lasttime + MAX_WAKEUP_ERR) { outerror(OUTERROR_TYPE_WARN, "System Time Changed Forward or Mainloop Skipped %lim %lis!!\n", (long)(gdata.curtime-lasttime)/60, (long)(gdata.curtime-lasttime)%60); if (gdata.debug > 0) { dumpcontext(); } } lasttime = gdata.curtime; changesec = 1; } if (changesec && lasttime/60/60 != lasthour) { lasthour = lasttime/60/60; changehour = 1; } if (changesec && lasttime/60 != lastmin) { lastmin = lasttime/60; changemin = 1; } if (gdata.needsshutdown) { gdata.needsshutdown = 0; shutdowniroffer(); } if (gdata.needsreap) { gdata.needsreap = 0; irc_resolved(); } #ifdef USE_CURL fetch_perform(); #endif /* USE_CURL */ updatecontext(); if (changesec) { gdata.totaluptime++; gdata.xdccsent[(gdata.curtime+1)%XDCC_SENT_SIZE] = 0; gdata.xdccrecv[(gdata.curtime+1)%XDCC_SENT_SIZE] = 0; xdccsent = 0; for (i=0; i<XDCC_SENT_SIZE; i++) xdccsent += (ir_uint64)gdata.xdccsum[i]; if (((float)xdccsent)/XDCC_SENT_SIZE/1024.0 > gdata.sentrecord) gdata.sentrecord = ((float)xdccsent)/XDCC_SENT_SIZE/1024.0; gdata.xdccsum[(gdata.curtime+1)%XDCC_SENT_SIZE] = 0; run_delayed_jobs(); } updatecontext(); /*----- see if anything waiting on console ----- */ gdata.needsclear = 0; if (!gdata.background && FD_ISSET(fileno(stdin), &gdata.readset)) parseconsole(); irc_perform(changesec); l_perform(changesec); chat_perform(); t_perform(changesec, changequartersec); #ifndef WITHOUT_TELNET telnet_perform(); #endif /* WITHOUT_TELNET */ #ifndef WITHOUT_HTTP h_perform(changesec, changequartersec); #endif /* WITHOUT_HTTP */ /*----- time for a delayed shutdown? ----- */ if (changesec && gdata.delayedshutdown) { if (!irlist_size(&gdata.trans)) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "Delayed Shutdown Activated, No Transfers Remaining"); shutdowniroffer(); } } updatecontext(); for (ss=0; ss<gdata.networks_online; ss++) { gnetwork = &(gdata.networks[ss]); /*----- send server stuff ----- */ if (changesec) { sendserver(); if (gdata.curtime%INAMNT_SIZE == (INAMNT_SIZE-1)) gnetwork->inamnt[0] = 0; else gnetwork->inamnt[gdata.curtime%INAMNT_SIZE+1] = 0; } /*----- see if we can send out some xdcc lists */ if (changesec && gnetwork->serverstatus == SERVERSTATUS_CONNECTED) { if (!irlist_size((&gnetwork->serverq_normal)) && !irlist_size(&(gnetwork->serverq_slow))) sendxdlqueue(); } } gnetwork = NULL; /*----- see if its time to change maxb */ if (changehour) { gdata.maxb = gdata.overallmaxspeed; if (gdata.overallmaxspeeddayspeed != gdata.overallmaxspeed) { struct tm *localt; localt = localtime(&gdata.curtime); if ((unsigned int)localt->tm_hour >= gdata.overallmaxspeeddaytimestart && (unsigned int)localt->tm_hour < gdata.overallmaxspeeddaytimeend && ( gdata.overallmaxspeeddaydays & (1 << (unsigned int)localt->tm_wday)) ) gdata.maxb = gdata.overallmaxspeeddayspeed; } isrotatelog(); expire_options(); } /*----- see if we've hit a transferlimit or need to reset counters */ if (changesec) { unsigned int ii; unsigned int transferlimits_over = 0; for (ii=0; ii<NUMBER_TRANSFERLIMITS; ii++) { /* reset counters? */ if ((!gdata.transferlimits[ii].ends) || (gdata.transferlimits[ii].ends < gdata.curtime)) { struct tm *localt; if (gdata.transferlimits[ii].limit && gdata.transferlimits[ii].ends) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "Resetting %s transfer limit, used %" LLPRINTFMT "uMB of the %" LLPRINTFMT "uMB limit", transferlimit_type_to_string(ii), gdata.transferlimits[ii].used / 1024 / 1024, gdata.transferlimits[ii].limit / 1024 / 1024); } /* find our next end time */ localt = localtime(&gdata.curtime); localt->tm_sec = localt->tm_min = localt->tm_hour = 0; /* midnight */ switch (ii) { case TRANSFERLIMIT_DAILY: /* tomorrow */ localt->tm_mday++; break; case TRANSFERLIMIT_WEEKLY: /* next sunday morning */ localt->tm_mday += 7 - localt->tm_wday; break; case TRANSFERLIMIT_MONTHLY: /* next month */ localt->tm_mday = gdata.start_of_month; localt->tm_mon++; break; default: outerror(OUTERROR_TYPE_CRASH, "unknown type %u", ii); } /* tm_wday and tm_yday are ignored in mktime() */ gdata.transferlimits[ii].ends = mktime(localt); gdata.transferlimits[ii].used = 0; if ( ii == TRANSFERLIMIT_DAILY ) reset_download_limits(); } if (!transferlimits_over && gdata.transferlimits[ii].limit && (gdata.transferlimits[ii].used >= gdata.transferlimits[ii].limit)) { transferlimits_over = 1 + ii; if (!gdata.transferlimits_over) { char *tempstr = transfer_limit_exceeded_msg(ii); ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "All %" LLPRINTFMT "uMB of the %s transfer limit used. Stopping transfers.", gdata.transferlimits[ii].limit / 1024 / 1024, transferlimit_type_to_string(ii)); /* remove queued users */ queue_all_remove(&gdata.mainqueue, tempstr); queue_all_remove(&gdata.idlequeue, tempstr); /* stop transfers */ for (tr = irlist_get_head(&gdata.trans); tr; tr = irlist_get_next(tr)) { if (tr->tr_status != TRANSFER_STATUS_DONE) { gnetwork = &(gdata.networks[tr->net]); t_closeconn(tr,tempstr,0); } } gnetwork = NULL; mydelete(tempstr); } } } if (gdata.transferlimits_over != transferlimits_over) { if (!transferlimits_over) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "No longer over any transfer limits. Transfers are now allowed."); } gdata.transferlimits_over = transferlimits_over; } } /*----- gdata.autoignore_threshold seconds ----- */ if (changesec && ((unsigned)gdata.curtime > (lastignoredec + gdata.autoignore_threshold))) { igninfo *ignore; lastignoredec += gdata.autoignore_threshold; ignore = irlist_get_head(&gdata.ignorelist); while(ignore) { ignore->bucket--; if ((ignore->flags & IGN_IGNORING) && (ignore->bucket == 0)) { ignore->flags &= ~IGN_IGNORING; ioutput(OUT_S|OUT_L|OUT_D, COLOR_NO_COLOR, "Ignore removed for %s",ignore->hostmask); write_statefile(); } if (ignore->bucket == 0) { mydelete(ignore->hostmask); ignore = irlist_delete(&gdata.ignorelist, ignore); } else { ignore = irlist_get_next(ignore); } } } /*----- periodicmsg_time seconds ----- */ if (changesec) { send_periodicmsg(); } updatecontext(); /*----- 5 seconds ----- */ if (changesec && (gdata.curtime - last5sec > 4)) { last5sec = gdata.curtime; updatecontext(); /*----- server timeout ----- */ for (ss=0; ss<gdata.networks_online; ss++) { gnetwork = &(gdata.networks[ss]); if (gdata.needsshutdown) continue; if ((gnetwork->serverstatus == SERVERSTATUS_CONNECTED) && (gdata.curtime > gnetwork->lastservercontact + SRVRTOUT)) { if (gnetwork->servertime < 3) { const char *servname = gnetwork->curserveractualname ? gnetwork->curserveractualname : gnetwork->curserver.hostname; size_t len = 6 + strlen(servname); char *tempstr3 = mymalloc(len + 1); snprintf(tempstr3, len + 1, "PING %s\n", servname); writeserver_ssl(tempstr3, len); if (gdata.debug > 0) { tempstr3[len-1] = '\0'; len--; ioutput(OUT_S, COLOR_MAGENTA, "<NORES<: %s", tempstr3); } mydelete(tempstr3); gnetwork->servertime++; } else if (gnetwork->servertime == 3) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_RED, "Closing Server Connection on %s: No Response for %u minutes.", gnetwork->name, SRVRTOUT/60); close_server(); gnetwork->servertime = 0; } } /*----- ping server ----- */ if (gnetwork->recentsent) { pingserver(); gnetwork->recentsent--; } } } /* networks */ gnetwork = NULL; /*----- 4 seconds ----- */ if (changesec && (gdata.curtime - last4sec > 3)) { /*----- update lastspeed, check minspeed ----- */ tr = irlist_get_head(&gdata.trans); while(tr) { if ( tr->con.connecttime+(MIN_TL/2) > gdata.curtime ) /* initial */ { tr->lastspeed = (tr->lastspeed)*DCL_SPDW_I + (((float)(tr->bytessent-tr->lastspeedamt))/1024.0)*(1.0-DCL_SPDW_I)/((float)(gdata.curtime-last4sec)*1.0); } else /* ongoing */ { tr->lastspeed = (tr->lastspeed)*DCL_SPDW_O + (((float)(tr->bytessent-tr->lastspeedamt))/1024.0)*(1.0-DCL_SPDW_O)/((float)(gdata.curtime-last4sec)*1.0); } tr->lastspeedamt = tr->bytessent; t_checkminspeed(tr); tr = irlist_get_next(tr); } ul = irlist_get_head(&gdata.uploads); while(ul) { if ( ul->con.connecttime+(MIN_TL/2) > gdata.curtime ) /* initial */ { ul->lastspeed = (ul->lastspeed)*DCL_SPDW_I + (((float)(ul->bytesgot-ul->lastspeedamt))/1024.0)*(1.0-DCL_SPDW_I)/((float)(gdata.curtime-last4sec)*1.0); } else /* ongoing */ { ul->lastspeed = (ul->lastspeed)*DCL_SPDW_O + (((float)(ul->bytesgot-ul->lastspeedamt))/1024.0)*(1.0-DCL_SPDW_O)/((float)(gdata.curtime-last4sec)*1.0); } ul->lastspeedamt = ul->bytesgot; ul = irlist_get_next(ul); } last4sec = gdata.curtime; } updatecontext(); /*----- check for size change ----- */ if (changesec) checktermsize(); updatecontext(); for (ss=0; ss<gdata.networks_online; ss++) { gnetwork = &(gdata.networks[ss]); /*----- plist stuff ----- */ if ((gnetwork->serverstatus == SERVERSTATUS_CONNECTED) && changemin && irlist_size(&gdata.xdccs) && !gdata.transferlimits_over && (irlist_size(&(gnetwork->serverq_channel)) < irlist_size(&gdata.xdccs)) && (!gdata.queuesize || irlist_size(&gdata.mainqueue) < gdata.queuesize) && (gdata.nolisting <= gdata.curtime)) { char *tchanf = NULL, *tchanm = NULL, *tchans = NULL; for(ch = irlist_get_head(&(gnetwork->channels)); ch; ch = irlist_get_next(ch)) { if ((ch->flags & CHAN_ONCHAN) && (ch->nextann < gdata.curtime) && ch->plisttime && (((gdata.curtime / 60) % ch->plisttime) == ch->plistoffset)) { ch->nextmsg = gdata.curtime + ch->delay; if (ch->pgroup != NULL) { ioutput(OUT_S|OUT_D, COLOR_NO_COLOR, "Plist sent to %s (pgroup)", ch->name); pubplist = mycalloc(sizeof(userinput)); pubplist->method = method_xdl_channel; pubplist->net = gnetwork->net; pubplist->level = ADMIN_LEVEL_PUBLIC; a_fillwith_plist(pubplist, ch->name, ch); u_parseit(pubplist); mydelete(pubplist); continue; } if (ch->flags & CHAN_MINIMAL) { if (tchanm) { strncat(tchanm,",",maxtextlength-strlen(tchanm)-1); strncat(tchanm,ch->name,maxtextlength-strlen(tchanm)-1); } else { tchanm = mymalloc(maxtextlength); strncpy(tchanm,ch->name,maxtextlength-1); } } else if (ch->flags & CHAN_SUMMARY) { if (tchans) { strncat(tchans,",",maxtextlength-strlen(tchans)-1); strncat(tchans,ch->name,maxtextlength-strlen(tchans)-1); } else { tchans = mymalloc(maxtextlength); strncpy(tchans,ch->name,maxtextlength-1); } } else { if (tchanf) { strncat(tchanf,",",maxtextlength-strlen(tchanf)-1); strncat(tchanf,ch->name,maxtextlength-strlen(tchanf)-1); } else { tchanf = mymalloc(maxtextlength); strncpy(tchanf,ch->name,maxtextlength-1); } } } } if (tchans) { if (gdata.restrictprivlist && !gdata.creditline && !irlist_size(&gdata.headline)) { ioutput(OUT_S|OUT_D, COLOR_NO_COLOR, "Can't send Summary Plist to %s (restrictprivlist is set and no creditline or headline, summary makes no sense!)", tchans); } else { ioutput(OUT_S|OUT_D, COLOR_NO_COLOR, "Plist sent to %s (summary)", tchans); pubplist = mycalloc(sizeof(userinput)); a_fillwith_msg2(pubplist, tchans, "XDL"); pubplist->method = method_xdl_channel_sum; u_parseit(pubplist); mydelete(pubplist); } mydelete(tchans); } if (tchanf) { ioutput(OUT_S|OUT_D, COLOR_NO_COLOR, "Plist sent to %s (full)", tchanf); pubplist = mycalloc(sizeof(userinput)); a_fillwith_plist(pubplist, tchanf, NULL); pubplist->method = method_xdl_channel; u_parseit(pubplist); mydelete(pubplist); mydelete(tchanf); } if (tchanm) { ioutput(OUT_S|OUT_D, COLOR_NO_COLOR, "Plist sent to %s (minimal)", tchanm); pubplist = mycalloc(sizeof(userinput)); a_fillwith_msg2(pubplist, tchanm, "XDL"); pubplist->method = method_xdl_channel_min; u_parseit(pubplist); mydelete(pubplist); mydelete(tchanm); } } } /* networks */ gnetwork = NULL; updatecontext(); /*----- low bandwidth send, save state file ----- */ if (changesec && (gdata.curtime - last3min > 180)) { last3min = gdata.curtime; xdccsent = 0; for (i=0; i<XDCC_SENT_SIZE; i++) xdccsent += (ir_uint64)gdata.xdccsent[i]; xdccsent /= XDCC_SENT_SIZE*1024; if ((xdccsent < (unsigned)gdata.lowbdwth) && !gdata.exiting && irlist_size(&gdata.mainqueue) && (irlist_size(&gdata.trans) < gdata.maxtrans)) { check_idle_queue(0); send_from_queue(1, 0, NULL); } write_files(); } updatecontext(); for (ss=0; ss<gdata.networks_online; ss++) { gnetwork = &(gdata.networks[ss]); /*----- queue notify ----- */ if (changesec && gdata.notifytime && (!gdata.quietmode) && ((unsigned)gdata.curtime > (gnetwork->lastnotify + (gdata.notifytime*60)))) { gnetwork->lastnotify = gdata.curtime; if (gnetwork->serverstatus == SERVERSTATUS_CONNECTED) { if ((irlist_size(&(gnetwork->serverq_fast)) >= 10) || (irlist_size(&(gnetwork->serverq_normal)) >= 10) || (irlist_size(&(gnetwork->serverq_slow)) >= 50)) { ioutput(OUT_S|OUT_D|OUT_L, COLOR_NO_COLOR, "notifications skipped on %s, server queue is rather large", gnetwork->name); } else { notifyqueued(); notifybandwidth(); notifybandwidthtrans(); } } } } /* networks */ gnetwork = NULL; updatecontext(); /*----- log stats / remote admin stats ----- */ if ( changesec && ((unsigned)gdata.curtime >= (last2min + gdata.status_time_dcc_chat))) { last2min = gdata.curtime; if (gdata.logstats) { logstat(); chat_writestatus(); } } updatecontext(); /* look to see if any files changed */ if (changesec) look_for_file_remove(); updatecontext(); /*----- 20 seconds ----- */ if (changesec && (gdata.curtime - last20sec > 19)) { expire_badip(); if (gdata.logfd != FD_UNUSED) { /* cycle */ close(gdata.logfd); gdata.logfd = FD_UNUSED; } updatecontext(); for (ss=0; ss<gdata.networks_online; ss++) { gnetwork = &(gdata.networks[ss]); /* try rejoining channels not on */ ch = irlist_get_head(&(gnetwork->channels)); while(ch) { if ((gnetwork->serverstatus == SERVERSTATUS_CONNECTED) && !(ch->flags & CHAN_ONCHAN)) { joinchannel(ch); } ch = irlist_get_next(ch); } } /* networks */ gnetwork = NULL; last20sec = gdata.curtime; updatecontext(); for (ss=0; ss<gdata.networks_online; ss++) { gnetwork = &(gdata.networks[ss]); /* try to regain nick */ if (!gnetwork->user_nick || strcmp(get_config_nick(), gnetwork->user_nick)) { writeserver(WRITESERVER_NORMAL, "NICK %s", get_config_nick()); } } /* networks */ gnetwork = NULL; updatecontext(); /* update status line */ if (!gdata.background && !gdata.noscreen) { char tempstr[maxtextlength]; char tempstr2[maxtextlengthshort]; if (gdata.attop) gotobot(); tostdout(IRVT_SAVE_CURSOR); getstatusline(tempstr,maxtextlength); tempstr[min2(maxtextlength-2,gdata.termcols-4)] = '\0'; snprintf(tempstr2, maxtextlengthshort, IRVT_CURSOR_HOME1 "[ %%-%us ]", gdata.termlines - 1, gdata.termcols - 4); tostdout(tempstr2,tempstr); tostdout(IRVT_CURSOR_HOME2 IRVT_UNSAVE_CURSOR, gdata.termlines, gdata.termcols); } admin_jobs(); #ifdef USE_RUBY rehash_myruby(1); #endif /* USE_RUBY */ delayed_announce(); } updatecontext(); if (changemin) { reverify_restrictsend(); update_hour_dinoex(lastmin); check_idle_queue(0); clean_uploadhost(); auto_rehash(); } updatecontext(); if ((gdata.md5build.file_fd != FD_UNUSED) && FD_ISSET(gdata.md5build.file_fd, &gdata.readset)) { ssize_t howmuch; #if defined(_OS_CYGWIN) int reads_per_loop = 32; #else /* _OS_CYGWIN */ int reads_per_loop = 64; #endif /* _OS_CYGWIN */ assert(gdata.md5build.xpack); while (reads_per_loop--) { howmuch = read(gdata.md5build.file_fd, gdata.sendbuff, BUFFERSIZE); if (gdata.debug >30) { ioutput(OUT_S, COLOR_YELLOW, "MD5: [Pack %u] read %ld", number_of_pack(gdata.md5build.xpack), (long)howmuch); } if ((howmuch < 0) && (errno != EAGAIN)) { outerror(OUTERROR_TYPE_WARN, "MD5: [Pack %u] Can't read data from file '%s': %s", number_of_pack(gdata.md5build.xpack), gdata.md5build.xpack->file, strerror(errno)); event_close(gdata.md5build.file_fd); gdata.md5build.file_fd = FD_UNUSED; gdata.md5build.xpack = NULL; break; } else if (howmuch < 0) { break; } else if (howmuch == 0) { /* EOF */ outerror(OUTERROR_TYPE_WARN, "MD5: [Pack %u] Can't read data from file '%s': %s", number_of_pack(gdata.md5build.xpack), gdata.md5build.xpack->file, "truncated"); start_md5_hash(gdata.md5build.xpack, number_of_pack(gdata.md5build.xpack)); break; } /* else got data */ MD5Update(&gdata.md5build.md5sum, gdata.sendbuff, howmuch); if (!gdata.nocrc32) crc32_update((char *)gdata.sendbuff, howmuch); gdata.md5build.bytes += howmuch; if (gdata.md5build.bytes == gdata.md5build.xpack->st_size) { complete_md5_hash(); break; } } } if (!gdata.nomd5sum && changesec && (!gdata.md5build.xpack)) { unsigned int packnum = 1; /* see if any pack needs a md5sum calculated */ if (gdata.nomd5_start <= gdata.curtime) for (xd = irlist_get_head(&gdata.xdccs); xd; xd = irlist_get_next(xd), packnum++) { if (!gdata.nocrc32) { if (!xd->has_crc32) xd->has_md5sum = 0; /* force recheck with crc */ } if (!xd->has_md5sum) { if (verifyshell(&gdata.md5sum_exclude, xd->file)) continue; if (!gdata.attop) gototop(); start_md5_hash(xd, packnum); break; } } } updatecontext(); if (gdata.exiting && has_closed_servers()) { for (chat = irlist_get_head(&gdata.dccchats); chat; chat = irlist_delete(&gdata.dccchats,chat)) { writedccchat(chat, 0, "iroffer exited, Closing DCC Chat\n"); shutdowndccchat(chat,1); } mylog("iroffer exited\n\n"); exit_iroffer(0); } updatecontext(); if (gdata.needsrehash) { gdata.needsrehash = 0; urehash = mycalloc(sizeof(userinput)); a_fillwith_msg2(urehash, NULL, "REHASH"); urehash->method = method_out_all; /* just OUT_S|OUT_L|OUT_D it */ urehash->net = 0; urehash->level = ADMIN_LEVEL_FULL; u_parseit(urehash); mydelete(urehash); } updatecontext(); chat = irlist_get_head(&gdata.dccchats); while (chat) { if (chat->status == DCCCHAT_UNUSED) { chat = irlist_delete(&gdata.dccchats,chat); } else { flushdccchat(chat); chat = irlist_get_next(chat); } } if (gdata.autoadd_time > 0) { if (changesec && ((unsigned)gdata.curtime > (lastautoadd + gdata.autoadd_time))) { lastautoadd = gdata.curtime; autoadd_all(); } } /* END */ updatecontext(); if (gdata.needsclear) drawbot(); changehour=changemin=0; }
void t_closeconn(transfer * const t, const char *msg, int errno1) { gnetwork_t *backup; updatecontext(); if (errno1) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW, "XDCC [%02i:%s on %s]: Connection closed: %s (%s)", t->id, t->nick, gdata.networks[ t->net ].name, msg, strerror(errno1)); } else { ioutput(OUT_S|OUT_L|OUT_D, COLOR_YELLOW, "XDCC [%02i:%s on %s]: Connection closed: %s", t->id, t->nick, gdata.networks[ t->net ].name, msg); } if (t->tr_status == TRANSFER_STATUS_DONE) { return; } if (gdata.debug > 0) { ioutput(OUT_S, COLOR_YELLOW, "clientsock = %d", t->con.clientsocket); } #ifdef HAVE_MMAP if (t->mmap_info) { t->mmap_info->ref_count--; if (!t->mmap_info->ref_count) { int callval_i; callval_i = munmap(t->mmap_info->mmap_ptr, t->mmap_info->mmap_size); if (callval_i < 0) { outerror(OUTERROR_TYPE_WARN, "Couldn't munmap(): %s", strerror(errno)); } irlist_delete(&t->xpack->mmaps, t->mmap_info); } t->mmap_info = NULL; } #endif if (t->con.listensocket != FD_UNUSED && t->con.listensocket > 2) { event_close(t->con.listensocket); t->con.listensocket = FD_UNUSED; } if (t->con.clientsocket != FD_UNUSED && t->con.clientsocket > 2) { shutdown_close(t->con.clientsocket); t->con.clientsocket = FD_UNUSED; } t->xpack->file_fd_count--; if (!t->xpack->file_fd_count && (t->xpack->file_fd != FD_UNUSED)) { close(t->xpack->file_fd); t->xpack->file_fd = FD_UNUSED; t->xpack->file_fd_location = 0; } if (t->tr_status == TRANSFER_STATUS_LISTENING) ir_listen_port_connected(t->con.localport); #ifdef USE_UPNP if (gdata.upnp_router && (t->con.family == AF_INET)) upnp_rem_redir(t->con.localport); #endif /* USE_UPNP */ t->tr_status = TRANSFER_STATUS_DONE; backup = gnetwork; gnetwork = &(gdata.networks[t->net]); if (errno1) { notice(t->nick, "** Closing Connection: %s (%s)", msg, strerror(errno1)); } else { notice(t->nick, "** Closing Connection: %s", msg); } gnetwork = backup; }
/* the DNS resolution as a separate process */ void child_resolver(int family) { #if !defined(NO_GETADDRINFO) struct addrinfo hints; struct addrinfo *results; struct addrinfo *res; #else /* NO_GETADDRINFO */ struct hostent *remotehost; #endif /* NO_GETADDRINFO */ struct sockaddr_in *remoteaddr; res_addrinfo_t rbuffer; ssize_t bytes; int i; #if !defined(NO_GETADDRINFO) int status; int found; char portname[16]; #endif /* NO_GETADDRINFO */ close(gnetwork->serv_resolv.sp_fd[0]); for (i=3; i<((int)FD_SETSIZE); ++i) { /* include [0], but not [1] */ if (i != gnetwork->serv_resolv.sp_fd[1]) { close(i); } } memset(&rbuffer, 0, sizeof(res_addrinfo_t)); /* enable logfile */ gdata.logfd = FD_UNUSED; #if !defined(NO_GETADDRINFO) memset(&hints, 0, sizeof(hints)); switch (family) { case 0: hints.ai_family = PF_UNSPEC; break; case AF_INET: hints.ai_family = PF_INET; break; default: hints.ai_family = PF_INET6; break; } hints.ai_socktype = SOCK_STREAM; snprintf(portname, sizeof(portname), "%d", /* NOTRANSLATE */ gnetwork->serv_resolv.to_port); status = getaddrinfo(gnetwork->serv_resolv.to_ip, portname, &hints, &results); if ((status) || results == NULL) { #else /* NO_GETADDRINFO */ (void)family; remotehost = gethostbyname(gnetwork->serv_resolv.to_ip); if (remotehost == NULL) { #endif /* NO_GETADDRINFO */ #ifdef NO_HOSTCODES _exit(10); #else /* NO_HOSTCODES */ switch (h_errno) { case HOST_NOT_FOUND: _exit(20); case NO_ADDRESS: #if NO_ADDRESS != NO_DATA case NO_DATA: #endif /* NO_ADDRESS != NO_DATA */ _exit(21); case NO_RECOVERY: _exit(22); case TRY_AGAIN: _exit(23); default: _exit(12); } #endif /* NO_HOSTCODES */ } remoteaddr = (struct sockaddr_in *)(&(rbuffer.ai_addr)); rbuffer.ai_reset = 0; #if !defined(NO_GETADDRINFO) found = -1; for (res = results; res; res = res->ai_next) { ++found; if (found < gnetwork->serv_resolv.next) continue; if (res->ai_next == NULL) rbuffer.ai_reset = 1; break; } if (res == NULL) { res = results; rbuffer.ai_reset = 1; } rbuffer.ai_family = res->ai_family; rbuffer.ai_socktype = res->ai_socktype; rbuffer.ai_protocol = res->ai_protocol; rbuffer.ai_addrlen = res->ai_addrlen; rbuffer.ai_addr = *(res->ai_addr); memcpy(remoteaddr, res->ai_addr, res->ai_addrlen); #else /* NO_GETADDRINFO */ rbuffer.ai_family = AF_INET; rbuffer.ai_socktype = SOCK_STREAM; rbuffer.ai_protocol = 0; rbuffer.ai_addrlen = sizeof(struct sockaddr_in); rbuffer.ai_addr.sa_family = remotehost->h_addrtype; remoteaddr->sin_port = htons(gnetwork->serv_resolv.to_port); memcpy(&(remoteaddr->sin_addr), remotehost->h_addr_list[0], sizeof(struct in_addr)); #endif /* NO_GETADDRINFO */ bytes = write(gnetwork->serv_resolv.sp_fd[1], &rbuffer, sizeof(res_addrinfo_t)); #if !defined(NO_GETADDRINFO) freeaddrinfo(results); #endif /* NO_GETADDRINFO */ if (bytes != sizeof(res_addrinfo_t)) { _exit(11); } } #ifndef NO_HOSTCODES static const char *irc_resolved_errormsg[] = { "host not found", "no ip address", "non-recoverable name server", "try again later", }; #endif /* collect the the DNS resolution from the child process */ void irc_resolved(void) { pid_t child; unsigned int ss; int status; while ((child = waitpid(-1, &status, WNOHANG)) > 0) { for (ss=0; ss<gdata.networks_online; ++ss) { if (child != gdata.networks[ss].serv_resolv.child_pid) continue; if (gdata.networks[ss].serverstatus == SERVERSTATUS_RESOLVING) { /* lookup failed */ #ifdef NO_WSTATUS_CODES ioutput(OUT_S|OUT_L|OUT_D, COLOR_RED, "Unable to resolve server %s on %s " "(status=0x%.8X)", gdata.networks[ss].curserver.hostname, gdata.networks[ss].name, status); #else int hasexited = WIFEXITED(status); int ecode = WEXITSTATUS(status); #ifndef NO_HOSTCODES if (hasexited && (ecode >= 20) && (ecode <= 23)) { ioutput(OUT_S|OUT_L|OUT_D, COLOR_RED, "Unable to resolve server %s on %s " "(%s)", gdata.networks[ss].curserver.hostname, gdata.networks[ss].name, irc_resolved_errormsg[ecode - 20]); } else #endif { ioutput(OUT_S|OUT_L|OUT_D, COLOR_RED, "Unable to resolve server %s on %s " "(status=0x%.8X, %s: %d)", gdata.networks[ss].curserver.hostname, gdata.networks[ss].name, status, hasexited ? "exit" : WIFSIGNALED(status) ? "signaled" : "??", hasexited ? ecode : WIFSIGNALED(status) ? WTERMSIG(status) : 0); } #endif gdata.networks[ss].serverstatus = SERVERSTATUS_NEED_TO_CONNECT; } /* cleanup */ event_close(gdata.networks[ss].serv_resolv.sp_fd[0]); gdata.networks[ss].serv_resolv.sp_fd[0] = 0; gdata.networks[ss].serv_resolv.child_pid = 0; } } }
static int test_body(void) { int i, orig_period, max_period; struct event event; /* We use PMC4 to make sure the kernel switches all counters correctly */ event_init_named(&event, 0x40002, "instructions"); event_leader_ebb_init(&event); event.attr.exclude_kernel = 1; event.attr.exclude_hv = 1; event.attr.exclude_idle = 1; FAIL_IF(event_open(&event)); ebb_enable_pmc_counting(4); setup_ebb_handler(standard_ebb_callee); ebb_global_enable(); FAIL_IF(ebb_event_enable(&event)); /* * We want a low sample period, but we also want to get out of the EBB * handler without tripping up again. * * This value picked after much experimentation. */ orig_period = max_period = sample_period = 400; mtspr(SPRN_PMC4, pmc_sample_period(sample_period)); while (ebb_state.stats.ebb_count < 1000000) { /* * We are trying to get the EBB exception to race exactly with * us entering the kernel to do the syscall. We then need the * kernel to decide our timeslice is up and context switch to * the other thread. When we come back our EBB will have been * lost and we'll spin in this while loop forever. */ for (i = 0; i < 100000; i++) sched_yield(); /* Change the sample period slightly to try and hit the race */ if (sample_period >= (orig_period + 200)) sample_period = orig_period; else sample_period++; if (sample_period > max_period) max_period = sample_period; } ebb_freeze_pmcs(); ebb_global_disable(); count_pmc(4, sample_period); mtspr(SPRN_PMC4, 0xdead); dump_summary_ebb_state(); dump_ebb_hw_state(); event_close(&event); FAIL_IF(ebb_state.stats.ebb_count == 0); /* We vary our sample period so we need extra fudge here */ FAIL_IF(!ebb_check_count(4, orig_period, 2 * (max_period - orig_period))); return 0; }
static int per_event_excludes(void) { struct event *e, events[4]; char *platform; int i; platform = (char *)get_auxv_entry(AT_BASE_PLATFORM); FAIL_IF(!platform); SKIP_IF(strcmp(platform, "power8") != 0); /* * We need to create the events disabled, otherwise the running/enabled * counts don't match up. */ e = &events[0]; event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, PERF_TYPE_HARDWARE, "instructions"); e->attr.disabled = 1; e = &events[1]; event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, PERF_TYPE_HARDWARE, "instructions(k)"); e->attr.disabled = 1; e->attr.exclude_user = 1; e->attr.exclude_hv = 1; e = &events[2]; event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, PERF_TYPE_HARDWARE, "instructions(h)"); e->attr.disabled = 1; e->attr.exclude_user = 1; e->attr.exclude_kernel = 1; e = &events[3]; event_init_opts(e, PERF_COUNT_HW_INSTRUCTIONS, PERF_TYPE_HARDWARE, "instructions(u)"); e->attr.disabled = 1; e->attr.exclude_hv = 1; e->attr.exclude_kernel = 1; FAIL_IF(event_open(&events[0])); /* * The open here will fail if we don't have per event exclude support, * because the second event has an incompatible set of exclude settings * and we're asking for the events to be in a group. */ for (i = 1; i < 4; i++) FAIL_IF(event_open_with_group(&events[i], events[0].fd)); /* * Even though the above will fail without per-event excludes we keep * testing in order to be thorough. */ prctl(PR_TASK_PERF_EVENTS_ENABLE); /* Spin for a while */ for (i = 0; i < INT_MAX; i++) asm volatile("" : : : "memory"); prctl(PR_TASK_PERF_EVENTS_DISABLE); for (i = 0; i < 4; i++) { FAIL_IF(event_read(&events[i])); event_report(&events[i]); } /* * We should see that all events have enabled == running. That * shows that they were all on the PMU at once. */ for (i = 0; i < 4; i++) FAIL_IF(events[i].result.running != events[i].result.enabled); /* * We can also check that the result for instructions is >= all the * other counts. That's because it is counting all instructions while * the others are counting a subset. */ for (i = 1; i < 4; i++) FAIL_IF(events[0].result.value < events[i].result.value); for (i = 0; i < 4; i++) event_close(&events[i]); return 0; }