summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/makedevs
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-devtools/makedevs
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadpoky-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-devtools/makedevs')
-rw-r--r--meta/recipes-devtools/makedevs/makedevs-1.0.0/makedevs.c360
-rw-r--r--meta/recipes-devtools/makedevs/makedevs_1.0.0.bb21
2 files changed, 381 insertions, 0 deletions
diff --git a/meta/recipes-devtools/makedevs/makedevs-1.0.0/makedevs.c b/meta/recipes-devtools/makedevs/makedevs-1.0.0/makedevs.c
new file mode 100644
index 0000000000..c7ad722f2e
--- /dev/null
+++ b/meta/recipes-devtools/makedevs/makedevs-1.0.0/makedevs.c
@@ -0,0 +1,360 @@
1#define _GNU_SOURCE
2#include <stdio.h>
3#include <errno.h>
4#include <string.h>
5#include <stdarg.h>
6#include <stdlib.h>
7#include <ctype.h>
8#include <fcntl.h>
9#include <dirent.h>
10#include <unistd.h>
11#include <time.h>
12#include <getopt.h>
13#include <libgen.h>
14#include <sys/types.h>
15#include <sys/stat.h>
16
17#define MINORBITS 8
18#define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
19
20/* These are all stolen from busybox's libbb to make
21 * error handling simpler (and since I maintain busybox,
22 * I'm rather partial to these for error handling).
23 * -Erik
24 */
25static const char *const app_name = "makedevs";
26static const char *const memory_exhausted = "memory exhausted";
27static char default_rootdir[]=".";
28static char *rootdir = default_rootdir;
29
30static void verror_msg(const char *s, va_list p)
31{
32 fflush(stdout);
33 fprintf(stderr, "%s: ", app_name);
34 vfprintf(stderr, s, p);
35}
36
37static void error_msg_and_die(const char *s, ...)
38{
39 va_list p;
40
41 va_start(p, s);
42 verror_msg(s, p);
43 va_end(p);
44 putc('\n', stderr);
45 exit(EXIT_FAILURE);
46}
47
48static void vperror_msg(const char *s, va_list p)
49{
50 int err = errno;
51
52 if (s == 0)
53 s = "";
54 verror_msg(s, p);
55 if (*s)
56 s = ": ";
57 fprintf(stderr, "%s%s\n", s, strerror(err));
58}
59
60#if 0
61static void perror_msg(const char *s, ...)
62{
63 va_list p;
64
65 va_start(p, s);
66 vperror_msg(s, p);
67 va_end(p);
68}
69#endif
70
71static void perror_msg_and_die(const char *s, ...)
72{
73 va_list p;
74
75 va_start(p, s);
76 vperror_msg(s, p);
77 va_end(p);
78 exit(EXIT_FAILURE);
79}
80
81static FILE *xfopen(const char *path, const char *mode)
82{
83 FILE *fp;
84
85 if ((fp = fopen(path, mode)) == NULL)
86 perror_msg_and_die("%s", path);
87 return fp;
88}
89
90static char *xstrdup(const char *s)
91{
92 char *t;
93
94 if (s == NULL)
95 return NULL;
96
97 t = strdup(s);
98
99 if (t == NULL)
100 error_msg_and_die(memory_exhausted);
101
102 return t;
103}
104
105
106static void add_new_directory(char *name, char *path,
107 unsigned long uid, unsigned long gid, unsigned long mode)
108{
109 mkdir(path, mode);
110 chown(path, uid, gid);
111// printf("Directory: %s %s UID: %ld GID %ld MODE: %ld\n", path, name, uid, gid, mode);
112}
113
114static void add_new_device(char *name, char *path, unsigned long uid,
115 unsigned long gid, unsigned long mode, dev_t rdev)
116{
117 int status;
118 struct stat sb;
119 time_t timestamp = time(NULL);
120
121 memset(&sb, 0, sizeof(struct stat));
122 status = lstat(path, &sb);
123
124 if (status >= 0) {
125 /* It is ok for some types of files to not exit on disk (such as
126 * device nodes), but if they _do_ exist the specified mode had
127 * better match the actual file or strange things will happen.... */
128 if ((mode & S_IFMT) != (sb.st_mode & S_IFMT))
129 error_msg_and_die("%s: file type does not match specified type!", path);
130 timestamp = sb.st_mtime;
131 }
132
133 mknod(name, mode, rdev);
134 chown(path, uid, gid);
135// printf("Device: %s %s UID: %ld GID: %ld MODE: %ld MAJOR: %d MINOR: %d\n",
136// path, name, uid, gid, mode, (short)(rdev >> 8), (short)(rdev & 0xff));
137}
138
139static void add_new_file(char *name, char *path, unsigned long uid,
140 unsigned long gid, unsigned long mode)
141{
142 int fd = open(path,O_CREAT | O_WRONLY, mode);
143 if (fd < 0) {
144 error_msg_and_die("%s: file can not be created!", path);
145 } else {
146 close(fd);
147 }
148 chmod(path, mode);
149 chown(path, uid, gid);
150// printf("File: %s %s UID: %ld GID: %ld MODE: %ld\n",
151// path, name, gid, uid, mode);
152}
153
154
155static void add_new_fifo(char *name, char *path, unsigned long uid,
156 unsigned long gid, unsigned long mode)
157{
158 if (mknod(path, mode, 0))
159 error_msg_and_die("%s: file can not be created with mknod!", path);
160 chown(path, uid, gid);
161// printf("File: %s %s UID: %ld GID: %ld MODE: %ld\n",
162// path, name, gid, uid, mode);
163}
164
165
166/* device table entries take the form of:
167 <path> <type> <mode> <uid> <gid> <major> <minor> <start> <inc> <count>
168 /dev/mem c 640 0 0 1 1 0 0 -
169
170 type can be one of:
171 f A regular file
172 d Directory
173 c Character special device file
174 b Block special device file
175 p Fifo (named pipe)
176
177 I don't bother with symlinks (permissions are irrelevant), hard
178 links (special cases of regular files), or sockets (why bother).
179
180 Regular files must exist in the target root directory. If a char,
181 block, fifo, or directory does not exist, it will be created.
182*/
183static int interpret_table_entry(char *line)
184{
185 char *name;
186 char path[4096], type;
187 unsigned long mode = 0755, uid = 0, gid = 0, major = 0, minor = 0;
188 unsigned long start = 0, increment = 1, count = 0;
189
190 if (0 > sscanf(line, "%40s %c %lo %lu %lu %lu %lu %lu %lu %lu", path,
191 &type, &mode, &uid, &gid, &major, &minor, &start,
192 &increment, &count))
193 {
194 return 1;
195 }
196
197 if (!strcmp(path, "/")) {
198 error_msg_and_die("Device table entries require absolute paths");
199 }
200 name = xstrdup(path + 1);
201 sprintf(path, "%s/%s\0", rootdir, name);
202
203 switch (type) {
204 case 'd':
205 mode |= S_IFDIR;
206 add_new_directory(name, path, uid, gid, mode);
207 break;
208 case 'f':
209 mode |= S_IFREG;
210 add_new_file(name, path, uid, gid, mode);
211 break;
212 case 'p':
213 mode |= S_IFIFO;
214 add_new_fifo(name, path, uid, gid, mode);
215 break;
216 case 'c':
217 case 'b':
218 mode |= (type == 'c') ? S_IFCHR : S_IFBLK;
219 if (count > 0) {
220 int i;
221 dev_t rdev;
222 char buf[80];
223
224 for (i = start; i < count; i++) {
225 sprintf(buf, "%s%d", name, i);
226 /* FIXME: MKDEV uses illicit insider knowledge of kernel
227 * major/minor representation... */
228 rdev = MKDEV(major, minor + (i * increment - start));
229 add_new_device(buf, path, uid, gid, mode, rdev);
230 }
231 } else {
232 /* FIXME: MKDEV uses illicit insider knowledge of kernel
233 * major/minor representation... */
234 dev_t rdev = MKDEV(major, minor);
235
236 add_new_device(name, path, uid, gid, mode, rdev);
237 }
238 break;
239 default:
240 error_msg_and_die("Unsupported file type");
241 }
242 if (name) free(name);
243 return 0;
244}
245
246
247static void parse_device_table(FILE * file)
248{
249 char *line;
250 size_t length = 256;
251 int len = 0;
252
253 /* Looks ok so far. The general plan now is to read in one
254 * line at a time, check for leading comment delimiters ('#'),
255 * then try and parse the line as a device table. If we fail
256 * to parse things, try and help the poor fool to fix their
257 * device table with a useful error msg... */
258
259 if((line = (char *)malloc(length)) == NULL) {
260 fclose(file);
261 return;
262 }
263
264 while ((len = getline(&line, &length, file)) != -1) {
265 /* First trim off any whitespace */
266
267 /* trim trailing whitespace */
268 while (len > 0 && isspace(line[len - 1]))
269 line[--len] = '\0';
270
271 /* trim leading whitespace */
272 memmove(line, &line[strspn(line, " \n\r\t\v")], len + 1);
273
274 /* If this is NOT a comment line, try to interpret it */
275 if (*line != '#') interpret_table_entry(line);
276 }
277 if (line) free(line);
278
279 fclose(file);
280}
281
282static int go(char *dname, FILE * devtable)
283{
284 struct stat sb;
285
286 if (lstat(dname, &sb)) {
287 perror_msg_and_die("%s", dname);
288 }
289 if (chdir(dname))
290 perror_msg_and_die("%s", dname);
291
292 if (devtable)
293 parse_device_table(devtable);
294
295 return 0;
296}
297
298
299static struct option long_options[] = {
300 {"root", 1, NULL, 'r'},
301 {"help", 0, NULL, 'h'},
302 {"squash", 0, NULL, 'q'},
303 {"version", 0, NULL, 'v'},
304 {"devtable", 1, NULL, 'D'},
305 {NULL, 0, NULL, 0}
306};
307
308static char *helptext =
309 "Usage: makedevs [OPTIONS]\n"
310 "Build entries based upon device_table.txt\n\n"
311 "Options:\n"
312 " -r, -d, --root=DIR Build filesystem from directory DIR (default: cwd)\n"
313 " -D, --devtable=FILE Use the named FILE as a device table file\n"
314 " -q, --squash Squash permissions and owners making all files be owned by root\n"
315 " -h, --help Display this help text\n"
316 " -v, --version Display version information\n\n";
317
318
319static char *revtext = "$Revision: 0.1 $";
320
321int main(int argc, char **argv)
322{
323 int c, opt;
324 extern char *optarg;
325 struct stat statbuf;
326 FILE *devtable = NULL;
327
328 umask (0);
329
330 while ((opt = getopt_long(argc, argv, "D:d:r:qhv",
331 long_options, &c)) >= 0) {
332 switch (opt) {
333 case 'D':
334 devtable = xfopen(optarg, "r");
335 if (fstat(fileno(devtable), &statbuf) < 0)
336 perror_msg_and_die(optarg);
337 if (statbuf.st_size < 10)
338 error_msg_and_die("%s: not a proper device table file", optarg);
339 break;
340 case 'h':
341 fprintf(stderr, helptext);
342 exit(1);
343 case 'r':
344 case 'd': /* for compatibility with mkfs.jffs, genext2fs, etc... */
345 if (rootdir != default_rootdir) {
346 error_msg_and_die("root directory specified more than once");
347 }
348 rootdir = xstrdup(optarg);
349 break;
350
351 case 'v':
352 fprintf(stderr, "makedevs revision %.*s\n",
353 (int) strlen(revtext) - 13, revtext + 11);
354 exit(1);
355 }
356 }
357
358 go(rootdir, devtable);
359 return 0;
360}
diff --git a/meta/recipes-devtools/makedevs/makedevs_1.0.0.bb b/meta/recipes-devtools/makedevs/makedevs_1.0.0.bb
new file mode 100644
index 0000000000..5db2d9b142
--- /dev/null
+++ b/meta/recipes-devtools/makedevs/makedevs_1.0.0.bb
@@ -0,0 +1,21 @@
1DESCRIPTION = "A tool to make device nodes"
2LICENSE = "GPLv2"
3SECTION = "base"
4PRIORITY = "required"
5SRC_URI = "file://makedevs.c"
6PR = "r6"
7
8do_configure() {
9 install -m 0644 ${WORKDIR}/makedevs.c ${S}/
10}
11
12do_compile() {
13 ${CC} ${CFLAGS} -o ${S}/makedevs ${S}/makedevs.c
14}
15
16do_install() {
17 install -d ${D}${base_sbindir}
18 install -m 0755 ${S}/makedevs ${D}${base_sbindir}/makedevs
19}
20
21BBCLASSEXTEND = "native"