ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / usr / gen_init_cpio.c
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
10 static unsigned int offset;
11 static unsigned int ino = 721;
12
13 static 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
22 static void push_pad (void)
23 {
24         while (offset & 3) {
25                 putchar(0);
26                 offset++;
27         }
28 }
29
30 static 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
47 static void push_hdr(const char *s)
48 {
49         fputs(s, stdout);
50         offset += 110;
51 }
52
53 static 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",               /* magic */
61                 0,                      /* ino */
62                 0,                      /* mode */
63                 (long) 0,               /* uid */
64                 (long) 0,               /* gid */
65                 1,                      /* nlink */
66                 (long) 0,               /* mtime */
67                 0,                      /* filesize */
68                 0,                      /* major */
69                 0,                      /* minor */
70                 0,                      /* rmajor */
71                 0,                      /* rminor */
72                 (unsigned)strlen(name) + 1, /* namesize */
73                 0);                     /* chksum */
74         push_hdr(s);
75         push_rest(name);
76
77         while (offset % 512) {
78                 putchar(0);
79                 offset++;
80         }
81 }
82
83 static 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",               /* magic */
92                 ino++,                  /* ino */
93                 S_IFDIR | mode,         /* mode */
94                 (long) uid,             /* uid */
95                 (long) gid,             /* gid */
96                 2,                      /* nlink */
97                 (long) mtime,           /* mtime */
98                 0,                      /* filesize */
99                 3,                      /* major */
100                 1,                      /* minor */
101                 0,                      /* rmajor */
102                 0,                      /* rminor */
103                 (unsigned)strlen(name) + 1,/* namesize */
104                 0);                     /* chksum */
105         push_hdr(s);
106         push_rest(name);
107 }
108
109 static 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",               /* magic */
124                 ino++,                  /* ino */
125                 mode,                   /* mode */
126                 (long) uid,             /* uid */
127                 (long) gid,             /* gid */
128                 1,                      /* nlink */
129                 (long) mtime,           /* mtime */
130                 0,                      /* filesize */
131                 3,                      /* major */
132                 1,                      /* minor */
133                 maj,                    /* rmajor */
134                 min,                    /* rminor */
135                 (unsigned)strlen(name) + 1,/* namesize */
136                 0);                     /* chksum */
137         push_hdr(s);
138         push_rest(name);
139 }
140
141 /* Not marked static to keep the compiler quiet, as no one uses this yet... */
142 void 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",               /* magic */
181                 ino++,                  /* ino */
182                 mode,                   /* mode */
183                 (long) uid,             /* uid */
184                 (long) gid,             /* gid */
185                 1,                      /* nlink */
186                 (long) buf.st_mtime,    /* mtime */
187                 (int) buf.st_size,      /* filesize */
188                 3,                      /* major */
189                 1,                      /* minor */
190                 0,                      /* rmajor */
191                 0,                      /* rminor */
192                 (unsigned)strlen(location) + 1,/* namesize */
193                 0);                     /* chksum */
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         
206 error_free:
207         free(filebuf);
208 error_close:
209         close(file);
210 error:
211         exit(-1);
212 }
213
214 int 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         /* silence compiler warnings */
224         return 0;
225         (void) argc;
226         (void) argv;
227 }
228