protected function process_header($block, $handler) {
        // If the block consists entirely of nulls, ignore it. (This happens
        // twice at end of archive.)
        if ($block === str_pad('', tgz_packer::TAR_BLOCK_SIZE, "\0")) {
            return;
        }

        // struct header_posix_ustar {
        //    char name[100];
        $name = rtrim(substr($block, 0, 100), "\0");

        //    char mode[8];
        //    char uid[8];
        //    char gid[8];
        //    char size[12];
        $filesize = octdec(substr($block, 124, 11));

        //    char mtime[12];
        $mtime = octdec(substr($block, 136, 11));

        //    char checksum[8];
        //    char typeflag[1];
        $typeflag = substr($block, 156, 1);

        //    char linkname[100];
        //    char magic[6];
        $magic = substr($block, 257, 6);
        if ($magic !== "ustar\0" && $magic !== "ustar ") {
            // There are two checks above; the first is the correct POSIX format
            // and the second is for GNU tar default format.
            throw new moodle_exception('errorprocessingarchive', '', '', null,
                    'Header does not have POSIX ustar magic string');
        }

        //    char version[2];
        //    char uname[32];
        //    char gname[32];
        //    char devmajor[8];
        //    char devminor[8];
        //    char prefix[155];
        $prefix = rtrim(substr($block, 345, 155), "\0");

        //    char pad[12];
        // };

        $archivepath = ltrim($prefix . '/' . $name, '/');

        // For security, ensure there is no .. folder in the archivepath.
        $archivepath = clean_param($archivepath, PARAM_PATH);

        // Handle file depending on the type.
        switch ($typeflag) {
            case '1' :
            case '2' :
            case '3' :
            case '4' :
            case '6' :
            case '7' :
                // Ignore these special cases.
                break;

            case '5' :
                // Directory.
                if ($this->mode === self::MODE_LIST) {
                    $this->listresults[] = (object)array(
                            'original_pathname' => $archivepath,
                            'pathname' => $archivepath,
                            'mtime' => $mtime,
                            'is_directory' => true,
                            'size' => 0);
                } else if ($handler->tgz_directory($archivepath, $mtime)) {
                    $this->results[$archivepath] = true;
                }
                break;

            default:
                // All other values treated as normal file.
                $this->start_current_file($archivepath, $filesize, $mtime, $handler);
                break;
        }
    }