Skip to content

Instantly share code, notes, and snippets.

@supki
Created December 3, 2013 21:16
Show Gist options
  • Save supki/7777635 to your computer and use it in GitHub Desktop.
Save supki/7777635 to your computer and use it in GitHub Desktop.
maksenov@supki-laptop:~/playground/tar% time ./Main > /dev/null
./Main > /dev/null 0.16s user 0.09s system 99% cpu 0.250 total
maksenov@supki-laptop:~/playground/tar% time ./a.out > /dev/null
./a.out > /dev/null 0.01s user 0.03s system 98% cpu 0.037 total
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
const char * kTarFilePath = "/home/maksenov/.cabal/packages/hackage.haskell.org/00-index.tar";
int octal_string_to_int(char *current_char, unsigned int size)
{
unsigned int output = 0;
while (size > 0)
{
output = output * 8 + *current_char - '0';
current_char++;
size--;
}
return output;
}
int parse_header(int fd)
{
char header[135];
int res = read(fd, header, 135);
if (res < 135)
{
return 0;
}
printf("%s\n", header);
int size = octal_string_to_int(&header[124], 11);
int skip = (512 - 135) + ((size / 512) + (size % 512 ? 1 : 0)) * 512;
return skip;
}
int main()
{
int fd = open(kTarFilePath, O_RDONLY);
int offset;
while (offset = parse_header(fd))
{
lseek(fd, offset, SEEK_CUR);
}
close(fd);
return EXIT_SUCCESS;
}
module Main (main) where
import Control.Monad
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString hiding (putStrLn)
import qualified Data.ByteString.Char8 as ByteString (putStrLn)
import Data.Char (ord)
import System.IO
import System.IO.Error
tar :: FilePath
tar = "/home/maksenov/.cabal/packages/hackage.haskell.org/00-index.tar"
main :: IO ()
main = do
h <- openFile tar ReadMode
parseHeader h
`catchIOError`
\_ -> return ()
parseHeader :: Handle -> IO ()
parseHeader h = do
bs <- ByteString.hGet h 135
unless (ByteString.length bs < 135) $ do
let (path, _) = ByteString.breakByte 0 bs
size = parseSize bs
ByteString.putStrLn path
hSeek h RelativeSeek ((512 - 135) + ((size `quot` 512) + (if size `rem` 512 > 0 then 1 else 0)) * 512);
parseHeader h
parseSize :: ByteString -> Integer
parseSize =
ByteString.foldl' (\a x -> a * 8 + fi x - fi (ord '0')) 0 . ByteString.take 11 . ByteString.drop 124
fi :: Integral a => a -> Integer
fi = fromIntegral
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment