Beispiel #1
0
//! @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;
}
Beispiel #2
0
/**
 * 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);
}
Beispiel #3
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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 */
Beispiel #7
0
/** 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:
			;
	}
}
Beispiel #8
0
/* ======================================================================== */
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
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
}
Beispiel #11
0
static void md_crc32_update(struct context *ctx, u_char * s, size_t len)
{
    ctx->checksum.crc32 = crc32_update(ctx->checksum.crc32, s, len);
}
Beispiel #12
0
static void crc_update(uint32 *a, void *b)
{
    *a = crc32_update(*a, b, 4);
}
Beispiel #13
0
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);

}
Beispiel #14
0
/**
 * 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;
}
Beispiel #15
0
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(&timestruct, NULL);
        last250ms = gdata.curtimems;
        gdata.curtimems = timeval_to_ms(&timestruct);
        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(&timestruct, NULL);
    gdata.selecttimems = timeval_to_ms(&timestruct);
    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(&timestruct, NULL) < 0)
    {
        outerror(OUTERROR_TYPE_CRASH,"gettimeofday() failed! %s\n",strerror(errno));
    }

    gdata.curtimems = timeval_to_ms(&timestruct);
    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;

}
Beispiel #17
-1
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;
}