//! @brief Calculate crc on a range of flash, specified in the bootloader configuration area. static uint32_t calculate_application_crc32(bootloader_configuration_data_t * config) { uint32_t crc32; // Initialize the CRC32 information crc32_data_t crcInfo; crc32_init(&crcInfo); // Run CRC, Considering skip crcExpectedValue address uint32_t bypassStartAddress = kBootloaderConfigAreaAddress + ((uint32_t)&config->crcExpectedValue - (uint32_t)&config->tag); uint32_t bypassEndAddress = bypassStartAddress + sizeof(config->crcExpectedValue); if ((config->crcStartAddress >= bypassEndAddress) || (config->crcStartAddress + config->crcByteCount <= bypassStartAddress)) { crc32_update(&crcInfo, (uint8_t *)config->crcStartAddress, config->crcByteCount); } else { // Assume that crcExpectedValue address (4 byte) resides in crc addresses completely crc32_update(&crcInfo, (uint8_t *)config->crcStartAddress, bypassStartAddress - config->crcStartAddress); crc32_update(&crcInfo, (uint8_t *)bypassEndAddress, config->crcStartAddress + config->crcByteCount - bypassEndAddress); } // Finalize the CRC calculations crc32_finalize(&crcInfo, &crc32); return crc32; }
/** * Generate new token for given version string. */ static char * tok_generate(time_t now, const char *version) { char token[TOKEN_BASE64_SIZE + 1]; char digest[TOKEN_VERSION_SIZE]; char lvldigest[LEVEL_SIZE]; char lvlbase64[LEVEL_BASE64_SIZE + 1]; const struct tokkey *tk; uint32 crc32; uint idx; const char *key; SHA1Context ctx; struct sha1 sha1; int lvlsize; int i; /* * Compute token. */ key = random_key(now, &idx, &tk); now = clock_loc2gmt(now); /* As close to GMT as possible */ poke_be32(&digest[0], now); random_bytes(&digest[4], 3); digest[6] &= 0xe0U; /* Upper 3 bits only */ digest[6] |= idx & 0xffU; /* Has 5 bits for the index */ SHA1Reset(&ctx); SHA1Input(&ctx, key, strlen(key)); SHA1Input(&ctx, digest, 7); SHA1Input(&ctx, version, strlen(version)); SHA1Result(&ctx, &sha1); memcpy(&digest[7], sha1.data, SHA1_RAW_SIZE); /* * Compute level. */ lvlsize = G_N_ELEMENTS(token_keys) - (tk - token_keys); crc32 = crc32_update(0, digest, TOKEN_VERSION_SIZE); for (i = 0; i < lvlsize; i++) { poke_be16(&lvldigest[i*2], tok_crc(crc32, tk)); tk++; } /* * Encode into base64. */ base64_encode_into(digest, TOKEN_VERSION_SIZE, token, TOKEN_BASE64_SIZE); token[TOKEN_BASE64_SIZE] = '\0'; ZERO(&lvlbase64); base64_encode_into(lvldigest, 2 * lvlsize, lvlbase64, LEVEL_BASE64_SIZE); return g_strconcat(token, "; ", lvlbase64, (void *) 0); }
bool cpld_xc2c64a_jtag_checksum( const jtag_t* const jtag, const cpld_xc2c64a_verify_t* const verify, uint32_t* const crc_value ) { cpld_xc2c_jtag_reset_and_idle(jtag); if( cpld_xc2c64a_jtag_idcode_ok(jtag) && cpld_xc2c_jtag_read_write_protect(jtag) && cpld_xc2c64a_jtag_idcode_ok(jtag) && cpld_xc2c_jtag_read_write_protect(jtag) ) { cpld_xc2c_jtag_bypass(jtag, false); cpld_xc2c_jtag_enable(jtag); cpld_xc2c_jtag_enable(jtag); cpld_xc2c_jtag_enable(jtag); cpld_xc2c_jtag_read(jtag); crc32_t crc; crc32_init(&crc); uint8_t dr[CPLD_XC2C64A_BYTES_IN_ROW]; for(size_t row=0; row<CPLD_XC2C64A_ROWS; row++) { const size_t address = cpld_hackrf_row_addresses.address[row]; cpld_xc2c64a_jtag_read_row(jtag, address, dr); const size_t mask_index = verify->mask_index[row]; for(size_t i=0; i<CPLD_XC2C64A_BYTES_IN_ROW; i++) { dr[i] &= verify->mask[mask_index].value[i]; } /* Important checksum calculation NOTE: * Do checksum of all bits in row bytes, but ensure that invalid bits * are set to zero by masking. This subtlety just wasted several hours * of my life... */ crc32_update(&crc, dr, CPLD_XC2C64A_BYTES_IN_ROW); } *crc_value = crc32_digest(&crc); cpld_xc2c_jtag_init_special(jtag); cpld_xc2c_jtag_conld(jtag); if( cpld_xc2c64a_jtag_idcode_ok(jtag) && cpld_xc2c_jtag_is_done(jtag) ) { cpld_xc2c_jtag_conld(jtag); cpld_xc2c_jtag_bypass(jtag, false); cpld_xc2c_jtag_bypass(jtag, true); return true; } } cpld_xc2c_jtag_reset_and_idle(jtag); return false; }
int main(int argc, char ** argv){ if(argc != 2){ return 1; } char * str = argv[1]; uint8_t crc_val[4]; { // generating CRC struct CRC32 crc; crc32_init(&crc, GENPOLY); uint8_t * p; for(p = str; *p; p += 1){ crc32_update(&crc, *p); } crc32_finalize(&crc); uint8_t i; for(i=0;i<4;i+=1){ crc_val[i] = crc32_get_reversed(&crc, i); } } int _return; { // checking crc struct CRC32 crc; crc32_init(&crc, GENPOLY); uint8_t * p; for(p = str; *p; p += 1){ crc32_update(&crc, *p); } uint8_t i; for(i=0;i<4;i+=1){ crc32_update(&crc, crc_val[i]); } if(crc32_check_zero(&crc)){ fprintf(stderr, "success!\n"); _return = 0; }else{ fprintf(stderr, "fail =(\n"); _return = 1; } } return _return; }
static uint16 tok_crc(uint32 crc, const struct tokkey *tk) { const char **keys = tk->keys; size_t i; i = tk->count; while (i-- > 0) { const char *k = *keys++; crc = crc32_update(crc, k, strlen(k)); } crc ^= (crc >> 8); crc &= 0x00ff00ffU; crc |= crc >> 8; return crc & 0xffffU; }
static void mavis_io(struct context *ctx) { av_ctx *avc = NULL; struct query *q; rb_node_t *r; char *serial; Debug((DEBUG_PROC, "mavis_io %p\n", ctx)); switch (mavis_recv(mcx, &avc, ctx)) { case MAVIS_FINAL: break; case MAVIS_TIMEOUT: counter_expired++, counter_p_expired++; default: return; } if (!(serial = av_get(avc, AV_A_SERIAL))) return; q = alloca(sizeof(struct query)); q->serial = serial; q->serial_crc = crc32_update(INITCRC32, (u_char *) serial, strlen(serial)); if (!(r = RB_search(deferred_by_serial, q))) return; q = RB_payload(r, struct query *); /* XXX -- move the unset functionality to a separate module? */ if (!transmit_password) { av_unset(avc, AV_A_PASSWORD); av_unset(avc, AV_A_DBPASSWORD); } ctx = io_get_ctx(io, q->fd); /* Send answer to client */ av_send(avc, q->fd, &q->sa, ctx->blowfish); /* Remove query from deferred queue */ RB_delete(deferred_by_serial, r); backlog--; setproctitle("%s: backlog: %d", common_data.progname, backlog); counter_answered++, counter_p_answered++; return; } /* if */
/** Update the checksum calculation with an incoming byte */ void cksum_update(SBMP_CksumType type, uint32_t *scratch, uint8_t byte) { switch (type) { #if SBMP_HAS_CRC32 case SBMP_CKSUM_CRC32: *scratch = crc32_update(*scratch, byte); break; #endif case SBMP_CKSUM_XOR: *scratch ^= byte; break; case SBMP_CKSUM_NONE: // fall-through default: ; } }
/* ======================================================================== */ uint_32 file_crc32(const char *fname) { FILE *f; uint_32 crc = 0xFFFFFFFFU; int c; if (fname == NULL) f = stdin; else if (!(f = fopen(fname, "rb"))) return crc; while ((c = fgetc(f)) != EOF) crc = crc32_update(crc, c & 0xFF); if (fname) fclose(f); return crc ^ 0xFFFFFFFFU; }
uint32_t calc_sram_crc(uint32_t base_addr, uint32_t size) { uint8_t data; uint32_t count; uint32_t crc; crc=0; crc_valid=1; set_mcu_addr(base_addr); FPGA_SELECT(); FPGA_TX_BYTE(0x88); for(count=0; count<size; count++) { FPGA_WAIT_RDY(); data = FPGA_RX_BYTE(); if(get_snes_reset()) { crc_valid = 0; break; } crc += crc32_update(crc, data); } FPGA_DESELECT(); return crc; }
int crc32_test(void) { #ifndef LTC_TEST return CRYPT_NOP; #else const void* in = "libtomcrypt"; const unsigned char crc32[] = { 0xef, 0x76, 0x73, 0xb3 }; unsigned char out[4]; crc32_state ctx; crc32_init(&ctx); crc32_update(&ctx, in, strlen(in)); crc32_finish(&ctx, out, 4); if (XMEMCMP(crc32, out, 4)) { #ifdef LTC_TEST_DBG ulong32 _out, _crc32; LOAD32H(_out, out); LOAD32H(_crc32, crc32); printf("crc32 fail! Is: 0x%x Should: 0x%x\n", _out, _crc32); #endif return CRYPT_FAIL_TESTVECTOR; } return CRYPT_OK; #endif }
static void md_crc32_update(struct context *ctx, u_char * s, size_t len) { ctx->checksum.crc32 = crc32_update(ctx->checksum.crc32, s, len); }
static void crc_update(uint32 *a, void *b) { *a = crc32_update(*a, b, 4); }
int32_t initgroupfile(const char *filename) { uint8_t buf[16] ; int32_t i, j, k ; grpArchive_t *archive ; printf("Loading %s ...\n", filename); if (grpSet.num == MAXGROUPFILES) { printf("Error: Unable to open an extra GRP archive <= No more slot available.\n"); return(-1); } archive = &grpSet.archives[grpSet.num]; //Init the slot memset(archive, 0, sizeof(grpArchive_t)); //groupfil_memory[numgroupfiles] = NULL; // addresses of raw GRP files in memory //groupefil_crc32[numgroupfiles] = 0; archive->fileDescriptor = open(filename,O_BINARY|O_RDWR,S_IREAD); if (archive->fileDescriptor < 0) { printf("Error: Unable to open file %s.\n",filename); getchar(); exit(0); } read(archive->fileDescriptor,buf,16); //FCS : The ".grp" file format is just a collection of a lot of files stored into 1 big one. //KS doc: I tried to make the format as simple as possible: The first 12 bytes contains my name, //"KenSilverman". The next 4 bytes is the number of files that were compacted into the //group file. Then for each file, there is a 16 byte structure, where the first 12 //bytes are the filename, and the last 4 bytes are the file's size. The rest of the //group file is just the raw data packed one after the other in the same order as the list //of files. - ken // Check the magic number (12 bytes header). if ((buf[0] != 'K') || (buf[1] != 'e') || (buf[2] != 'n') || (buf[3] != 'S') || (buf[4] != 'i') || (buf[5] != 'l') || (buf[6] != 'v') || (buf[7] != 'e') || (buf[8] != 'r') || (buf[9] != 'm') || (buf[10] != 'a') || (buf[11] != 'n')) { printf("Error: File %s is not a GRP archive.\n",filename); return(-1); } // The next 4 bytes of the header feature the number of files in the GRP archive. archive->numFiles = BUILDSWAP_INTEL32(*((int32_t *)&buf[12])); archive->gfilelist = kmalloc(archive->numFiles * sizeof(grpIndexEntry_t)); archive->fileOffsets = kmalloc(archive->numFiles * sizeof(int32_t)); archive->filesizes = kmalloc(archive->numFiles * sizeof(int32_t)); // Load the full index 16 bytes per file (12bytes for name + 4 bytes for the size). read(archive->fileDescriptor,archive->gfilelist, archive->numFiles * 16); //Initialize all file offset and pointers. j = 12 + 4 + archive->numFiles * sizeof(grpIndexEntry_t); for (i=0; i<archive->numFiles; i++) { k = BUILDSWAP_INTEL32(*((int32_t *)&archive->gfilelist[i][12])); // get size // Now that the filesize has been read, we can replace it with '0' and hence have a // valid, null terminated character string that will be usable. archive->gfilelist[i][12] = '\0'; archive->filesizes[i] = k; archive->fileOffsets[i] = j; // absolute offset list of all files. j += k; } //archive->fileOffsets[archive->numFiles-1] = j; // Compute CRC32 of the whole grp and implicitely caches the GRP in memory through windows caching service. // Rewind the fileDescriptor lseek(archive->fileDescriptor, 0, SEEK_SET); //i = 1000000; //groupfil_memory[numgroupfiles] = malloc(i); //Load the full GRP in RAM. while ((j=read(archive->fileDescriptor, crcBuffer, sizeof(crcBuffer)))) { archive->crc32 = crc32_update(crcBuffer,j,archive->crc32); } // The game layer seems to absolutely need to access an array int[4] groupefil_crc32 // so we need to store the crc32 in there too. groupefil_crc32[grpSet.num] = archive->crc32; //free(groupfil_memory[numgroupfiles]); //groupfil_memory[numgroupfiles] = 0; grpSet.num++; return(grpSet.num-1); }
/** * Validate a base64-encoded version token `tokenb64' of `len' bytes. * The `ip' is given only for clock update operations. * * @returns error code, or TOK_OK if token is valid. */ tok_error_t tok_version_valid( const char *version, const char *tokenb64, int len, host_addr_t addr) { time_t now = tm_time(); time_t stamp; uint32 crc; const struct tokkey *tk; const struct tokkey *rtk; const struct tokkey *latest; uint idx; const char *key; SHA1Context ctx; char lvldigest[1024]; char token[TOKEN_VERSION_SIZE]; struct sha1 digest; version_t rver; char *end; int toklen; int lvllen; int lvlsize; uint i; end = strchr(tokenb64, ';'); /* After 25/02/2003 */ toklen = end ? (end - tokenb64) : len; /* * Verify token. */ if (toklen != TOKEN_BASE64_SIZE) return TOK_BAD_LENGTH; if (!base64_decode_into(tokenb64, toklen, token, TOKEN_VERSION_SIZE)) return TOK_BAD_ENCODING; stamp = (time_t) peek_be32(&token); /* * Use that stamp, whose precision is TOKEN_LIFE, to update our * clock skew if necessary. */ clock_update(stamp, TOKEN_LIFE, addr); if (ABS(stamp - clock_loc2gmt(now)) > TOKEN_CLOCK_SKEW) return TOK_BAD_STAMP; if (!version_fill(version, &rver)) /* Remote version */ return TOK_BAD_VERSION; tk = find_tokkey_version(&rver, stamp); /* The keys they used */ if (tk == NULL) return TOK_BAD_KEYS; idx = (uchar) token[6] & 0x1f; /* 5 bits for the index */ if (idx >= tk->count) return TOK_BAD_INDEX; key = tk->keys[idx]; SHA1Reset(&ctx); SHA1Input(&ctx, key, strlen(key)); SHA1Input(&ctx, token, 7); SHA1Input(&ctx, version, strlen(version)); SHA1Result(&ctx, &digest); if (0 != memcmp(&token[7], digest.data, SHA1_RAW_SIZE)) return TOK_INVALID; if (version_build_cmp(&rver, &tk->ver) < 0) return TOK_OLD_VERSION; if (end == NULL) return TOK_MISSING_LEVEL; latest = find_latest(&rver); if (latest == NULL) /* Unknown in our key set */ return TOK_OLD_VERSION; /* * Verify build. * * Build numbers were emitted when we switched to SVN on 2006-08-26 * and stopped being a monotonous increasing function when we switched * to git on 2011-09-11. */ if ( rver.timestamp >= 1156543200 && /* 2006-08-26 */ rver.timestamp < GIT_SWITCH /* 2011-09-11 */ ) { if (0 == rver.build) return TOK_MISSING_BUILD; if (rver.build < latest->ver.build) return TOK_WRONG_BUILD; } /* * Verify level. */ lvllen = len - toklen - 2; /* Forget about "; " */ end += 2; /* Skip "; " */ if (UNSIGNED(lvllen) >= sizeof(lvldigest) || lvllen <= 0) return TOK_BAD_LEVEL_LENGTH; if (lvllen & 0x3) return TOK_BAD_LEVEL_LENGTH; lvllen = base64_decode_into(end, lvllen, lvldigest, sizeof(lvldigest)); if (lvllen == 0 || (lvllen & 0x1)) return TOK_BAD_LEVEL_ENCODING; g_assert(lvllen >= 2); g_assert((lvllen & 0x1) == 0); /* * Only check the highest keys we can check. */ lvllen /= 2; /* # of keys held remotely */ lvlsize = G_N_ELEMENTS(token_keys) - (tk - token_keys); lvlsize = MIN(lvllen, lvlsize); g_assert(lvlsize >= 1); rtk = tk + (lvlsize - 1); /* Keys at that level */ crc = crc32_update(0, token, TOKEN_VERSION_SIZE); crc = tok_crc(crc, rtk); lvlsize--; /* Move to 0-based offset */ if (peek_be16(&lvldigest[2*lvlsize]) != crc) return TOK_INVALID_LEVEL; for (i = 0; i < G_N_ELEMENTS(token_keys); i++) { rtk = &token_keys[i]; if (rtk->ver.timestamp > rver.timestamp) { rtk--; /* `rtk' could not exist remotely */ break; } } if (lvlsize < rtk - tk) return TOK_SHORT_LEVEL; return TOK_OK; }
void client_io(struct context *ctx, int cur) { /* We have incoming data. */ char *serial; int res; ssize_t buflen; sockaddr_union sa; socklen_t sinlen = (socklen_t) sizeof(sockaddr_union); char *avt; char buf[BUFSIZE_MAVIS]; av_ctx *avc; static struct query *q = NULL; if (!q) q = Xcalloc(1, sizeof(struct query)); Debug((DEBUG_PROC, "client_io\n")); /* Receive request from client */ buflen = recvfrom(cur, buf, sizeof(buf) - 1, 0, &sa.sa, &sinlen); if (buflen <= 0) return; buf[buflen] = 0; /* Decode data, if neccessary */ if (ctx->blowfish) blowfish_dec(ctx->blowfish, (a_char *) buf, buflen); /* Check client IP address */ res = acl_check(&sa); if (!res) { char ibuf[INET6_ADDRSTRLEN]; logmsg("Ignoring query from %s", su_ntop(&sa, ibuf, (socklen_t) sizeof(ibuf))); return; } counter_query++, counter_p_query++; avc = av_new(NULL, NULL); av_char_to_array(avc, buf, NULL); serial = av_get(avc, AV_A_SERIAL); if (!serial) { char ibuf[INET6_ADDRSTRLEN]; logmsg("query from %s lacks serial", su_ntop(&sa, ibuf, (socklen_t) sizeof(ibuf))); counter_err++, counter_p_err++; av_free(avc); return; } q->serial = serial; q->serial_crc = crc32_update(INITCRC32, (u_char *) serial, strlen(serial)); if (RB_search(deferred_by_serial, q)) { char ibuf[INET6_ADDRSTRLEN]; Debug((DEBUG_PROC, "Duplicate detected\n")); logmsg("Ignoring duplicate query from %s (backlog: %d)", su_ntop(&sa, ibuf, (socklen_t) sizeof(ibuf)), backlog); counter_retry++, counter_p_retry++; av_free(avc); return; } if (av_get(avc, AV_A_RESULT)) { char ibuf[INET6_ADDRSTRLEN]; Debug((DEBUG_PROC, "AV_A_RESULT already set. Spoofing?\n")); logmsg("Ignoring query with pre-set result code " "from %s (backlog: %d)", su_ntop(&sa, ibuf, (socklen_t) sizeof(ibuf)), backlog); counter_err++, counter_p_err++; av_free(avc); return; } avt = av_get(avc, AV_A_TYPE); if (!avt || !strncmp(avt, AV_V_TYPE_PRIVATE_PREFIX, AV_V_TYPE_PRIVATE_PREFIX_LEN)) { counter_err++, counter_p_err++; av_free(avc); return; } av_setcb(avc, (void *) mavis_io, (void *) q); switch (mavis_send(mcx, &avc)) { case MAVIS_DEFERRED: Debug((DEBUG_PROC, "mavis_send yields DEFERRED\n")); q->sa = sa; q->fd = cur; q->serial = Xstrdup(serial); RB_insert(deferred_by_serial, q); q = NULL; backlog++; if (backlog > backlog_max) backlog_max = backlog; if (backlog > backlog_max_p) backlog_max_p = backlog; setproctitle("%s: backlog: %d", common_data.progname, backlog); return; case MAVIS_TIMEOUT: counter_expired++, counter_p_expired++; break; case MAVIS_FINAL: if (!transmit_password) { av_unset(avc, AV_A_PASSWORD); av_unset(avc, AV_A_DBPASSWORD); } av_send(avc, cur, &sa, ctx->blowfish); counter_answered++, counter_p_answered++; } av_free(avc); }
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; }
int app_ok(){ if (!APP_RANGE_VALID(APP_START, app_info->image_size)) { return 0; } uint32_t crc = crc32_init(); crc = crc32_update(crc, (void*)APP_START, app_info->image_size); crc = crc32_finalize(crc); if (crc != 0) { return 0; } return 1; }