14 #define str(s) xstr(s)
16 static unsigned int offset;
17 static unsigned int ino = 721;
21 int (*handler)(const char *line);
24 static void push_string(const char *name)
26 unsigned int name_len = strlen(name) + 1;
33 static void push_pad (void)
41 static void push_rest(const char *name)
43 unsigned int name_len = strlen(name) + 1;
50 tmp_ofs = name_len + 110;
58 static void push_hdr(const char *s)
64 static void cpio_trailer(void)
67 const char name[] = "TRAILER!!!";
69 sprintf(s, "%s%08X%08X%08lX%08lX%08X%08lX"
70 "%08X%08X%08X%08X%08X%08X%08X",
83 (unsigned)strlen(name) + 1, /* namesize */
88 while (offset % 512) {
94 static int cpio_mkdir(const char *name, unsigned int mode,
98 time_t mtime = time(NULL);
100 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
101 "%08X%08X%08X%08X%08X%08X%08X",
102 "070701", /* magic */
104 S_IFDIR | mode, /* mode */
105 (long) uid, /* uid */
106 (long) gid, /* gid */
108 (long) mtime, /* mtime */
114 (unsigned)strlen(name) + 1,/* namesize */
121 static int cpio_mkdir_line(const char *line)
123 char name[PATH_MAX + 1];
129 if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
130 fprintf(stderr, "Unrecognized dir format '%s'", line);
133 rc = cpio_mkdir(name, mode, uid, gid);
138 static int cpio_mknod(const char *name, unsigned int mode,
139 uid_t uid, gid_t gid, char dev_type,
140 unsigned int maj, unsigned int min)
143 time_t mtime = time(NULL);
150 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
151 "%08X%08X%08X%08X%08X%08X%08X",
152 "070701", /* magic */
155 (long) uid, /* uid */
156 (long) gid, /* gid */
158 (long) mtime, /* mtime */
164 (unsigned)strlen(name) + 1,/* namesize */
171 static int cpio_mknod_line(const char *line)
173 char name[PATH_MAX + 1];
182 if (7 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u",
183 name, &mode, &uid, &gid, &dev_type, &maj, &min)) {
184 fprintf(stderr, "Unrecognized nod format '%s'", line);
187 rc = cpio_mknod(name, mode, uid, gid, dev_type, maj, min);
192 /* Not marked static to keep the compiler quiet, as no one uses this yet... */
193 static int cpio_mkfile(const char *name, const char *location,
194 unsigned int mode, uid_t uid, gid_t gid)
197 char *filebuf = NULL;
206 retval = stat (location, &buf);
208 fprintf (stderr, "File %s could not be located\n", location);
212 file = open (location, O_RDONLY);
214 fprintf (stderr, "File %s could not be opened for reading\n", location);
218 filebuf = malloc(buf.st_size);
220 fprintf (stderr, "out of memory\n");
224 retval = read (file, filebuf, buf.st_size);
226 fprintf (stderr, "Can not read %s file\n", location);
230 sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX"
231 "%08X%08X%08X%08X%08X%08X%08X",
232 "070701", /* magic */
235 (long) uid, /* uid */
236 (long) gid, /* gid */
238 (long) buf.st_mtime, /* mtime */
239 (int) buf.st_size, /* filesize */
244 (unsigned)strlen(name) + 1,/* namesize */
250 for (i = 0; i < buf.st_size; ++i)
251 fputc(filebuf[i], stdout);
252 offset += buf.st_size;
257 if (filebuf) free(filebuf);
258 if (file >= 0) close(file);
262 static int cpio_mkfile_line(const char *line)
264 char name[PATH_MAX + 1];
265 char location[PATH_MAX + 1];
271 if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, location, &mode, &uid, &gid)) {
272 fprintf(stderr, "Unrecognized file format '%s'", line);
275 rc = cpio_mkfile(name, location, mode, uid, gid);
280 void usage(const char *prog)
282 fprintf(stderr, "Usage:\n"
285 "<cpio_list> is a file containing newline separated entries that\n"
286 "describe the files to be included in the initramfs archive:\n"
289 "file <name> <location> <mode> <uid> <gid> \n"
290 "dir <name> <mode> <uid> <gid>\n"
291 "nod <name> <mode> <uid> <gid> <dev_type> <maj> <min>\n"
293 "<name> name of the file/dir/nod in the archive\n"
294 "<location> location of the file in the current filesystem\n"
295 "<mode> mode/permissions of the file\n"
296 "<uid> user id (0=root)\n"
297 "<gid> group id (0=root)\n"
298 "<dev_type> device type (b=block, c=character)\n"
299 "<maj> major number of nod\n"
300 "<min> minor number of nod\n"
303 "# A simple initramfs\n"
304 "dir /dev 0755 0 0\n"
305 "nod /dev/console 0600 0 0 c 5 1\n"
306 "dir /root 0700 0 0\n"
307 "dir /sbin 0755 0 0\n"
308 "file /sbin/kinit /usr/src/klibc/kinit/kinit 0755 0 0\n",
312 struct file_type file_type_table[] = {
315 .handler = cpio_mkfile_line,
318 .handler = cpio_mknod_line,
321 .handler = cpio_mkdir_line,
328 #define LINE_SIZE (2 * PATH_MAX + 50)
330 int main (int argc, char *argv[])
333 char line[LINE_SIZE];
343 if (! (cpio_list = fopen(argv[1], "r"))) {
344 fprintf(stderr, "ERROR: unable to open '%s': %s\n\n",
345 argv[1], strerror(errno));
350 while (fgets(line, LINE_SIZE, cpio_list)) {
352 size_t slen = strlen(line);
357 /* comment - skip to next line */
361 if (! (type = strtok(line, " \t"))) {
363 "ERROR: incorrect format, could not locate file type line %d: '%s'\n",
373 if (slen == strlen(type)) {
374 /* must be an empty line */
378 if (! (args = strtok(NULL, "\n"))) {
380 "ERROR: incorrect format, newline required line %d: '%s'\n",
385 for (type_idx = 0; file_type_table[type_idx].type; type_idx++) {
387 if (! strcmp(line, file_type_table[type_idx].type)) {
388 if ((rc = file_type_table[type_idx].handler(args))) {
390 fprintf(stderr, " line %d\n", line_nr);
396 if (NULL == file_type_table[type_idx].type) {
397 fprintf(stderr, "unknown file type line %d: '%s'\n",