14 #define PAD(x) (((x)+3)&~3)
16 #define CLEANMARKER "\x85\x19\x03\x20\x0c\x00\x00\x00\xb1\xb0\x1e\xe4"
17 #define JFFS2_EOF "\xde\xad\xc0\xde"
19 static int last_ino
= 0;
20 static int last_version
= 0;
21 static char *buf
= NULL
;
24 static int mtdofs
= 0;
26 static void prep_eraseblock(void);
28 static void pad(int size
)
30 if ((ofs
% size
== 0) && (ofs
< erasesize
))
33 if (ofs
< erasesize
) {
34 memset(buf
+ ofs
, 0xff, (size
- (ofs
% size
)));
35 ofs
+= (size
- (ofs
% size
));
37 ofs
= ofs
% erasesize
;
39 mtd_erase_block(outfd
, mtdofs
);
40 write(outfd
, buf
, erasesize
);
45 static inline int rbytes(void)
47 return erasesize
- (ofs
% erasesize
);
50 static inline void add_data(char *ptr
, int len
)
52 if (ofs
+ len
> erasesize
) {
56 memcpy(buf
+ ofs
, ptr
, len
);
60 static void prep_eraseblock(void)
65 add_data(CLEANMARKER
, sizeof(CLEANMARKER
) - 1);
68 static int add_dirent(char *name
, char type
, int parent
)
70 struct jffs2_raw_dirent
*de
;
72 if (ofs
- erasesize
< sizeof(struct jffs2_raw_dirent
) + strlen(name
))
77 memset(buf
+ ofs
, 0, sizeof(struct jffs2_raw_dirent
));
78 de
= (struct jffs2_raw_dirent
*) (buf
+ ofs
);
80 de
->magic
= JFFS2_MAGIC_BITMASK
;
81 de
->nodetype
= JFFS2_NODETYPE_DIRENT
;
83 de
->name_crc
= crc32(0, name
, strlen(name
));
86 de
->totlen
= sizeof(*de
) + strlen(name
);
87 de
->hdr_crc
= crc32(0, (void *) de
, sizeof(struct jffs2_unknown_node
) - 4);
88 de
->version
= last_version
++;
90 de
->nsize
= strlen(name
);
91 de
->node_crc
= crc32(0, (void *) de
, sizeof(*de
) - 8);
92 memcpy(de
->name
, name
, strlen(name
));
94 ofs
+= sizeof(struct jffs2_raw_dirent
) + de
->nsize
;
100 static int add_dir(char *name
, int parent
)
102 struct jffs2_raw_inode ri
;
105 inode
= add_dirent(name
, IFTODT(S_IFDIR
), parent
);
107 if (rbytes() < sizeof(ri
))
111 memset(&ri
, 0, sizeof(ri
));
112 ri
.magic
= JFFS2_MAGIC_BITMASK
;
113 ri
.nodetype
= JFFS2_NODETYPE_INODE
;
114 ri
.totlen
= sizeof(ri
);
115 ri
.hdr_crc
= crc32(0, &ri
, sizeof(struct jffs2_unknown_node
) - 4);
118 ri
.mode
= S_IFDIR
| 0755;
120 ri
.atime
= ri
.ctime
= ri
.mtime
= 0;
121 ri
.isize
= ri
.csize
= ri
.dsize
= 0;
123 ri
.node_crc
= crc32(0, &ri
, sizeof(ri
) - 8);
126 add_data((char *) &ri
, sizeof(ri
));
131 static void add_file(char *name
, int parent
)
133 int inode
, f_offset
= 0, fd
;
134 struct jffs2_raw_inode ri
;
136 char wbuf
[4096], *fname
;
139 if (stat(name
, &st
)) {
140 fprintf(stderr
, "File %s does not exist\n", name
);
144 fname
= strrchr(name
, '/');
150 inode
= add_dirent(name
, IFTODT(S_IFREG
), parent
);
151 memset(&ri
, 0, sizeof(ri
));
152 ri
.magic
= JFFS2_MAGIC_BITMASK
;
153 ri
.nodetype
= JFFS2_NODETYPE_INODE
;
156 ri
.mode
= st
.st_mode
;
158 ri
.atime
= st
.st_atime
;
159 ri
.ctime
= st
.st_ctime
;
160 ri
.mtime
= st
.st_mtime
;
161 ri
.isize
= st
.st_size
;
167 fprintf(stderr
, "File %s does not exist\n", name
);
175 len
= rbytes() - sizeof(ri
);
183 if (len
> sizeof(wbuf
))
186 len
= read(fd
, wbuf
, len
);
190 ri
.totlen
= sizeof(ri
) + len
;
191 ri
.hdr_crc
= crc32(0, &ri
, sizeof(struct jffs2_unknown_node
) - 4);
192 ri
.version
= ++last_version
;
193 ri
.offset
= f_offset
;
194 ri
.csize
= ri
.dsize
= len
;
195 ri
.node_crc
= crc32(0, &ri
, sizeof(ri
) - 8);
196 ri
.data_crc
= crc32(0, wbuf
, len
);
198 add_data((char *) &ri
, sizeof(ri
));
207 int mtd_write_jffs2(char *mtd
, char *filename
, char *dir
)
210 int err
= -1, fdeof
= 0;
213 outfd
= mtd_check_open(mtd
);
218 fprintf(stderr
, "Appending %s to jffs2 partition %s\n", filename
, mtd
);
220 buf
= malloc(erasesize
);
222 fprintf(stderr
, "Out of memory!\n");
226 /* parse the structure of the jffs2 first
227 * locate the directory that the file is going to be placed in */
229 struct jffs2_unknown_node
*node
= (struct jffs2_unknown_node
*) buf
;
230 unsigned int ofs
= 0;
232 if (read(outfd
, buf
, erasesize
) != erasesize
) {
238 if (node
->magic
== 0x8519) {
239 fprintf(stderr
, "Error: wrong endianness filesystem\n");
243 /* assume no magic == end of filesystem
244 * the filesystem will probably end with be32(0xdeadc0de) */
245 if (node
->magic
!= 0x1985)
248 while (ofs
< erasesize
) {
249 node
= (struct jffs2_unknown_node
*) (buf
+ ofs
);
250 if (node
->magic
== 0x1985) {
251 ofs
+= PAD(node
->totlen
);
252 if (node
->nodetype
== JFFS2_NODETYPE_DIRENT
) {
253 struct jffs2_raw_dirent
*de
= (struct jffs2_raw_dirent
*) node
;
255 /* is this the right directory name and is it a subdirectory of / */
256 if ((de
->pino
== 1) && !strncmp(de
->name
, dir
, de
->nsize
))
257 target_ino
= de
->ino
;
259 /* store the last inode and version numbers for adding extra files */
260 if (last_ino
< de
->ino
)
262 if (last_version
< de
->version
)
263 last_version
= de
->version
;
272 fprintf(stderr
, "Error: No room for additional data\n");
276 /* jump back one eraseblock */
278 lseek(outfd
, mtdofs
, SEEK_SET
);
286 target_ino
= add_dir(dir
, 1);
288 add_file(filename
, target_ino
);
291 /* add eof marker, pad to eraseblock size and write the data */
292 add_data(JFFS2_EOF
, sizeof(JFFS2_EOF
) - 1);
This page took 0.076356 seconds and 5 git commands to generate.