r90870 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r90869‎ | r90870 | r90871 >
Date:08:02, 27 June 2011
Author:ariel
Status:deferred
Tags:
Comment:
quick checker for truncated bz2 files
Modified paths:
  • /branches/ariel/xmldumps-backup/checkforbz2footer.c (added) (history)

Diff [purge]

Index: branches/ariel/xmldumps-backup/checkforbz2footer.c
@@ -0,0 +1,156 @@
 2+#include <unistd.h>
 3+#include <stdio.h>
 4+#include <string.h>
 5+#include <sys/types.h>
 6+#include <sys/stat.h>
 7+#include <fcntl.h>
 8+#include <stdlib.h>
 9+#include <errno.h>
 10+
 11+/*
 12+ Check to see whether a file ends with a bz2 footer or not
 13+ (i.e. if it is truncated or corrupted).
 14+ This is a crude but fast test for integrity; we don't
 15+ check the CRC at the end of fthe stream, nor do we check the
 16+ bit padding in the last byte of the file.
 17+
 18+ Arguments: the name of the file to check, presumably
 19+ a bzipped file.
 20+ Outputs: none.
 21+ Exits with 1 if the file contains the footer at the end,
 22+ 0 if the file does not contain the footer, and -1 on error.
 23+*/
 24+
 25+
 26+int read_footer(unsigned char *buffer, int fin) {
 27+ int res;
 28+
 29+ res = lseek(fin, -11, SEEK_END);
 30+ if (res < 0) {
 31+ fprintf(stderr,"lseek of file failed\n");
 32+ exit(-1);
 33+ }
 34+ res = read(fin, buffer, 11);
 35+ if (res < 0) {
 36+ fprintf(stderr,"read of file failed\n");
 37+ exit(-1);
 38+ }
 39+ return(0);
 40+}
 41+
 42+#define LEFT 0
 43+#define RIGHT 1
 44+
 45+/* return n ones either at left or right end */
 46+int bitmask(int numbits, int end) {
 47+ if (end == RIGHT) {
 48+ return((1<<numbits)-1);
 49+ }
 50+ else {
 51+ return(((1<<numbits)-1) << (8-numbits));
 52+ }
 53+}
 54+
 55+void shiftbytesright(unsigned char *buffer, int buflen, int numbits) {
 56+ int i;
 57+
 58+ for (i=buflen-1; i>=0; i--) {
 59+ /* right 1 */
 60+ buffer[i] = (unsigned char) ((int) (buffer[i]) >> numbits);
 61+
 62+ /* grab rightmost from prev byte */
 63+ if (i > 0) {
 64+ buffer[i] = ( unsigned char ) ((unsigned int) buffer[i] | ( ((unsigned int) (buffer[i-1])<<(8-numbits)) & bitmask(1,LEFT)));
 65+ }
 66+ }
 67+}
 68+
 69+/* buff1 is some random bytes, buff2 is some random bytes which we expect to start with the contents of buff1,
 70+ both buffers are bit-shifted to the right "bitsrightshifted". this function compares the two and returns 1 if buff2
 71+ matches and 0 otherwise. */
 72+int bytescompare(unsigned char *buff1, unsigned char *buff2, int numbytes, int bitsrightshifted) {
 73+ int i;
 74+
 75+ if (bitsrightshifted == 0) {
 76+ for (i = 0; i< numbytes; i++) {
 77+ if (buff1[i] != buff2[i]) {
 78+ return(0);
 79+ }
 80+ }
 81+ return(1);
 82+ }
 83+ else {
 84+ for (i = 1; i< numbytes-2; i++) {
 85+ if (buff1[i] != buff2[i]) {
 86+ return(0);
 87+ }
 88+ }
 89+ /* do leftmost byte */
 90+ if ((buff1[0] & bitmask(8-bitsrightshifted,RIGHT)) != (buff2[0] & bitmask(8-bitsrightshifted,RIGHT)) ) {
 91+ return(0);
 92+ }
 93+ /* do rightmost byte */
 94+ if ((buff1[numbytes-1] & bitmask(bitsrightshifted,LEFT)) != (buff2[numbytes-1] & bitmask(bitsrightshifted,LEFT)) ) {
 95+ return(0);
 96+ }
 97+ return(1);
 98+ }
 99+}
 100+
 101+int checkfileforfooter(int fin) {
 102+ unsigned char buffer[11];
 103+ int result, i;
 104+ unsigned char **footer = malloc(8*sizeof(unsigned char *));
 105+
 106+ /* set up footer plus its various right-shifted incarnations */
 107+ /* dude why couldn't you have 0 padded each bzip2 block? seriously ... */
 108+ for (i = 0; i< 8; i++) {
 109+ footer[i] = malloc(sizeof(unsigned char)*7);
 110+ }
 111+ footer[0][0]= (unsigned char) 0x17;
 112+ footer[0][1]= (unsigned char) 0x72;
 113+ footer[0][2]= (unsigned char) 0x45;
 114+ footer[0][3]= (unsigned char) 0x38;
 115+ footer[0][4]= (unsigned char) 0x50;
 116+ footer[0][5]= (unsigned char) 0x90;
 117+ footer[0][6]= (unsigned char) 0x00;
 118+ for (i = 1; i< 8; i++) {
 119+ memcpy((char *)(footer[i]), (char *)(footer[i-1]),7);
 120+ shiftbytesright(footer[i],7,1);
 121+ }
 122+
 123+ read_footer(buffer,fin);
 124+
 125+ result = bytescompare(footer[0],buffer+1,6,0);
 126+ if (result) {
 127+ return(result);
 128+ }
 129+
 130+ for (i=1; i<8; i++) {
 131+ result = bytescompare(footer[i],buffer,7,i);
 132+ if (result) {
 133+ return(result);
 134+ }
 135+ }
 136+ return(0);
 137+}
 138+
 139+int main(int argc, char **argv) {
 140+
 141+ int fin;
 142+ int result;
 143+
 144+ if (argc != 2) {
 145+ fprintf(stderr,"usage: %s infile\n", argv[0]);
 146+ exit(-1);
 147+ }
 148+ fin = open (argv[1], O_RDONLY);
 149+ if (fin < 0) {
 150+ fprintf(stderr,"failed to open file %s for read\n", argv[1]);
 151+ exit(-1);
 152+ }
 153+ result = checkfileforfooter(fin);
 154+ close(fin);
 155+ exit(result);
 156+}
 157+
Property changes on: branches/ariel/xmldumps-backup/checkforbz2footer.c
___________________________________________________________________
Added: svn:eol-style
1158 + native

Status & tagging log