static int openroot(FileSystem *fs, Dir *dir, size_t szdir) { (void)szdir; TarState *state = (TarState*) kmalloc(sizeof(TarState)); dir->fsdata = state; state->prefix[0] = 0; state->dirDepth = 0; state->header = masterHeader; dir->dirent.d_ino = (ino_t) masterHeader; strcpyUntilSlash(dir->dirent.d_name, masterHeader->filename); dir->stat.st_dev = 0; dir->stat.st_ino = (ino_t) masterHeader; dir->stat.st_mode = 0555; if (masterHeader->filename[strlen(masterHeader->filename)-1] == '/') dir->stat.st_mode |= VFS_MODE_DIRECTORY; dir->stat.st_nlink = 1; dir->stat.st_uid = 0; dir->stat.st_gid = 0; dir->stat.st_rdev = 0; dir->stat.st_size = parseOct(masterHeader->size); dir->stat.st_blksize = 512; dir->stat.st_blocks = dir->stat.st_size / 512; if (dir->stat.st_size % 512) dir->stat.st_blocks++; dir->stat.st_atime = 0; dir->stat.st_ctime = 0; dir->stat.st_mtime = 0; dir->openfile = openfile; dir->opendir = opendir; dir->next = dirNext; dir->close = dirClose; return 0; };
static int dirNext(Dir *dir) { TarState *state = (TarState*) dir->fsdata; while (1) { state->header = &state->header[1+dir->stat.st_blocks]; if ((uint64_t)(state->header) >= initrdEnd) { return -1; }; if (state->header->filename[0] == 0) { return -1; }; dir->dirent.d_ino = (ino_t) state->header; strcpyUntilSlash(dir->dirent.d_name, &state->header->filename[strlen(state->prefix)]); dir->stat.st_ino = dir->dirent.d_ino; dir->stat.st_mode = 0555; if (state->header->filename[strlen(state->header->filename)-1] == '/') dir->stat.st_mode |= VFS_MODE_DIRECTORY; dir->stat.st_size = parseOct(state->header->size); dir->stat.st_blksize = 512; dir->stat.st_blocks = dir->stat.st_size / 512; if (dir->stat.st_size % 512) dir->stat.st_blocks++; size_t numSlashes = 0; const char *scan = state->header->filename; while (*scan != 0) { if ((*scan++) == '/') numSlashes++; }; // last slash (for directories) does not count. if (state->header->filename[strlen(state->header->filename)-1] == '/') numSlashes--; if (numSlashes != state->dirDepth) { continue; }; if (strlen(state->header->filename) < strlen(state->prefix)) { continue; }; if (memcmp(state->header->filename, state->prefix, strlen(state->prefix)) != 0) { continue; }; break; }; return 0; };
void Shell::pushInt(const char *str) { bool opposite = false; if(str[0]=='-') { opposite=true; str++; } int v = 0; if(str[0] == '0') { //Could be octal or hexa if(str[1] == 'x') v = parseHex(str+2); else v = parseOct(str+1); } else { v = parseDec(str); } if(opposite) v = -v; s.push(v); }
Error QTar::extract() { //ifstream ofstream to seekg() QArchive::extract(); if(!exists()) return Archive::OpenError; char buff[Header::RecordSize]; //QFile outFile; //FILE* f; size_t bytes_read; unsigned int filesize; #if ARCREADER_QT4 if(!open(QIODevice::ReadOnly)) { error(); #else if(open(IO_ReadOnly)) { qDebug("open error"); #endif //ARCREADER_QT4 return Archive::OpenError; } Q_D(QArchive); for (;;) { #if ARCREADER_QT4 bytes_read = read(buff,Header::RecordSize); #else bytes_read = readBlock(buff,Header::RecordSize); #endif //ARCREADER_QT4 //put them here emit byteProcessed(d->processedSize+=Header::RecordSize); d->current_fileName=QFileInfo(buff).fileName(); if (bytes_read < Header::RecordSize) { fprintf(stderr,"Short read. expected 512, got %d\n", bytes_read); return Archive::ReadError; } if (isEndBuff(buff)) { #if USE_SLOT emit byteProcessed(d->processedSize+=Header::RecordSize); //header; #else estimate(); progressHandler->Progress(d->current_fileName, d->size, d->processedSize+=Header::RecordSize, d->totalSize, d->speed, d->elapsed, d->left); #endif finishMessage(); return End; } if (!verifyChecksum(buff)) { fprintf(stderr, "Checksum failure\n"); return ChecksumError; } switch (buff[156]) { case Header::LinkFlag::kLink : printf(" Ignoring hardlink %s\n", buff); break; case Header::LinkFlag::kSymbolicLink : printf(" Ignoring symlink %s\n", buff); break; ///////////////////////// case Header::LinkFlag::kCharacter: printf(" Ignoring character device %s\n", buff); break; case Header::LinkFlag::kBlock: printf(" Ignoring block device %s\n", buff); break; case Header::LinkFlag::kDirectory: createDir(QString::fromLocal8Bit(buff), parseOct(buff + 100, 8)); filesize = 0; break; case Header::LinkFlag::kFIFO: printf(" Ignoring FIFO %s\n", buff); break; default: createFile(QString::fromLocal8Bit(buff), parseOct(buff + 100, 8)); break; } ++d->numFiles; filesize = parseOct(buff + 124, 12); d->size = filesize; #if USE_SLOT updateMessage(); #endif while (filesize > 0) { checkTryPause(); #if ARCREADER_QT4 bytes_read = read(buff,Header::RecordSize); #else bytes_read = readBlock(buff,Header::RecordSize); #endif //ARCREADER_QT4 if (bytes_read < Header::RecordSize) { fprintf(stderr,"Short read. Expected 512, got %d\n",bytes_read); return Archive::ReadError; } if (filesize < Header::RecordSize) bytes_read = filesize; if (d->outFile.isOpen()) { #if CONFIG_QT4 if(d->outFile.write(buff,bytes_read)!=bytes_read) { fprintf(stderr, "[%s] %s @%d: Failed to write %s\n",__FILE__,__PRETTY_FUNCTION__,__LINE__,qPrintable(d->outFile.fileName())); #else if(d->outFile.writeBlock(buff,bytes_read)!=bytes_read) { fprintf(stderr, "[%s] %s @%d: Failed to write %s\n",__FILE__,__PRETTY_FUNCTION__,__LINE__,qPrintable(d->outFile.name())); #endif d->outFile.close(); } /*if (fwrite(buff, 1, bytes_read, f)!= bytes_read) { fprintf(stderr, "Failed write\n"); fclose(f); f = NULL; }*/ } #if USE_SLOT forceShowMessage(1000); emit byteProcessed(d->processedSize+=Header::RecordSize);//bytes_read); #else estimate(); progressHandler->Progress(d->current_fileName, d->size, d->processedSize+=Header::RecordSize, d->totalSize, d->speed, d->elapsed, d->left); #endif filesize -= bytes_read; } //emit byteProcessed(processedSize+=size); if(d->outFile.isOpen()) d->outFile.close(); } close(); } Archive::Error QTar::extract(const QString& archive,const QString& dir) { setArchive(archive); setOutDir(dir); return extract(); }