Skip to content

Commit 498b1d0

Browse files
committed
List old cpio tapes.
Supported formats: - Harris CX/UX ASCII cpio. - NS32000 binary cpio.
1 parent a566950 commit 498b1d0

File tree

3 files changed

+201
-1
lines changed

3 files changed

+201
-1
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ mini-dumper
3232
linum
3333
tendmp
3434
acct
35+
old-cpio

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ OBJS = pdp10-opc.o info.o dis.o symbols.o \
1414
UTILS = cat36 itsarc magdmp magfrm dskdmp dump \
1515
macdmp macro-tapes tape-dir harscntopbm palx cross \
1616
ipak kldcp klfedr scrmbl unscr tvpic tito dart od10 \
17-
constantinople dumper mini-dumper linum tendmp acct
17+
constantinople dumper mini-dumper linum tendmp acct \
18+
old-cpio
1819

1920
all: dis10 $(UTILS) check
2021

@@ -85,6 +86,9 @@ dumper: dumper.o $(OBJS) $(LIBWORD)
8586
mini-dumper: dumper
8687
ln -f $< $@
8788

89+
old-cpio: old-cpio.o
90+
$(CC) $(CFLAGS) $^ -o $@
91+
8892
od10: od10.o $(OBJS) $(LIBWORD)
8993
$(CC) $(CFLAGS) $^ -o $@
9094

old-cpio.c

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
#include <time.h>
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
#include <stdint.h>
5+
#include <string.h>
6+
7+
#define RECORD_SIZE 5120
8+
static uint8_t buffer[2 * RECORD_SIZE];
9+
static uint32_t buf_size = RECORD_SIZE;
10+
static uint8_t *ptr = &buffer[RECORD_SIZE];
11+
static char name[65535];
12+
13+
static uint8_t
14+
read_frame (void)
15+
{
16+
int c;
17+
c = getchar ();
18+
if (c == EOF)
19+
{
20+
printf ("Physical end of tape.\n");
21+
exit (0);
22+
}
23+
return c;
24+
}
25+
26+
static uint32_t
27+
read_size (void)
28+
{
29+
uint8_t x1, x2, x3, x4;
30+
x1 = read_frame ();
31+
x2 = read_frame ();
32+
x3 = read_frame ();
33+
x4 = read_frame ();
34+
return x1 | (x2 << 8) | (x3 << 16) | (x4 << 24);
35+
}
36+
37+
static uint32_t
38+
read_record (uint8_t *buffer)
39+
{
40+
uint32_t i, size;
41+
42+
size = read_size ();
43+
if (size & 0x80000000)
44+
return size;
45+
else if (size > 0)
46+
{
47+
for (i = 0; i < size; i++)
48+
*buffer++ = read_frame ();
49+
if (size != read_size ())
50+
{
51+
printf ("Error in image.\n");
52+
exit (1);
53+
}
54+
}
55+
56+
return size;
57+
}
58+
59+
static uint8_t *
60+
read_data (uint32_t size)
61+
{
62+
if (ptr >= &buffer[RECORD_SIZE])
63+
{
64+
memcpy (buffer, &buffer[RECORD_SIZE], RECORD_SIZE);
65+
buf_size -= RECORD_SIZE;
66+
ptr -= RECORD_SIZE;
67+
}
68+
69+
if (ptr + size > &buffer[buf_size])
70+
{
71+
int eof = 0;
72+
uint32_t n;
73+
74+
for (;;)
75+
{
76+
n = read_record (&buffer[buf_size]);
77+
eof = (n == 0) ? eof+1 : 0;
78+
if (n == 0)
79+
{
80+
printf ("Tape mark.\n");
81+
if (eof == 2)
82+
printf ("Logical end of tape.\n");
83+
}
84+
else if (n & 0x80000000)
85+
printf ("Tape error.\n");
86+
else
87+
break;
88+
}
89+
buf_size += n;
90+
}
91+
92+
ptr += size;
93+
return ptr - size;
94+
}
95+
96+
static uint32_t
97+
read_16bit (uint8_t *data)
98+
{
99+
return data[0] | (data[1] << 8);
100+
}
101+
102+
static uint32_t
103+
read_32bit (uint8_t *data)
104+
{
105+
return (read_16bit (data) << 16) | read_16bit (data + 2);
106+
}
107+
108+
static uint32_t
109+
read_octal (uint8_t *data, int size)
110+
{
111+
char tmp[12];
112+
memcpy (tmp, data, size);
113+
tmp[size] = 0;
114+
return strtoul (tmp, NULL, 8);
115+
}
116+
117+
static void
118+
read_file (void)
119+
{
120+
uint32_t i, mode, uid, gid, links, mtime, name_size, file_size;
121+
uint8_t *data;
122+
uint8_t adjust = 0;
123+
time_t t;
124+
char *s;
125+
126+
again:
127+
data = read_data (100);
128+
129+
if (read_16bit (data) == 070707)
130+
{
131+
mode = read_16bit (data + 6);
132+
uid = read_16bit (data + 8);
133+
gid = read_16bit (data + 10);
134+
links = read_16bit (data + 12);
135+
mtime = read_32bit (data + 16);
136+
name_size = read_16bit (data + 20);
137+
file_size = read_32bit (data + 22);
138+
memcpy (name, data + 26, name_size);
139+
ptr = data + 26 + name_size;
140+
adjust = 1;
141+
}
142+
else if (memcmp (data, "070707", 6) == 0)
143+
{
144+
mode = read_octal (data + 18, 6);
145+
uid = read_octal (data + 24, 6);
146+
gid = read_octal (data + 30, 6);
147+
links = read_octal (data + 36, 6);
148+
mtime = read_octal (data + 48, 11);
149+
name_size = read_octal (data + 59, 6);
150+
file_size = read_octal (data + 65, 11);
151+
memcpy (name, data + 76, name_size);
152+
ptr = data + 76 + name_size;
153+
adjust = 0;
154+
}
155+
else
156+
{
157+
printf ("Not a cpio record, spacing forward to next.\n");
158+
read_data (RECORD_SIZE - (ptr - buffer));
159+
goto again;
160+
}
161+
162+
if (file_size == 0 && strcmp (name, "TRAILER!!!") == 0)
163+
{
164+
printf ("Saveset trailer.\n");
165+
read_data (RECORD_SIZE - (ptr - buffer));
166+
}
167+
else
168+
{
169+
t = mtime;
170+
s = ctime (&t);
171+
s[strlen (s) - 1] = 0;
172+
printf ("%06o %3u %5u %5u %7u %s %s\n",
173+
mode, links, uid, gid, file_size, s, name);
174+
175+
if (file_size & 1)
176+
file_size += adjust;
177+
for (i = 0; i < file_size; i++)
178+
{
179+
data = read_data (1);
180+
}
181+
}
182+
183+
/* The next file header must start on an even boundary. */
184+
if ((ptr - buffer) & 1)
185+
read_data (adjust);
186+
187+
}
188+
189+
int main (void)
190+
{
191+
for (;;)
192+
read_file ();
193+
194+
return 0;
195+
}

0 commit comments

Comments
 (0)