void read_vertices(FILE* fd) { safe_fread(buf, NVAR*nv, sizeof(float), fd); for (int iv=0, ib=0; iv<nv; ++iv) { xx[iv] = buf[ib++]; yy[iv] = buf[ib++]; zz[iv] = buf[ib++]; vvx[iv] = buf[ib++]; vvy[iv] = buf[ib++]; vvz[iv] = buf[ib++]; } }
void read_faces(FILE* fd) { safe_fread(ibuf, nf*(NV_PER_FACE+1), sizeof(int), fd); for (int ifa = 0, ib = 0; ifa < nf; ++ifa) { ib++; /* skip number of vertices per face */ ff1[ifa] = ibuf[ib++]; ff2[ifa] = ibuf[ib++]; ff3[ifa] = ibuf[ib++]; } }
static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) { char buf[512]; if (!(option_mask32 & WGET_OPT_QUIET)) progress_meter(-1); if (G.chunked) goto get_clen; /* Loops only if chunked */ while (1) { while (1) { int n; unsigned rdsz; rdsz = sizeof(buf); if (G.got_clen) { if (G.content_len < (off_t)sizeof(buf)) { if ((int)G.content_len <= 0) break; rdsz = (unsigned)G.content_len; } } n = safe_fread(buf, rdsz, dfp); if (n <= 0) { if (ferror(dfp)) { /* perror will not work: ferror doesn't set errno */ bb_error_msg_and_die(bb_msg_read_error); } break; } xwrite(output_fd, buf, n); #if ENABLE_FEATURE_WGET_STATUSBAR G.transferred += n; #endif if (G.got_clen) G.content_len -= n; } if (!G.chunked) break; safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */ get_clen: safe_fgets(buf, sizeof(buf), dfp); G.content_len = STRTOOFF(buf, NULL, 16); /* FIXME: error check? */ if (G.content_len == 0) break; /* all done! */ G.got_clen = 1; } if (!(option_mask32 & WGET_OPT_QUIET)) progress_meter(0); }
int read_rolling_bufs(FILE *original_file, unsigned char *prev_buf, unsigned char *next_buf, zync_block_size_t block_size, off_t prev_offset, off_t next_offset) { memset(prev_buf, 0, block_size); if (fseek(original_file, prev_offset, SEEK_SET) != 0) { return -1; } if (safe_fread(prev_buf, block_size, original_file) == -1) { return -1; } memset(next_buf, 0, block_size); if (fseek(original_file, next_offset, SEEK_SET) != 0) { return -1; } if (safe_fread(next_buf, block_size, original_file) == -1) { return -1; } return 0; }
// Allocates memory (from_unsigned_cell()) void factor_vm::primitive_fread() { FILE* file = pop_file_handle(); void* buf = (void*)alien_offset(ctx->pop()); cell size = unbox_array_size(); if (size == 0) { ctx->push(from_unsigned_cell(0)); return; } size_t c = safe_fread(buf, 1, size, file); if (c == 0 || feof(file)) clearerr(file); ctx->push(from_unsigned_cell(c)); }
void load_from_file (FILE* file) { logger.debug() << "Loading " << Pos::numUsed() << " Obs from file" |0; Logging::IndentBlock block; const size_t FIELD_SIZE = sizeof(Int); //read data for (Pos::iterator i=Pos::begin(); i!=Pos::end(); ++i) { Pos pos = *i; _clear(pos); safe_fread(&(pos(BOOL_PROPERTIES)), FIELD_SIZE, 1, file); } }
void factor_vm::load_data_heap(FILE *file, image_header *h, vm_parameters *p) { p->tenured_size = std::max((h->data_size * 3) / 2,p->tenured_size); init_data_heap(p->young_size, p->aging_size, p->tenured_size); fixnum bytes_read = safe_fread((void*)data->tenured->start,1,h->data_size,file); if((cell)bytes_read != h->data_size) { std::cout << "truncated image: " << bytes_read << " bytes read, "; std::cout << h->data_size << " bytes expected\n"; fatal_error("load_data_heap failed",0); } data->tenured->initial_free_list(h->data_size); }
void factor_vm::load_code_heap(FILE *file, image_header *h, vm_parameters *p) { if(h->code_size > p->code_size) fatal_error("Code heap too small to fit image",h->code_size); init_code_heap(p->code_size); if(h->code_size != 0) { size_t bytes_read = safe_fread(code->allocator->first_block(),1,h->code_size,file); if(bytes_read != h->code_size) { std::cout << "truncated image: " << bytes_read << " bytes read, "; std::cout << h->code_size << " bytes expected\n"; fatal_error("load_code_heap failed",0); } } code->allocator->initial_free_list(h->code_size); }
/* This function also initializes the data and code heaps */ void factor_vm::load_image(vm_parameters *p) { FILE *file = OPEN_READ(p->image_path); if(file == NULL) { std::cout << "Cannot open image file: " << p->image_path << std::endl; std::cout << strerror(errno) << std::endl; exit(1); } image_header h; if(safe_fread(&h,sizeof(image_header),1,file) != 1) fatal_error("Cannot read image header",0); if(h.magic != image_magic) fatal_error("Bad image: magic number check failed",h.magic); if(h.version != image_version) fatal_error("Bad image: version number check failed",h.version); load_data_heap(file,&h,p); load_code_heap(file,&h,p); safe_fclose(file); init_objects(&h); cell data_offset = data->tenured->start - h.data_relocation_base; cell code_offset = code->seg->start - h.code_relocation_base; fixup_data(data_offset,code_offset); fixup_code(data_offset,code_offset); /* Store image path name */ special_objects[OBJ_IMAGE] = allot_alien(false_object,(cell)p->image_path); }
int import_config(char *url, webs_t stream, int *total) { char upload_file[] = "/tmp/ezp_cfg_XXXXXX"; char decoded_file[] = "/tmp/decoded_cfg.cfg"; FILE *fifo = NULL; FILE *tmp_fifo = NULL; char *buf = NULL; int c; int count; int ret = 0; long flags = -1; int size = BUFSIZ; mkstemp(upload_file) ; if (!(fifo = fopen(upload_file, "w"))) { ret = errno; goto err; } #ifdef DEBUG printf("Random filename %s\n", upload_file); #endif /* Set nonblock on the socket so we can timeout */ if (!do_ssl) { if ((flags = fcntl(fileno(stream), F_GETFL)) < 0 || fcntl(fileno(stream), F_SETFL, flags | O_NONBLOCK) < 0) { ret = errno; goto err; } } /* ** The buffer must be at least as big as what the stream file is ** using so that it can read all the data that has been buffered ** in the stream file. Otherwise it would be out of sync with fn ** select specially at the end of the data stream in which case ** the select tells there is no more data available but there in ** fact is data buffered in the stream file's buffer. Since no ** one has changed the default stream file's buffer size, let's ** use the constant BUFSIZ until someone changes it. **/ if ((buf = malloc(size)) == NULL) { ret = ENOMEM; goto err; } #ifdef DEBUG printf("Uploading the configuration file %s\n", upload_file); #endif /* Upload the configuration file first. */ while (total && *total) { if (do_ssl) { if (size > *total) size = *total; count = wfread(buf, 1, size, stream); } else { if (waitfor(fileno(stream), 30) <= 0) { cprintf("waitfor timeout 30 secs\n"); break; } count = safe_fread(buf, 1, size, stream); if (!count && (ferror(stream) || feof(stream))) break; } safe_fwrite(buf, 1, count, fifo); *total -= count; printf("total:%d\n", *total); #ifdef DEBUG printf("."); #endif } fclose(fifo); fifo = NULL; /* cfg file needs to be decoded. */ if (!(fifo = fopen(upload_file, "r"))) { ret = errno; goto err; } if (!(tmp_fifo = fopen(decoded_file, "w"))) { ret = errno; goto err; } /* Decoding procedure */ /* Note: c must be an integer to compare with EOF. */ while ((c = fgetc(fifo)) != EOF) { decode((char *)&c, 1); fputc(c, tmp_fifo); } fclose(fifo); fifo = NULL; fclose(tmp_fifo); tmp_fifo = NULL; if (!do_ssl) { /* Reset nonblock on the socket */ if (fcntl(fileno(stream), F_SETFL, flags) < 0) { ret = errno; goto err; } } ret=nvram_import(decoded_file); #ifdef DEBUG printf("done\n"); #endif err: if (buf) { free(buf); } if (fifo) { fclose(fifo); } if (tmp_fifo) { fclose(tmp_fifo); } #ifdef DEBUG if (ret) { perror(NULL); } #endif return ret; }
bool factor_vm::read_embedded_image_footer(FILE* file, embedded_image_footer* footer) { safe_fseek(file, -(off_t)sizeof(embedded_image_footer), SEEK_END); safe_fread(footer, (off_t)sizeof(embedded_image_footer), 1, file); return footer->magic == image_magic; }
int zync_original_file(FILE *original_file, FILE *download_file, zync_file_size_t original_filelen) { if (fseek(download_file, 0, SEEK_SET) != 0) { return -1; } struct zync_state *zs = read_zync_file(download_file); //zs+1 if (zs == NULL) { return -1; } zync_block_size_t block_size = zs->block_size; unsigned char *adler32_buf = safe_malloc(sizeof(unsigned char) * block_size); //adler32_buf+1 if (adler32_buf == NULL) { return -1; } if (fseek(download_file, 0, SEEK_SET) != 0) { free(zs); //zs-1 free(adler32_buf); //adler32_buf-1 return -1; } if (safe_fread(adler32_buf, block_size, original_file) == -1) { free(zs); //zs-1 free(adler32_buf); //adler32_buf-1 return -1; } zync_rsum_t rolling_adler32 = calc_adler32(adler32_buf, block_size); free(adler32_buf); //adler32_buf-1 unsigned char *prev_buf = safe_malloc(sizeof(unsigned char) * block_size); //prev_buf+1 if (prev_buf == NULL) { free(zs); //zs-1 return -1; } unsigned char *next_buf = safe_malloc(sizeof(unsigned char) * block_size); //next_buf+1 if (next_buf == NULL) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 return -1; } unsigned char prev_ch = 0; unsigned char next_ch = 0; off_t prev_offset = 0; off_t next_offset = block_size; zync_file_size_t index = 0; if (read_rolling_bufs(original_file, prev_buf, next_buf, block_size, prev_offset, next_offset) != 0) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 return -1; } while (true) { struct zync_block *unfilled_zb = find_unfilled_zync_block_by_rsum(zs, rolling_adler32); if (unfilled_zb != NULL) { unsigned char *data_buf = safe_malloc(sizeof(unsigned char) * block_size); //data_buf+1 if (data_buf == NULL) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 return -1; } unsigned char *checksum_buf = safe_malloc(sizeof(unsigned char) * 16); //checksum_buf+1 if (checksum_buf == NULL) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 free(data_buf); //data_buf-1 return -1; } if (fseek(original_file, prev_offset, SEEK_SET) != 0) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 free(data_buf); //data_buf-1 free(checksum_buf); //checksum_buf-1 return -1; } if (safe_fread(data_buf, block_size, original_file) == -1) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 free(data_buf); //data_buf-1 free(checksum_buf); //checksum_buf-1 return -1; } calc_md5(data_buf, block_size, checksum_buf); if (unfilled_zb != NULL) { if (unfilled_zb->rsum == rolling_adler32) { if (memcmp(unfilled_zb->checksum, checksum_buf, 16) == 0) { unfilled_zb->block_fill_flag = 1; zs->block_fill_count++; if (fseek(download_file, 0, SEEK_SET) != 0) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 free(data_buf); //data_buf-1 free(checksum_buf); //checksum_buf-1 return -1; } if (update_download_file(download_file, data_buf, zs, unfilled_zb->block_index) == -1) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 free(data_buf); //data_buf-1 free(checksum_buf); //checksum_buf-1 return -1; } } } } free(data_buf); //data_buf-1 free(checksum_buf); //checksum_buf-1 } prev_ch = prev_buf[index]; next_ch = next_buf[index]; rolling_adler32 = calc_rolling_adler32(rolling_adler32, block_size, prev_ch, next_ch); index = (index + 1) % block_size; if (index == 0) { prev_offset += block_size; next_offset += block_size; if (prev_offset >= original_filelen) { break; } if (read_rolling_bufs(original_file, prev_buf, next_buf, block_size, prev_offset, next_offset) != 0) { free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 return -1; } } } free(zs); //zs-1 free(prev_buf); //prev_buf-1 free(next_buf); //next_buf-1 return 0; }
int generate_zync_state(FILE *in_file, struct zync_state *zs, zync_block_size_t block_size) { if (block_size <= 0) { fprintf(stderr, "block_size <= 0"); return -1; } if (fseek(in_file, 0, SEEK_SET) != 0) { return -1; } zync_file_size_t in_filelen = 0; zync_block_index_t block_id = 0; unsigned char *zync_checksum = safe_malloc(sizeof(unsigned char) * 16); //zync_checksum+1 if (zync_checksum == NULL) { return -1; } CC_MD5_CTX *zync_ctx = init_md5(); //zync_ctx+1 while (block_id < MAX_BLOCKS) { unsigned char *in_file_buf = safe_malloc(sizeof(unsigned char) * block_size); //in_file_buf+1 if (in_file_buf == NULL) { free(zync_checksum); //zync_checksum-1 free(zync_ctx); //zync_ctx-1 return -1; } size_t in_file_read = safe_fread(in_file_buf, block_size, in_file); if (in_file_read == -1) { free(zync_checksum); //zync_checksum-1 free(zync_ctx); //zync_ctx-1 free(in_file_buf); //in_file_buf-1 return -1; } zync_rsum_t adler = (zync_rsum_t) calc_adler32(in_file_buf, block_size); unsigned char *md5_buf = safe_malloc(sizeof(unsigned char) * 16); //md5_buf+1 if (md5_buf == NULL) { free(zync_checksum); //zync_checksum-1 free(zync_ctx); //zync_ctx-1 free(in_file_buf); //in_file_buf-1 return -1; } calc_md5((void *) in_file_buf, block_size, md5_buf); add_zync_block(zs, block_id++, 0, 0, adler, md5_buf); free(md5_buf); //md5_buf-1 update_md5(zync_ctx, (void *) in_file_buf, block_size); in_filelen += in_file_read; free(in_file_buf); //in_file_buf-1 if (feof(in_file)) { break; } } finalize_md5(zync_ctx, zync_checksum); //zync_ctx-1 for (int i = 0; i < 16; i++) { zs->checksum[i] = zync_checksum[i]; } free(zync_checksum); //zync_checksum-1 zs->filelen = in_filelen; zs->block_size = block_size; zs->block_fill_count = 0; return 0; }
int read_zync_state(FILE *in_file, struct zync_state *zs) { unsigned char *r_zync_checksum = (unsigned char *) safe_malloc(sizeof(unsigned char) * 16); //r_zync_checksum+1 if (r_zync_checksum == NULL) { return -1; } if (safe_fread((void *) r_zync_checksum, sizeof(unsigned char) * 16, in_file) == -1) { free(r_zync_checksum); //r_zync_checksum-1 return -1; } for (int i = 0; i < 16; i++) { zs->checksum[i] = r_zync_checksum[i]; } free(r_zync_checksum); //r_zync_checksum-1 zync_file_size_t r_filelen = 0; if (fread((void *) &r_filelen, sizeof(zync_file_size_t), 1, in_file) != 1) { return -1; } zs->filelen = r_filelen; zync_block_size_t r_block_size = 0; if (fread((void *) &r_block_size, sizeof(zync_block_size_t), 1, in_file) != 1) { return -1; } zs->block_size = r_block_size; if (r_block_size == 0) { fprintf(stderr, "block size is 0\n"); return -1; } zync_block_index_t r_block_count = 0; if (fread((void *) &r_block_count, sizeof(zync_block_index_t), 1, in_file) != 1) { return -1; } zs->block_fill_count = r_block_count; zync_block_size_t block_size = r_block_size; zync_block_index_t blocks = (zs->filelen + block_size - 1)/ block_size; for (zync_block_index_t i = 0; i < blocks; i++) { zync_block_index_t r_block_index = 0; if (fread((void *) &r_block_index, sizeof(zync_block_index_t), 1, in_file) != 1) { return -1; } zync_block_index_t r_block_id = 0; if (fread((void *) &r_block_id, sizeof(zync_block_index_t), 1, in_file) != 1) { return -1; } zync_block_flag_t r_block_flag = 0; if (fread((void *) &r_block_flag, sizeof(zync_block_flag_t), 1, in_file) != 1) { return -1; } zync_rsum_t r_rsum = 0; if (fread((void *) &r_rsum, sizeof(zync_rsum_t), 1, in_file) != 1) { return -1; } unsigned char *r_checksum = (unsigned char *) safe_malloc(sizeof(unsigned char) * 16); //r_checksum+1 if (r_checksum == NULL) { free(r_checksum); //r_checksum-1 return -1; } if (fread((void *) r_checksum, sizeof(unsigned char) * 16, 1, in_file) != 1) { free(r_checksum); //r_checksum-1 return -1; } add_zync_block(zs, r_block_index, r_block_id, r_block_flag, r_rsum, r_checksum); free(r_checksum); //r_checksum-1 } return 0; }
static void NOINLINE retrieve_file_data(FILE *dfp, int output_fd) { char buf[512]; #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT # if ENABLE_FEATURE_WGET_TIMEOUT unsigned second_cnt; # endif struct pollfd polldata; polldata.fd = fileno(dfp); polldata.events = POLLIN | POLLPRI; ndelay_on(polldata.fd); #endif progress_meter(PROGRESS_START); if (G.chunked) goto get_clen; /* Loops only if chunked */ while (1) { while (1) { int n; unsigned rdsz; rdsz = sizeof(buf); if (G.got_clen) { if (G.content_len < (off_t)sizeof(buf)) { if ((int)G.content_len <= 0) break; rdsz = (unsigned)G.content_len; } } #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT # if ENABLE_FEATURE_WGET_TIMEOUT second_cnt = G.timeout_seconds; # endif while (1) { if (safe_poll(&polldata, 1, 1000) != 0) break; /* error, EOF, or data is available */ # if ENABLE_FEATURE_WGET_TIMEOUT if (second_cnt != 0 && --second_cnt == 0) { progress_meter(PROGRESS_END); bb_perror_msg_and_die("download timed out"); } # endif /* Needed for "stalled" indicator */ progress_meter(PROGRESS_BUMP); } #endif n = safe_fread(buf, rdsz, dfp); if (n <= 0) { if (ferror(dfp)) { /* perror will not work: ferror doesn't set errno */ bb_error_msg_and_die(bb_msg_read_error); } break; } xwrite(output_fd, buf, n); #if ENABLE_FEATURE_WGET_STATUSBAR G.transferred += n; progress_meter(PROGRESS_BUMP); #endif if (G.got_clen) G.content_len -= n; } if (!G.chunked) break; safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */ get_clen: safe_fgets(buf, sizeof(buf), dfp); G.content_len = STRTOOFF(buf, NULL, 16); /* FIXME: error check? */ if (G.content_len == 0) break; /* all done! */ G.got_clen = 1; } progress_meter(PROGRESS_END); }
int do_upgrade(char *url, webs_t stream, int *total) { char upload_file[] = "/tmp/ezp_firmware_XXXXXX"; FILE *fifo = NULL; FILE *tmp_fifo = NULL; char *write_argv[4]; pid_t pid; char *buf = NULL; int count; int ret = 0; long flags = -1; int size = BUFSIZ; struct stat st; int upgrade_cmd_complete = 0; #if defined(PLATFORM_LIS) || defined(PLATFORM_AXA) FILE *pFile; char result[24]={0}; int percentage=0; if ((pFile = popen("ezp-i2c gauge percentage", "r"))) { fgets(result, sizeof(result), pFile); sscanf(result,"Battery: %d %%", &percentage); } // terminate pclose (pFile); if (percentage < 60) { ret=2; goto err; } #endif system("/sbin/stop_services.sh"); start_upgrade_indicator(); /* FIRMWARE upgrade utility */ write_argv[0] = "/usr/sbin/upgraded"; write_argv[1] = upload_file; write_argv[2] = NULL; // system("/tmp/ezp-i2c gauge upgrade start"); // system("/sbin/reserve_link.sh"); mkstemp(upload_file) ; if (!(fifo = fopen(upload_file, "w"))) { ret = errno; goto err; } #ifdef DEBUG printf("Random filename %s\n", upload_file); #endif /* Set nonblock on the socket so we can timeout */ if (!do_ssl) { if ((flags = fcntl(fileno(stream), F_GETFL)) < 0 || fcntl(fileno(stream), F_SETFL, flags | O_NONBLOCK) < 0) { ret = errno; goto err; } } /* ** The buffer must be at least as big as what the stream file is ** using so that it can read all the data that has been buffered ** in the stream file. Otherwise it would be out of sync with fn ** select specially at the end of the data stream in which case ** the select tells there is no more data available but there in ** fact is data buffered in the stream file's buffer. Since no ** one has changed the default stream file's buffer size, let's ** use the constant BUFSIZ until someone changes it. **/ if ((buf = malloc(size)) == NULL) { ret = ENOMEM; goto err; } #ifdef DEBUG printf("Uploading the firmware %s\n", upload_file); #endif /* Upload the file first. */ while (total && *total) { if (do_ssl) { if (size > *total) size = *total; count = wfread(buf, 1, size, stream); } else { if (waitfor(fileno(stream), 30) <= 0) { cprintf("waitfor timeout 30 secs\n"); ret = errno; goto err; } count = safe_fread(buf, 1, size, stream); if (!count && (ferror(stream) || feof(stream))) { ret = errno; goto err; } } safe_fwrite(buf, 1, count, fifo); *total -= count; #ifdef DEBUG printf("."); #endif } fclose(fifo); fifo = NULL; if (!do_ssl) { /* Reset nonblock on the socket */ if (fcntl(fileno(stream), F_SETFL, flags) < 0) { ret = errno; goto err; } } /* Data transfer finished, bring down devices. */ //system("/sbin/ifdown wan0"); //system("/sbin/ifdown wan1"); //system("/sbin/ifdown lan0"); _eval(write_argv, NULL, 0, &pid) ; upgrade_cmd_complete = 1; while((stat("/tmp/fw_incorrect",&st) != 0) && (stat("/tmp/fw_correct",&st) != 0)){ usleep(200000); } if(stat("/tmp/fw_incorrect", &st) == 0) ret = 1; else if(stat("/tmp/fw_correct", &st) == 0) ret = 0; #ifdef DEBUG printf("done with ret:%d\n", ret); #endif err: if (buf) { free(buf); } if (fifo) { fclose(fifo); } if (tmp_fifo) { fclose(tmp_fifo); } #ifdef DEBUG if (ret) { perror(NULL); } #endif if(!upgrade_cmd_complete) { system("/tmp/ezp-i2c gauge upgrade finish"); } /* ret value * 1 : upgrade fail * 2 : low power * other : upgrade success * */ return ret; }
static int retrieve_file_data(struct globals *state, FILE *dfp, int (*progress)(void *data, int current, int total), int (*output_func)(void *data, char *bytes, int len), void *data) { char buf[4*1024]; /* made bigger to speed up local xfers */ unsigned second_cnt; struct pollfd polldata; polldata.fd = fileno(dfp); polldata.events = POLLIN | POLLPRI; progress(data, 0, state->total_len); if (state->chunked) goto get_clen; /* Loops only if chunked */ while (1) { ndelay_on(polldata.fd); while (1) { int n; unsigned rdsz; rdsz = sizeof(buf); if (state->got_clen) { if (state->content_len < (off_t)sizeof(buf)) { if ((int)state->content_len <= 0) break; rdsz = (unsigned)state->content_len; } } second_cnt = state->timeout_seconds; while (1) { if (safe_poll(&polldata, 1, 1000) != 0) break; /* error, EOF, or data is available */ if (second_cnt != 0 && --second_cnt == 0) { progress(data, -1, state->total_len); ERROR("download timed out"); return -1; } /* Needed for "stalled" indicator */ progress(data, state->transferred, state->total_len); } /* fread internally uses read loop, which in our case * is usually exited when we get EAGAIN. * In this case, libc sets error marker on the stream. * Need to clear it before next fread to avoid possible * rare false positive ferror below. Rare because usually * fread gets more than zero bytes, and we don't fall * into if (n <= 0) ... */ clearerr(dfp); errno = 0; n = safe_fread(buf, rdsz, dfp); /* man fread: * If error occurs, or EOF is reached, the return value * is a short item count (or zero). * fread does not distinguish between EOF and error. */ if (n <= 0) { if (errno == EAGAIN) /* poll lied, there is no data? */ continue; /* yes */ if (ferror(dfp)) ERROR("Could not read file"); break; /* EOF, not error */ } output_func(data, buf, n); state->transferred += n; progress(data, state->transferred, state->total_len); if (state->got_clen) { state->content_len -= n; if (state->content_len == 0) break; } } ndelay_off(polldata.fd); if (!state->chunked) break; safe_fgets(buf, sizeof(buf), dfp); /* This is a newline */ get_clen: safe_fgets(buf, sizeof(buf), dfp); state->content_len = strtol(buf, NULL, 16); /* FIXME: error check? */ if (state->content_len == 0) break; /* all done! */ state->got_clen = 1; } progress(data, state->transferred, state->total_len); return 0; }
static void file_load(void *f, void *data, long length, long offset) { safe_fseek(f, offset, SEEK_SET); safe_fread(data, length, 1, f); }