/* * multiMain - main driver of shs1 dual routines * * given: * argc arg count left after getopt * argv args left after getopt * pre_str pre-process this data first * pre_len length of pre_str * data_str data is this string, not a file * nospace 1 => don't space seperate multi digests * cnt number of digests to perform */ void multiMain(int argc, char **argv, BYTE *pre_str, UINT pre_len, char *data_str, int nospace, UINT cnt) { extern int optind; /* option index */ SHS1_INFO *digs; /* multiple digest */ unsigned int i; /* * firewall */ if (cnt <= 0) { return; } /* * initialize multiple digests */ digs = (SHS1_INFO *)malloc(sizeof(SHS1_INFO)*cnt); if (digs == NULL) { fprintf(stderr, "%s: bad malloc #1\n", program); exit(60); } for (i=0; i < cnt; ++i) { shs1Init(digs+i); } /* * digest a string */ if (data_str != NULL) { multiData(pre_str, pre_len, (BYTE*)data_str, strlen(data_str), cnt, digs); multiOutput(data_str, 1, nospace, cnt, digs); /* * case: digest stdin */ } else if (optind == argc) { multiStream(pre_str, pre_len, stdin, cnt, digs); multiOutput(NULL, 0, nospace, cnt, digs); /* * case: digest files */ } else { for (; optind < argc; optind++) { multiFile(pre_str, pre_len, argv[optind], cnt, digs); multiOutput(argv[optind], 0, nospace, cnt, digs); } } }
/*! Parses and loads multi definitions */ void cMultiCache::load( const QString &basePath ) { QFile indexFile( basePath + "multi.idx" ); if( !indexFile.open( IO_ReadOnly ) ) throw wpException( QString( "Error opening file %1 for reading." ).arg( basePath + "multi.idx" ) ); QDataStream indexStream( &indexFile ); indexStream.setByteOrder( QDataStream::LittleEndian ); QFile multiFile( basePath + "multi.mul" ); if ( !multiFile.open( IO_ReadOnly ) ) throw wpException( QString( "Error opening file %1 for reading." ).arg( basePath + "multi.mul" ) ); struct { Q_INT32 start; Q_INT32 length; Q_INT32 unknown; } indexData; ushort currentID = 0; while ( !indexStream.atEnd() ) { indexFile.at( currentID * 12 ); indexStream >> indexData.start; indexStream >> indexData.length; indexStream >> indexData.unknown; if ( indexData.start == -1 ) // empty record? { ++currentID; continue; } QValueVector<multiItem_st> items; items.reserve( indexData.length / 12 ); uint i = 0; multiFile.at( indexData.start ); QDataStream multiStream( &multiFile ); multiStream.setByteOrder( QDataStream::LittleEndian ); for (; i < indexData.length / 12; ++i ) { multiItem_st item; multiStream >> item.tile; multiStream >> item.x; multiStream >> item.y; multiStream >> item.z; Q_UINT8 empty; multiStream >> empty; // ???? Q_UINT32 isVisible = 0; multiStream >> isVisible; item.visible = isVisible > 0 ? true : false; if ( item.visible ) // we ignore invisible items (?) items.push_back(item); } MultiDefinition* multi = new MultiDefinition; multi->setItems( items ); multis.insert( currentID++, multi ); } }
/* * multiFile - divide a file into alternating bytes and digest both halves * * given: * pre_str string prefix or NULL * pre_len length of pre_str * filename the filename to process * cnt number of digests * digs array of digests, cnt elements long */ static void multiFile(BYTE *pre_str, UINT pre_len, char *filename, UINT cnt, SHS1_INFO *digs) { FILE *inFile; /* the open file stream */ struct stat buf; /* stat or lstat of file */ struct shs1_stat hashbuf; /* stat data to digest */ struct shs1_stat hashlbuf; /* lstat data to digest */ UINT i; /* * firewall */ if (cnt <= 0) { return; } /* * open the file */ inFile = fopen(filename, "rb"); if (inFile == NULL) { fprintf(stderr, "%s: cannot open %s: ", program, filename); perror(""); return; } /* * pre-process prefix if needed */ if (pre_str == NULL || pre_len <= 0) { if (i_flag) { multiData(NULL, 0, (BYTE *)filename, strlen(filename), cnt, digs); } } else { if (i_flag) { multiData(pre_str, pre_len, (BYTE *)filename, strlen(filename), cnt, digs); } else { multiData(pre_str, pre_len, NULL, 0, cnt, digs); } } /* * digest file stat and lstat */ if (i_flag) { if (fstat(fileno(inFile), &buf) < 0) { printf("%s can't be stated.\n", filename); return; } hashbuf.stat_dev = buf.st_dev; hashbuf.stat_ino = buf.st_ino; hashbuf.stat_mode = buf.st_mode; hashbuf.stat_nlink = buf.st_nlink; hashbuf.stat_uid = buf.st_uid; hashbuf.stat_gid = buf.st_gid; hashbuf.stat_size = buf.st_size; hashbuf.stat_mtime = buf.st_mtime; hashbuf.stat_ctime = buf.st_ctime; if (lstat(filename, &buf) < 0) { printf("%s can't be lstated.\n", filename); return; } hashlbuf.stat_dev = buf.st_dev; hashlbuf.stat_ino = buf.st_ino; hashlbuf.stat_mode = buf.st_mode; hashlbuf.stat_nlink = buf.st_nlink; hashlbuf.stat_uid = buf.st_uid; hashlbuf.stat_gid = buf.st_gid; hashlbuf.stat_size = buf.st_size; hashlbuf.stat_mtime = buf.st_mtime; hashlbuf.stat_ctime = buf.st_ctime; multiData((BYTE *)&hashbuf, sizeof(hashbuf), (BYTE *)&hashlbuf, sizeof(hashlbuf), cnt, digs); /* * pad sections with zeros to process file data faster */ for (i=0; i < cnt; ++i) { if (digs[i].datalen > 0) { shs1Update(digs+i, (BYTE *)shs1_zero, SHS1_CHUNKSIZE - digs[i].datalen); } } } /* * process the data stream */ multiStream(NULL, 0, inFile, cnt, digs); fclose(inFile); }