uc-sdk
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
mkromfs.c
Go to the documentation of this file.
1 #ifdef _WIN32
2 #include <windows.h>
3 #endif
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <stdint.h>
8 #include <dirent.h>
9 #include <string.h>
10 
11 #define hash_init 5381
12 
13 uint32_t hash_djb2(const uint8_t * str, uint32_t hash) {
14  int c;
15 
16  while ((c = *str++))
17  hash = ((hash << 5) + hash) ^ c;
18 
19  return hash;
20 }
21 
22 void usage(const char * binname) {
23  printf("Usage: %s [-d <dir>] [outfile]\n", binname);
24  exit(-1);
25 }
26 
27 void processdir(DIR * dirp, const char * curpath, FILE * outfile, const char * prefix) {
28  char fullpath[1024];
29  char buf[16 * 1024];
30  struct dirent * ent;
31  DIR * rec_dirp;
32  uint32_t cur_hash = hash_djb2((const uint8_t *) curpath, hash_init);
33  uint32_t size, w, hash;
34  uint8_t b;
35  FILE * infile;
36 
37  while ((ent = readdir(dirp))) {
38  strcpy(fullpath, prefix);
39  strcat(fullpath, "/");
40  strcat(fullpath, curpath);
41  strcat(fullpath, ent->d_name);
42  #ifdef _WIN32
43  if (GetFileAttributes(fullpath) & FILE_ATTRIBUTE_DIRECTORY) {
44  #else
45  if (ent->d_type == DT_DIR) {
46  #endif
47  if (strcmp(ent->d_name, ".") == 0)
48  continue;
49  if (strcmp(ent->d_name, "..") == 0)
50  continue;
51  strcat(fullpath, "/");
52  rec_dirp = opendir(fullpath);
53  processdir(rec_dirp, fullpath + strlen(prefix) + 1, outfile, prefix);
54  closedir(rec_dirp);
55  } else {
56  hash = hash_djb2((const uint8_t *) ent->d_name, cur_hash);
57  infile = fopen(fullpath, "rb");
58  if (!infile) {
59  perror("opening input file");
60  exit(-1);
61  }
62  b = (hash >> 0) & 0xff; fwrite(&b, 1, 1, outfile);
63  b = (hash >> 8) & 0xff; fwrite(&b, 1, 1, outfile);
64  b = (hash >> 16) & 0xff; fwrite(&b, 1, 1, outfile);
65  b = (hash >> 24) & 0xff; fwrite(&b, 1, 1, outfile);
66  fseek(infile, 0, SEEK_END);
67  size = ftell(infile);
68  fseek(infile, 0, SEEK_SET);
69  b = (size >> 0) & 0xff; fwrite(&b, 1, 1, outfile);
70  b = (size >> 8) & 0xff; fwrite(&b, 1, 1, outfile);
71  b = (size >> 16) & 0xff; fwrite(&b, 1, 1, outfile);
72  b = (size >> 24) & 0xff; fwrite(&b, 1, 1, outfile);
73  while (size) {
74  w = size > 16 * 1024 ? 16 * 1024 : size;
75  w = fread(buf, 1, w, infile);
76  fwrite(buf, 1, w, outfile);
77  size -= w;
78  }
79  fclose(infile);
80  }
81  }
82 }
83 
84 int main(int argc, char ** argv) {
85  char * binname = *argv++;
86  char * o;
87  char * outname = NULL;
88  char * dirname = ".";
89  uint64_t z = 0;
90  FILE * outfile;
91  DIR * dirp;
92 
93  while ((o = *argv++)) {
94  if (*o == '-') {
95  o++;
96  switch (*o) {
97  case 'd':
98  dirname = *argv++;
99  break;
100  default:
101  usage(binname);
102  break;
103  }
104  } else {
105  if (outname)
106  usage(binname);
107  outname = o;
108  }
109  }
110 
111  if (!outname)
112  outfile = stdout;
113  else
114  outfile = fopen(outname, "wb");
115 
116  if (!outfile) {
117  perror("opening output file");
118  exit(-1);
119  }
120 
121  dirp = opendir(dirname);
122  if (!dirp) {
123  perror("opening directory");
124  exit(-1);
125  }
126 
127  processdir(dirp, "", outfile, dirname);
128  fwrite(&z, 1, 8, outfile);
129  if (outname)
130  fclose(outfile);
131  closedir(dirp);
132 
133  return 0;
134 }