Skip to content

Commit b0f6f0a

Browse files
committed
Extract old cpio tapes.
1 parent 498b1d0 commit b0f6f0a

File tree

2 files changed

+72
-3
lines changed

2 files changed

+72
-3
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,4 @@ In addition, some mini and micro computer program formats are supported:
6666
- CROSS "ASCII HEX" files.
6767
- Atari DOS executables.
6868
- Imlac "speciall TTY" files.
69+
- Harris HCX/UX cpio.

old-cpio.c

+71-3
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
#include <stdlib.h>
44
#include <stdint.h>
55
#include <string.h>
6+
#include <fcntl.h>
7+
#include <sys/stat.h>
8+
#include <sys/time.h>
9+
#include <sys/types.h>
610

711
#define RECORD_SIZE 5120
812
static uint8_t buffer[2 * RECORD_SIZE];
913
static uint32_t buf_size = RECORD_SIZE;
1014
static uint8_t *ptr = &buffer[RECORD_SIZE];
1115
static char name[65535];
16+
static int extract = 0;
1217

1318
static uint8_t
1419
read_frame (void)
@@ -114,12 +119,58 @@ read_octal (uint8_t *data, int size)
114119
return strtoul (tmp, NULL, 8);
115120
}
116121

122+
static void
123+
mkdirs (char *dir)
124+
{
125+
char *p = dir;
126+
for (;;)
127+
{
128+
p = strchr (p, '/');
129+
if (p == NULL)
130+
return;
131+
*p = 0;
132+
mkdir (dir, 0700);
133+
*p++ = '/';
134+
}
135+
}
136+
137+
static FILE *
138+
open_file (char *name, mode_t mode)
139+
{
140+
int fd;
141+
142+
if (*name == '/')
143+
name++;
144+
145+
mkdirs (name);
146+
147+
if (mode & 040000)
148+
{
149+
mkdir (name, mode & 0777);
150+
return NULL;
151+
}
152+
153+
fd = creat (name, mode & 0777);
154+
return fdopen (fd, "w");
155+
}
156+
157+
static void
158+
timestamp (char *name, time_t timestamp)
159+
{
160+
struct timeval tv[2];
161+
tv[0].tv_sec = timestamp;
162+
tv[0].tv_usec = 0;
163+
tv[1] = tv[0];
164+
utimes (name, tv);
165+
}
166+
117167
static void
118168
read_file (void)
119169
{
120170
uint32_t i, mode, uid, gid, links, mtime, name_size, file_size;
121171
uint8_t *data;
122172
uint8_t adjust = 0;
173+
FILE *f = NULL;
123174
time_t t;
124175
char *s;
125176

@@ -172,11 +223,22 @@ read_file (void)
172223
printf ("%06o %3u %5u %5u %7u %s %s\n",
173224
mode, links, uid, gid, file_size, s, name);
174225

175-
if (file_size & 1)
176-
file_size += adjust;
226+
if (extract)
227+
f = open_file (name, mode);
228+
229+
/* The file data must start on an even boundary. */
230+
if ((ptr - buffer) & 1)
231+
read_data (adjust);
177232
for (i = 0; i < file_size; i++)
178233
{
179234
data = read_data (1);
235+
if (f)
236+
fputc (*data, f);
237+
}
238+
if (f)
239+
{
240+
fclose (f);
241+
timestamp (name, mtime);
180242
}
181243
}
182244

@@ -186,8 +248,14 @@ read_file (void)
186248

187249
}
188250

189-
int main (void)
251+
int main (int argc, char **argv)
190252
{
253+
if (argc == 2 && strcmp (argv[1], "-x") == 0)
254+
{
255+
extract = 1;
256+
umask (0);
257+
}
258+
191259
for (;;)
192260
read_file ();
193261

0 commit comments

Comments
 (0)