1#include <stdio.h>
2#include <stdlib.h>
3#include <sys/types.h>
4#include <sys/stat.h>
5#include <string.h>
6#include <unistd.h>
7#include <time.h>
8#include <fcntl.h>
9
10static unsigned int offset;
11static unsigned int ino = 721;
12
13static void push_string(const char *name)
14{
15 unsigned int name_len = strlen(name) + 1;
16
17 fputs(name, stdout);
18 putchar(0);
19 offset += name_len;
20}
21
22static void push_pad (void)
23{
24 while (offset & 3) {
25 putchar(0);
26 offset++;
27 }
28}
29
30static void push_rest(const char *name)
31{
32 unsigned int name_len = strlen(name) + 1;
33 unsigned int tmp_ofs;
34
35 fputs(name, stdout);
36 putchar(0);
37 offset += name_len;
38
39 tmp_ofs = name_len + 110;
40 while (tmp_ofs & 3) {
41 putchar(0);
42 offset++;
43 tmp_ofs++;
44 }
45}
46
47static void push_hdr(const char *s)
48{
49 fputs(s, stdout);
50 offset += 110;
51}
52
53static void cpio_trailer(void)
54{
55 char s[256];
56 const char name[] = "TRAILER!!!";
57
58 sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX"
59 "%08X%08X%08X%08X%08X%08X%08X",
60 "070701",
61 0,
62 0,
63 (long) 0,
64 (long) 0,
65 1,
66 (long) 0,
67 0,
68 0,
69 0,
70 0,
71 0,
72 (unsigned)strlen(name) + 1,
73 0);
74 push_hdr(s);
75 push_rest(name);
76
77 while (offset % 512) {
78 putchar(0);
79 offset++;
80 }
81}
82
83static void cpio_mkdir(const char *name, unsigned int mode,
84 uid_t uid, gid_t gid)
85{
86 char s[256];
87 time_t mtime = time(NULL);
88
89 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
90 "%08X%08X%08X%08X%08X%08X%08X",
91 "070701",
92 ino++,
93 S_IFDIR | mode,
94 (long) uid,
95 (long) gid,
96 2,
97 (long) mtime,
98 0,
99 3,
100 1,
101 0,
102 0,
103 (unsigned)strlen(name) + 1,
104 0);
105 push_hdr(s);
106 push_rest(name);
107}
108
109static void cpio_mknod(const char *name, unsigned int mode,
110 uid_t uid, gid_t gid, int dev_type,
111 unsigned int maj, unsigned int min)
112{
113 char s[256];
114 time_t mtime = time(NULL);
115
116 if (dev_type == 'b')
117 mode |= S_IFBLK;
118 else
119 mode |= S_IFCHR;
120
121 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
122 "%08X%08X%08X%08X%08X%08X%08X",
123 "070701",
124 ino++,
125 mode,
126 (long) uid,
127 (long) gid,
128 1,
129 (long) mtime,
130 0,
131 3,
132 1,
133 maj,
134 min,
135 (unsigned)strlen(name) + 1,
136 0);
137 push_hdr(s);
138 push_rest(name);
139}
140
141
142void cpio_mkfile(const char *filename, const char *location,
143 unsigned int mode, uid_t uid, gid_t gid)
144{
145 char s[256];
146 char *filebuf;
147 struct stat buf;
148 int file;
149 int retval;
150 int i;
151
152 mode |= S_IFREG;
153
154 retval = stat (filename, &buf);
155 if (retval) {
156 fprintf (stderr, "Filename %s could not be located\n", filename);
157 goto error;
158 }
159
160 file = open (filename, O_RDONLY);
161 if (file < 0) {
162 fprintf (stderr, "Filename %s could not be opened for reading\n", filename);
163 goto error;
164 }
165
166 filebuf = malloc(buf.st_size);
167 if (!filebuf) {
168 fprintf (stderr, "out of memory\n");
169 goto error_close;
170 }
171
172 retval = read (file, filebuf, buf.st_size);
173 if (retval < 0) {
174 fprintf (stderr, "Can not read %s file\n", filename);
175 goto error_free;
176 }
177
178 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
179 "%08X%08X%08X%08X%08X%08X%08X",
180 "070701",
181 ino++,
182 mode,
183 (long) uid,
184 (long) gid,
185 1,
186 (long) buf.st_mtime,
187 (int) buf.st_size,
188 3,
189 1,
190 0,
191 0,
192 (unsigned)strlen(location) + 1,
193 0);
194 push_hdr(s);
195 push_string(location);
196 push_pad();
197
198 for (i = 0; i < buf.st_size; ++i)
199 fputc(filebuf[i], stdout);
200 offset += buf.st_size;
201 close(file);
202 free(filebuf);
203 push_pad();
204 return;
205
206error_free:
207 free(filebuf);
208error_close:
209 close(file);
210error:
211 exit(-1);
212}
213
214int main (int argc, char *argv[])
215{
216 cpio_mkdir("/dev", 0755, 0, 0);
217 cpio_mknod("/dev/console", 0600, 0, 0, 'c', 5, 1);
218 cpio_mkdir("/root", 0700, 0, 0);
219 cpio_trailer();
220
221 exit(0);
222
223
224 return 0;
225 (void) argc;
226 (void) argv;
227}
228
229