Added tag v0.12 for changeset d3934b75e5e7
[hvf.git] / installer / cpio.c
blob4708540551063172ad682560f16061f35f83061b
1 /*
2 * Copyright (c) 2011 Josef 'Jeff' Sipek
3 */
4 #include "loader.h"
5 #include <string.h>
6 #include <ebcdic.h>
8 struct cpio_hdr {
9 u8 magic[6];
10 u8 dev[6];
11 u8 ino[6];
12 u8 mode[6];
13 u8 uid[6];
14 u8 gid[6];
15 u8 nlink[6];
16 u8 rdev[6];
17 u8 mtime[11];
18 u8 namesize[6];
19 u8 filesize[11];
20 u8 data[0];
23 struct table {
24 char *arch;
25 char fn[8];
26 char ft[8];
27 int lrecl;
28 int text;
29 u32 lba; /* 0 means undef */
32 static struct table table[] = {
33 {"hvf.directory", "HVF ", "DIRECT ", 80, 1, 0},
34 {"system.config", "SYSTEM ", "CONFIG ", 80, 1, 0},
35 {"local-3215.txt", "HVF ", "LOGO ", 80, 1, 0},
36 {"hvf", "HVF ", "ELF ", 4096, 0, 0},
37 {"eckd.rto", "ECKDLOAD", "BIN ", 4096, 0, 1},
38 {"loader.rto", "DASDLOAD", "BIN ", 4096, 0, 2},
39 {"installed_files.txt", "HVF ", "TEXT ", 80, 1, 0},
40 {"8ball", "8BALL ", "NSS ", 4096, 0, 0},
41 {"ipldev", "IPLDEV ", "NSS ", 4096, 0, 0},
42 {"login", "LOGIN ", "NSS ", 4096, 0, 0},
43 {"", "" , "" , -1, -1, 0},
46 static void save_file(struct table *te, int filesize, u8 *buf)
48 char pbuf[100];
49 struct FST fst;
50 int ret;
51 int rec;
53 ret = find_file(te->fn, te->ft, &fst);
54 if (!ret) {
55 wto("File '");
56 wto(te->fn);
57 wto("' already exists on the device.\n");
58 wto("The device has been left unmodified.\n");
59 die();
62 ret = create_file(te->fn, te->ft, te->lrecl, &fst);
63 if (ret) {
64 wto("Could not create file '");
65 wto(te->fn);
66 wto("'.\n");
67 die();
70 if (te->text)
71 ascii2ebcdic(buf, filesize);
73 if (te->lba) {
74 if (filesize > te->lrecl)
75 die();
76 snprintf(pbuf, 100, "special file, writing copy of data to LBA %d\n",
77 te->lba);
78 wto(pbuf);
79 write_blk(buf, te->lba);
82 for(rec=0; rec<(filesize/te->lrecl); rec++)
83 append_record(&fst, buf + (rec * te->lrecl));
85 if (filesize % te->lrecl) {
86 u8 buf2[te->lrecl];
88 memset(buf2, 0, te->lrecl);
89 memcpy(buf2, buf + (rec * te->lrecl), filesize % te->lrecl);
91 append_record(&fst, buf2);
95 static u32 getnumber(u8 *data, int digits)
97 u32 ret = 0;
99 for(;digits; digits--, data++)
100 ret = (ret * 8) + (*data - '0');
102 return ret;
105 static void readcard(u8 *buf)
107 static int eof;
108 int ret;
109 struct ccw ccw;
111 if (eof)
112 return;
114 ccw.cmd = 0x02;
115 ccw.flags = 0;
116 ccw.count = 80;
117 ccw.addr = ADDR31(buf);
119 ORB.param = 0x12345678,
120 ORB.f = 1,
121 ORB.lpm = 0xff,
122 ORB.addr = ADDR31(&ccw);
124 ret = __do_io(ipl_sch);
125 if (ret == 0x01) {
126 eof = 1;
127 return; // end of media
130 if (ret)
131 die();
134 void unload_archive(void)
136 char printbuf[132];
137 struct cpio_hdr *hdr;
138 u8 *dasd_buf;
139 int save;
140 int fill;
141 int i;
143 u32 filesize;
144 u32 namesize;
146 dasd_buf = malloc(2*1024*1024);
147 hdr = (void*) dasd_buf;
149 wto("\n");
151 fill = 0;
152 while(1) {
153 /* read a file header */
154 if (fill < sizeof(struct cpio_hdr)) {
155 readcard(dasd_buf + fill);
156 fill += 80;
159 namesize = getnumber(hdr->namesize, 6);
160 filesize = getnumber(hdr->filesize, 11);
162 while(namesize + sizeof(struct cpio_hdr) > fill) {
163 readcard(dasd_buf + fill);
164 fill += 80;
167 if ((namesize == 11) &&
168 !strncmp("TRAILER!!!", (char*) hdr->data, 10))
169 break;
171 save = 0;
172 for(i=0; table[i].lrecl != -1; i++) {
173 if (!strcmp((char*) hdr->data, table[i].arch)) {
174 save = 1;
175 break;
179 if (save) {
180 snprintf(printbuf, 132, "processing '%.8s' '%.8s' => '%s'\n",
181 table[i].fn, table[i].fn + 8, (char*) hdr->data);
182 wto(printbuf);
183 } else {
184 snprintf(printbuf, 132, "skipping '%s'\n",
185 (char*) hdr->data);
186 wto(printbuf);
189 fill -= (sizeof(struct cpio_hdr) + namesize);
190 memmove(hdr, hdr->data + namesize, fill);
192 /* read the entire file into storage (assuming it's <= 1MB) */
193 while(fill < filesize) {
194 readcard(dasd_buf + fill);
195 fill += 80;
198 if (save)
199 save_file(&table[i], filesize, dasd_buf);
201 fill -= filesize;
202 memmove(dasd_buf, dasd_buf + filesize, fill);