static int get_byte (void) { if (filepos == gzip_data_offset || bufloc == INBUFSIZ) { int pos; int old_filepos = filepos; bufloc = 0; grub_read (inbuf, INBUFSIZ); /* If there are 8 bytes or less left, we have read in all the * the file content. So get the last 8 bytes and get the crc * and uncompressed size. This is important for the loop in * gunzip_read() to terminate properly. */ if (filepos >= filemax - 8) { uch *eb = endbuf; for (pos = filemax - 8; pos < filepos; pos++) *eb++ = inbuf[pos - old_filepos]; if (filemax > filepos) grub_read(eb, filemax - filepos); gzip_crc = *((unsigned long *) endbuf); gzip_filemax = *((unsigned long *) (endbuf + 4)); } } return inbuf[bufloc++]; }
static int load_file(char *name, void **ptr, long *size) { char *buf = NULL; int allocated = 1 * 1024 * 1024; int len, filled = 0; if (!grub_open (name)) return -1; buf = malloc(allocated); errnum = 0; while (1) { len = grub_read (buf + filled, allocated - filled); if (! len) { if (!errnum) break; grub_close (); return -1; } filled += len; if (filled < allocated) break; allocated *= 2; buf = realloc(buf, allocated); } grub_close (); *ptr = buf; *size = filled; return 0; }
static int get_byte (void) { if (filepos == gzip_data_offset || bufloc == INBUFSIZ) { bufloc = 0; grub_read (inbuf, INBUFSIZ); } return inbuf[bufloc++]; }
void cmain (void) { grub_printf ("\n\nGRUB loading, please wait...\n"); /* * Here load the true second-stage boot-loader. */ if (grub_open (config_file)) { int ret; disk_read_hook = disk_read_savesect_func; grub_read ((char *) 0x8000, SECTOR_SIZE * 2); disk_read_hook = NULL; /* Sanity check: catch an internal error. */ if (saved_sector == -1) { grub_printf ("internal error: the second sector of Stage 2 is unknown."); stop (); } ret = grub_read ((char *) 0x8000 + SECTOR_SIZE * 2, -1); grub_close (); if (ret) chain_stage2 (0, 0x8200, saved_sector); } /* * If not, then print error message and die. */ print_error (); stop (); }
/* internal function for eating variable-length header fields */ static int bad_field (int len) { char ch = 1; int not_retval = 1; do { if (len >= 0) { if (!(len--)) break; } else { if (!ch) break; } } while ((not_retval = grub_read (&ch, 1)) == 1); return (!not_retval); }
int gunzip_test_header (void) { unsigned char buf[10]; /* "compressed_file" is already reset to zero by this point */ /* * This checks if the file is gzipped. If a problem occurs here * (other than a real error with the disk) then we don't think it * is a compressed file, and simply mark it as such. */ if (no_decompression || grub_read (buf, 10) != 10 || ((*((unsigned short *) buf) != GZIP_HDR_LE) && (*((unsigned short *) buf) != OLD_GZIP_HDR_LE))) { filepos = 0; return ! errnum; } /* * This does consistency checking on the header data. If a * problem occurs from here on, then we have corrupt or otherwise * bad data, and the error should be reported to the user. */ if (buf[2] != DEFLATED || (buf[3] & UNSUPP_FLAGS) || ((buf[3] & EXTRA_FIELD) && (grub_read (buf, 2) != 2 || bad_field (*((unsigned short *) buf)))) || ((buf[3] & ORIG_NAME) && bad_field (-1)) || ((buf[3] & COMMENT) && bad_field (-1))) { if (! errnum) errnum = ERR_BAD_GZIP_HEADER; return 0; } gzip_data_offset = filepos; filepos = filemax - 8; if (grub_read (buf, 8) != 8) { if (! errnum) errnum = ERR_BAD_GZIP_HEADER; return 0; } gzip_crc = *((unsigned long *) buf); gzip_fsmax = gzip_filemax = *((unsigned long *) (buf + 4)); initialize_tables (); compressed_file = 1; gunzip_swap_values (); /* * Now "gzip_*" values refer to the compressed data. */ filepos = 0; return 1; }
int gunzip_test_header (void) { unsigned char buf[10]; /* "compressed_file" is already reset to zero by this point */ /* * This checks if the file is gzipped. If a problem occurs here * (other than a real error with the disk) then we don't think it * is a compressed file, and simply mark it as such. */ if (no_decompression || grub_read (buf, 10) != 10 || ((*((unsigned short *) buf) != GZIP_HDR_LE) && (*((unsigned short *) buf) != OLD_GZIP_HDR_LE))) { filepos = 0; return ! errnum; } /* * This does consistency checking on the header data. If a * problem occurs from here on, then we have corrupt or otherwise * bad data, and the error should be reported to the user. */ if (buf[2] != DEFLATED || (buf[3] & UNSUPP_FLAGS) || ((buf[3] & EXTRA_FIELD) && (grub_read (buf, 2) != 2 || bad_field (*((unsigned short *) buf)))) || ((buf[3] & ORIG_NAME) && bad_field (-1)) || ((buf[3] & COMMENT) && bad_field (-1))) { if (! errnum) errnum = ERR_BAD_GZIP_HEADER; return 0; } gzip_data_offset = filepos; /* We could read the last 8 bytes of the file to get the uncompressed * size. Doing so under tftp would cause the file to be downloaded * twice, which can be problem with large files. So we set it to * MAXINT and correct it later when we get to the end of the file * in get_byte(). */ gzip_fsmax = gzip_filemax = MAXINT; initialize_tables (); compressed_file = 1; gunzip_swap_values (); /* * Now "gzip_*" values refer to the compressed data. */ filepos = 0; crc = (ulg)0xffffffffUL; return 1; }