summaryrefslogtreecommitdiffstats
path: root/cpio
diff options
context:
space:
mode:
authorThe Android Open Source Project2009-01-20 16:04:01 -0600
committerThe Android Open Source Project2009-01-20 16:04:01 -0600
commit8ac3a138168f79b47356fb5aea2f6d95fc3147c6 (patch)
tree97e97f6ce4dbd0461e52b50192420b4a70b1b988 /cpio
parent2eef60297a0ca1433d0824d6d662efd402709cfd (diff)
downloadplatform-system-core-8ac3a138168f79b47356fb5aea2f6d95fc3147c6.tar.gz
platform-system-core-8ac3a138168f79b47356fb5aea2f6d95fc3147c6.tar.xz
platform-system-core-8ac3a138168f79b47356fb5aea2f6d95fc3147c6.zip
auto import from //branches/cupcake/...@127101
Diffstat (limited to 'cpio')
-rw-r--r--cpio/mkbootfs.c73
1 files changed, 57 insertions, 16 deletions
diff --git a/cpio/mkbootfs.c b/cpio/mkbootfs.c
index 9fe625278..f67233634 100644
--- a/cpio/mkbootfs.c
+++ b/cpio/mkbootfs.c
@@ -25,7 +25,7 @@
25void die(const char *why, ...) 25void die(const char *why, ...)
26{ 26{
27 va_list ap; 27 va_list ap;
28 28
29 va_start(ap, why); 29 va_start(ap, why);
30 fprintf(stderr,"error: "); 30 fprintf(stderr,"error: ");
31 vfprintf(stderr, why, ap); 31 vfprintf(stderr, why, ap);
@@ -44,6 +44,11 @@ static void fix_stat(const char *path, struct stat *s)
44 44
45static void _eject(struct stat *s, char *out, int olen, char *data, unsigned datasize) 45static void _eject(struct stat *s, char *out, int olen, char *data, unsigned datasize)
46{ 46{
47 // Nothing is special about this value, just picked something in the
48 // approximate range that was being used already, and avoiding small
49 // values which may be special.
50 static unsigned next_inode = 300000;
51
47 while(total_size & 3) { 52 while(total_size & 3) {
48 total_size++; 53 total_size++;
49 putchar(0); 54 putchar(0);
@@ -55,12 +60,12 @@ static void _eject(struct stat *s, char *out, int olen, char *data, unsigned dat
55 printf("%06x%08x%08x%08x%08x%08x%08x" 60 printf("%06x%08x%08x%08x%08x%08x%08x"
56 "%08x%08x%08x%08x%08x%08x%08x%s%c", 61 "%08x%08x%08x%08x%08x%08x%08x%s%c",
57 0x070701, 62 0x070701,
58 (unsigned) s->st_ino, 63 next_inode++, // s.st_ino,
59 s->st_mode, 64 s->st_mode,
60 0, // s.st_uid, 65 0, // s.st_uid,
61 0, // s.st_gid, 66 0, // s.st_gid,
62 1, // s.st_nlink, 67 1, // s.st_nlink,
63 (unsigned) s->st_mtime, 68 0, // s.st_mtime,
64 datasize, 69 datasize,
65 0, // volmajor 70 0, // volmajor
66 0, // volminor 71 0, // volminor
@@ -75,7 +80,7 @@ static void _eject(struct stat *s, char *out, int olen, char *data, unsigned dat
75 total_size += 6 + 8*13 + olen + 1; 80 total_size += 6 + 8*13 + olen + 1;
76 81
77 if(strlen(out) != olen) die("ACK!"); 82 if(strlen(out) != olen) die("ACK!");
78 83
79 while(total_size & 3) { 84 while(total_size & 3) {
80 total_size++; 85 total_size++;
81 putchar(0); 86 putchar(0);
@@ -101,9 +106,13 @@ static void _eject_trailer()
101 106
102static void _archive(char *in, char *out, int ilen, int olen); 107static void _archive(char *in, char *out, int ilen, int olen);
103 108
109static int compare(const void* a, const void* b) {
110 return strcmp(*(const char**)a, *(const char**)b);
111}
112
104static void _archive_dir(char *in, char *out, int ilen, int olen) 113static void _archive_dir(char *in, char *out, int ilen, int olen)
105{ 114{
106 int t; 115 int i, t;
107 DIR *d; 116 DIR *d;
108 struct dirent *de; 117 struct dirent *de;
109 118
@@ -111,33 +120,65 @@ static void _archive_dir(char *in, char *out, int ilen, int olen)
111 fprintf(stderr,"_archive_dir('%s','%s',%d,%d)\n", 120 fprintf(stderr,"_archive_dir('%s','%s',%d,%d)\n",
112 in, out, ilen, olen); 121 in, out, ilen, olen);
113 } 122 }
114 123
115 d = opendir(in); 124 d = opendir(in);
116 if(d == 0) die("cannot open directory '%s'", in); 125 if(d == 0) die("cannot open directory '%s'", in);
117 126
127 int size = 32;
128 int entries = 0;
129 char** names = malloc(size * sizeof(char*));
130 if (names == NULL) {
131 fprintf(stderr, "failed to allocate dir names array (size %d)\n", size);
132 exit(1);
133 }
134
118 while((de = readdir(d)) != 0){ 135 while((de = readdir(d)) != 0){
119 /* xxx: feature? maybe some dotfiles are okay */ 136 /* xxx: feature? maybe some dotfiles are okay */
120 if(de->d_name[0] == '.') continue; 137 if(de->d_name[0] == '.') continue;
121 138
122 /* xxx: hack. use a real exclude list */ 139 /* xxx: hack. use a real exclude list */
123 if(!strcmp(de->d_name, "root")) continue; 140 if(!strcmp(de->d_name, "root")) continue;
124 141
125 t = strlen(de->d_name); 142 if (entries >= size) {
143 size *= 2;
144 names = realloc(names, size * sizeof(char*));
145 if (names == NULL) {
146 fprintf(stderr, "failed to reallocate dir names array (size %d)\n",
147 size);
148 exit(1);
149 }
150 }
151 names[entries] = strdup(de->d_name);
152 if (names[entries] == NULL) {
153 fprintf(stderr, "failed to strdup name \"%s\"\n",
154 de->d_name);
155 exit(1);
156 }
157 ++entries;
158 }
159
160 qsort(names, entries, sizeof(char*), compare);
161
162 for (i = 0; i < entries; ++i) {
163 t = strlen(names[i]);
126 in[ilen] = '/'; 164 in[ilen] = '/';
127 memcpy(in + ilen + 1, de->d_name, t + 1); 165 memcpy(in + ilen + 1, names[i], t + 1);
128 166
129 if(olen > 0) { 167 if(olen > 0) {
130 out[olen] = '/'; 168 out[olen] = '/';
131 memcpy(out + olen + 1, de->d_name, t + 1); 169 memcpy(out + olen + 1, names[i], t + 1);
132 _archive(in, out, ilen + t + 1, olen + t + 1); 170 _archive(in, out, ilen + t + 1, olen + t + 1);
133 } else { 171 } else {
134 memcpy(out, de->d_name, t + 1); 172 memcpy(out, names[i], t + 1);
135 _archive(in, out, ilen + t + 1, t); 173 _archive(in, out, ilen + t + 1, t);
136 } 174 }
137 175
138 in[ilen] = 0; 176 in[ilen] = 0;
139 out[olen] = 0; 177 out[olen] = 0;
178
179 free(names[i]);
140 } 180 }
181 free(names);
141} 182}
142 183
143static void _archive(char *in, char *out, int ilen, int olen) 184static void _archive(char *in, char *out, int ilen, int olen)
@@ -148,7 +189,7 @@ static void _archive(char *in, char *out, int ilen, int olen)
148 fprintf(stderr,"_archive('%s','%s',%d,%d)\n", 189 fprintf(stderr,"_archive('%s','%s',%d,%d)\n",
149 in, out, ilen, olen); 190 in, out, ilen, olen);
150 } 191 }
151 192
152 if(lstat(in, &s)) die("could not stat '%s'\n", in); 193 if(lstat(in, &s)) die("could not stat '%s'\n", in);
153 194
154 if(S_ISREG(s.st_mode)){ 195 if(S_ISREG(s.st_mode)){
@@ -166,7 +207,7 @@ static void _archive(char *in, char *out, int ilen, int olen)
166 } 207 }
167 208
168 _eject(&s, out, olen, tmp, s.st_size); 209 _eject(&s, out, olen, tmp, s.st_size);
169 210
170 free(tmp); 211 free(tmp);
171 close(fd); 212 close(fd);
172 } else if(S_ISDIR(s.st_mode)) { 213 } else if(S_ISDIR(s.st_mode)) {
@@ -208,13 +249,13 @@ int main(int argc, char *argv[])
208 } else { 249 } else {
209 x = ""; 250 x = "";
210 } 251 }
211 252
212 archive(*argv, x); 253 archive(*argv, x);
213 254
214 argv++; 255 argv++;
215 } 256 }
216 257
217 _eject_trailer(); 258 _eject_trailer();
218 259
219 return 0; 260 return 0;
220} 261}