static size_t curl_cback(void *ptr, size_t size, size_t nmemb, void *data) { uint8_t *b = ptr; size_t want; int timeout; size *= nmemb; nmemb = size; /* we don't check for overrun and just overwrite existing data */ while(size != 0) { timeout = 0; while((will_overflow() && (timeout++ < 20)) || paused || stopped) { if(stopped) return 0; usleep(100000); } want = bps - writeoff; if(want > size) want = size; memcpy(buffer + (bend * bps) + writeoff, b, want); writeoff += want; if(writeoff == bps) { if(++bend == BUFFCNT) bend = 0; writeoff = 0; } b += want; size -= want; } return nmemb; }
static size_t curl_cback(void *ptr, size_t size, size_t nmemb, void *data) { uint8_t *b = ptr; size_t want; size *= nmemb; nmemb = size; /* we don't check for overrun and just overwrite existing data */ while(size != 0) { while(will_overflow()) { printf("."); fflush(stdout); usleep(100000); } printf("CURL : %u bytes\n", size); want = bps - writeoff; if(want > size) want = size; memcpy(buffer + (bend * bps) + writeoff, b, want); writeoff += want; if(writeoff == bps) { if(++bend == BUFFCNT) bend = 0; writeoff = 0; } b += want; size -= want; } return nmemb; }
int main(void) { int prediction = will_overflow(INT_MAX); int actual = plus_one(INT_MAX) == INT_MIN; if (prediction == actual) { printf("SUCCESS\n"); } else { printf("FAILURE\n"); } return 0; }
static DWORD WINAPI curl_threadfunc(LPVOID _unused) { #else static void *curl_threadfunc(void *_unused) { #endif int i; CURLMsg *msg; int timeout; CURLcode cd = CURLE_OK; while(1) { while(1) { retry_ok: cd = CURLE_OK; timeout = 0; while((will_overflow() && (timeout++ < 20)) || (paused) || (stopped)) { usleep(100000); if(paused || stopped) timeout = 18; } curl_multi_perform(curl_multi, &i); while((msg = curl_multi_info_read(curl_multi, &i)) != NULL) { if(msg->msg == CURLMSG_DONE) { if(msg->data.result == CURLE_OK) { printf("Stop (URL complete)\n"); stopped = paused = 1; curl_multi_remove_handle(curl_multi, curl_handle); goto retry_ok; } cd = msg->data.result; goto retry; } } } retry: if(cd != CURLE_OK) printf("URL error: %s\n", curl_easy_strerror(cd)); sleep(2); printf("Retrying URL connect...\n"); } return 0; }
DecodedImageWinId GlzDecoderWindow::pre_decode_update_window(uint64_t image_id, uint64_t relative_head_id) { Lock lock(_win_modifiers_mutex); int realloc_size; while (will_overflow(image_id, relative_head_id)) { if (_aborting) { THROW("aborting"); } _release_image_cond.wait(lock); } // The following conditions prevent starvation in case thread (1) should realloc, // thread (2) is during decode and waits for a previous image and /// thread (3) should decode this the previous image and needs to enter pre decode although // (1) is in there. // We must give priority to older images in the window. // The condition should be checked over again in case a later image entered the window // and the realocation was already performed while ((realloc_size = calc_realloc_size(image_id))) { if (_aborting) { THROW("aborting"); } if (_win_alloc_rw_mutex.try_write_lock()) { realloc(realloc_size); _win_alloc_rw_mutex.write_unlock(); break; } else { _win_alloc_cond.wait(lock); } } if (image_id > _tail_image_id) { // not in missing list add_pre_decoded_image(image_id); } return calc_image_win_idx(image_id); }
static void exif_mnote_data_olympus_load (ExifMnoteData *en, const unsigned char *buf, unsigned int buf_size) { ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en; ExifShort c; size_t i, tcount, o, o2, datao = 6, base = 0; if (!n || !buf || !buf_size || will_overflow(n->offset, 6)) { exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteDataOlympus", "Short MakerNote"); return; } o2 = 6 + n->offset; /* Start of interesting data */ if (exceeds_buffer(buf_size, o2, 10)) { exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteDataOlympus", "Short MakerNote"); return; } /* * Olympus headers start with "OLYMP" and need to have at least * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the * number of entries, and 12 for one entry. * * Sanyo format is identical and uses identical tags except that * header starts with "SANYO". * * Epson format is identical and uses identical tags except that * header starts with "EPSON". * * Nikon headers start with "Nikon" (6 bytes including '\0'), * version number (1 or 2). * * Version 1 continues with 0, 1, 0, number_of_tags, * or just with number_of_tags (models D1H, D1X...). * * Version 2 continues with an unknown byte (0 or 10), * two unknown bytes (0), "MM" or "II", another byte 0 and * lastly 0x2A. */ n->version = exif_mnote_data_olympus_identify_variant(buf+o2, buf_size-o2); switch (n->version) { case olympusV1: case sanyoV1: case epsonV1: exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", "Parsing Olympus/Sanyo/Epson maker note v1..."); /* The number of entries is at position 8. */ if (buf[o2 + 6] == 1) n->order = EXIF_BYTE_ORDER_INTEL; else if (buf[o2 + 6 + 1] == 1) n->order = EXIF_BYTE_ORDER_MOTOROLA; o2 += 8; c = exif_get_short (buf + o2, n->order); if ((!(c & 0xFF)) && (c > 0x500)) { if (n->order == EXIF_BYTE_ORDER_INTEL) { n->order = EXIF_BYTE_ORDER_MOTOROLA; } else { n->order = EXIF_BYTE_ORDER_INTEL; } } break; case olympusV2: /* Olympus S760, S770 */ datao = o2; o2 += 8; if (exceeds_buffer(buf_size, o2, 4)) return; exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...", buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]); if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I')) n->order = EXIF_BYTE_ORDER_INTEL; else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M')) n->order = EXIF_BYTE_ORDER_MOTOROLA; /* The number of entries is at position 8+4. */ if (will_overflow(o2, 4)) return; o2 += 4; break; case nikonV1: o2 += 6; if (exceeds_buffer(buf_size, o2, 8)) return; exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, " "%02x, %02x, %02x, %02x, %02x)...", buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); /* Skip version number */ o2 += 1; /* Skip an unknown byte (00 or 0A). */ o2 += 1; base = MNOTE_NIKON1_TAG_BASE; /* Fix endianness, if needed */ c = exif_get_short (buf + o2, n->order); if ((!(c & 0xFF)) && (c > 0x500)) { if (n->order == EXIF_BYTE_ORDER_INTEL) { n->order = EXIF_BYTE_ORDER_MOTOROLA; } else { n->order = EXIF_BYTE_ORDER_INTEL; } } break; case nikonV2: o2 += 6; if (exceeds_buffer(buf_size, o2, 8)) return; exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, " "%02x, %02x, %02x, %02x, %02x)...", buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); /* Skip version number */ o2 += 1; /* Skip an unknown byte (00 or 0A). */ o2 += 1; /* Skip 2 unknown bytes (00 00). */ o2 += 2; /* * Byte order. From here the data offset * gets calculated. */ if (exceeds_buffer(buf_size, o2, 2)) return; datao = o2; if (!strncmp ((char *)&buf[o2], "II", 2)) n->order = EXIF_BYTE_ORDER_INTEL; else if (!strncmp ((char *)&buf[o2], "MM", 2)) n->order = EXIF_BYTE_ORDER_MOTOROLA; else { exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", "Unknown " "byte order '%c%c'", buf[o2], buf[o2 + 1]); return; } o2 += 2; /* Skip 2 unknown bytes (00 2A). */ if (will_overflow(o2, 2)) return; o2 += 2; /* Go to where the number of entries is. */ if (exceeds_buffer(buf_size, o2, 4)) return; if (will_overflow(datao, exif_get_long (buf + o2, n->order))) return; o2 = datao + exif_get_long (buf + o2, n->order); break; case nikonV0: exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, " "%02x, %02x, %02x, %02x, %02x)...", buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); /* 00 1b is # of entries in Motorola order - the rest should also be in MM order */ n->order = EXIF_BYTE_ORDER_MOTOROLA; break; default: exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", "Unknown Olympus variant %i.", n->version); return; } /* Sanity check the offset */ if (exceeds_buffer(buf_size, o2, 2)) { exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteOlympus", "Short MakerNote"); return; } /* Read the number of tags */ c = exif_get_short (buf + o2, n->order); o2 += 2; /* Remove any old entries */ exif_mnote_data_olympus_clear (n); /* Reserve enough space for all the possible MakerNote tags */ n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c); if (!n->entries) { EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOlympusEntry) * c); return; } /* Parse all c entries, storing ones that are successfully parsed */ tcount = 0; for (i = c, o = o2; i; --i, o += 12) { size_t s; if (exceeds_buffer(buf_size, o, 12)) { exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteOlympus", "Short MakerNote"); break; } n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base; n->entries[tcount].format = exif_get_short (buf + o + 2, n->order); n->entries[tcount].components = exif_get_long (buf + o + 4, n->order); n->entries[tcount].order = n->order; exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus", "Loading entry 0x%x ('%s')...", n->entries[tcount].tag, mnote_olympus_tag_get_name (n->entries[tcount].tag)); /* exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus", "0x%x %d %ld*(%d)", n->entries[tcount].tag, n->entries[tcount].format, n->entries[tcount].components, (int)exif_format_get_size(n->entries[tcount].format)); */ /* * Size? If bigger than 4 bytes, the actual data is not * in the entry but somewhere else (offset). */ s = exif_format_get_size (n->entries[tcount].format) * n->entries[tcount].components; n->entries[tcount].size = s; if (s) { size_t dataofs = o + 8; if (s > 4) { /* The data in this case is merely a pointer */ dataofs = exif_get_long (buf + dataofs, n->order) + datao; #ifdef EXIF_OVERCOME_SANYO_OFFSET_BUG /* Some Sanyo models (e.g. VPC-C5, C40) suffer from a bug when * writing the offset for the MNOTE_OLYMPUS_TAG_THUMBNAILIMAGE * tag in its MakerNote. The offset is actually the absolute * position in the file instead of the position within the IFD. */ if (dataofs + s > buf_size && n->version == sanyoV1) { /* fix pointer */ dataofs -= datao + 6; exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus", "Inconsistent thumbnail tag offset; attempting to recover"); } #endif } if (exceeds_buffer(buf_size, dataofs, s)) { exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteOlympus", "Tag data past end of buffer (%u > %u)", dataofs + s, buf_size); continue; } n->entries[tcount].data = exif_mem_alloc (en->mem, s); if (!n->entries[tcount].data) { EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s); continue; } memcpy (n->entries[tcount].data, buf + dataofs, s); } /* Tag was successfully parsed */ ++tcount; } /* Store the count of successfully parsed tags */ n->count = tcount; }
static DWORD WINAPI curl_threadfunc(LPVOID _unused) { #else static void *curl_threadfunc(void *_unused) { #endif while(1) { if(will_overflow()) { curl_easy_pause(curl_handle, CURLPAUSE_ALL); do { printf("."); fflush(stdout); usleep(100000); } while(will_overflow()); curl_easy_pause(curl_handle, CURLPAUSE_CONT); } if(curl_easy_perform(curl_handle) != CURLE_OK) sleep(2); printf("Retrying URL connect...\n"); } return 0; } int main(int argc, char *argv[]) { #ifdef _WIN32 int tid; #else pthread_t thd; #endif if(argc != 4) { fprintf(stderr, "Usage: %s <stream_url> <nbd_addr> <nbd_port>\n", argv[0]); return 1; } curl_global_init(CURL_GLOBAL_ALL); curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_URL, argv[1]); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, curl_cback); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "vdf_stream"); drv = vdf_drive_create(DRIVE_SIZE, DRIVE_FLAGS); if(drv == NULL) { perror("vdf_createdrive"); return 1; } bps = vdf_drive_sectorsize(drv); filesize = (vdf_drive_dataclusters(drv) - 16) * vdf_drive_clustersize(drv); /* leave a bit of room */ bufflen = bps * BUFFCNT; buffer = malloc(bufflen); if(buffer == NULL) { perror("malloc"); return 1; } bstart = bend = 0; writeoff = 0; fil = vdf_add_file_virt(vdf_drive_root(drv), TRACK_NAME, filesize, file_cback, NULL, 0); if(fil == NULL) { perror("vdf_add_file_virt"); return 1; } trans = vdf_transport_open(VTD_NBD_CLI_STR, drv, NULL, argv[2], argv[3]); if(trans == NULL) { perror("vdf_transport_open"); return 1; } #ifdef _WIN32 if(CreateThread(NULL, 0, curl_threadfunc, NULL, 0, &tid) == NULL) { perror("CreateThread"); return 1; } #else if(pthread_create(&thd, NULL, curl_threadfunc, NULL) == -1) { perror("pthread_create"); return 1; } #endif // vdf_dump_drive_info(drv, stdout); // vdf_dump_drive(drv, "stream.img"); // return 0; while(1) { if(vdf_transport_start(trans) == 0) { while(vdf_transport_process(trans) == 0); } else { printf("Retrying NBD connect...\n"); sleep(2); } } }