2 * Copyright (c) 2001, Robert Collins
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * A copy of the GNU General Public License can be found at
12 * Written by Robert Collins <rbtcollins@hotmail.com>
16 /* An individual stream from a tar archive. */
21 #include "io_stream.h"
24 #include "archive_tar.h"
26 archive_tar_file::archive_tar_file (tar_state
& newstate
):read_something (false), state (newstate
)
30 archive_tar_file::~archive_tar_file ()
33 state
.header_read
= 0;
37 ssize_t
archive_tar_file::read (void *buffer
, size_t len
)
39 /* how many bytes do we want to give the user */
41 want
= std::min ((off_t
) len
, state
.file_length
- state
.file_offset
);
42 /* how many do we need to read after that to line up the file pointer */
44 roundup
= (512 - (want
% 512)) % 512;
45 read_something
= true;
49 char *p
= (char *)buffer
;
52 ssize_t got
= state
.parent
->read (p
, need
);
55 /* unexpected EOF or read error in the tar parent stream */
56 /* the user can query the parent for the error */
68 ssize_t got2
= state
.parent
->read (p
, roundup
);
71 /* unexpected EOF or read error in the tar parent stream */
72 /* the user can query the parent for the error */
80 state
.file_offset
+= want
;
86 /* provide data to (double duh!) */
87 ssize_t
archive_tar_file::write (const void *buffer
, size_t len
)
89 /* write not supported */
90 state
.lasterr
= EBADF
;
94 /* read data without removing it from the class's internal buffer */
95 ssize_t
archive_tar_file::peek (void *buffer
, size_t len
)
98 want
= std::min ((off_t
) len
, state
.file_length
- state
.file_offset
);
102 got
= state
.parent
->peek (buffer
, want
);
109 /* unexpected EOF or read error in the tar parent stream */
110 /* the user can query the parent for the error */
119 archive_tar_file::tell ()
121 return state
.file_offset
;
125 archive_tar_file::seek (off_t where
, io_stream_seek_t whence
)
127 /* nothing needs seeking here yet. Implement when needed
129 state
.lasterr
= EINVAL
;
133 /* try guessing this one */
135 archive_tar_file::error ()
137 return state
.lasterr
;
141 archive_tar_file::get_mtime ()
144 sscanf (state
.tar_header
.mtime
, "%lo", &mtime
);
145 return (time_t) mtime
;
149 archive_tar_file::get_mode ()
152 sscanf (state
.tar_header
.mode
, "%lo", &mode
);
153 return (mode_t
) mode
;