Mercurial > hg > toybox
comparison toys/pending/makedevs.c @ 1325:41fc44c76ade draft
makedevs - making devices/nodes in a range. Supports reading the tabled entry from file.
author | Ashwini Sharma <ak.ashwini1981@gmail.com> |
---|---|
date | Thu, 29 May 2014 08:20:30 -0500 |
parents | |
children | b9605ebd3af4 |
comparison
equal
deleted
inserted
replaced
1324:3191aa9490aa | 1325:41fc44c76ade |
---|---|
1 /* makedevs.c - Make ranges of device files. | |
2 * | |
3 * Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com> | |
4 * Copyright 2014 Kyungwan Han <asura321@gmail.com> | |
5 * | |
6 * No Standard | |
7 | |
8 USE_MAKEDEVS(NEWTOY(makedevs, "<1>1d:", TOYFLAG_USR|TOYFLAG_BIN)) | |
9 | |
10 config MAKEDEVS | |
11 bool "makedevs" | |
12 default n | |
13 help | |
14 usage: makedevs [-d device_table] rootdir | |
15 Create a range of special files as specified in a device table. | |
16 Device table entries take the following form: | |
17 <name> <type> <mode> <uid> <gid> <major> <minor> <start> <increment> <count> | |
18 Where name is the file name, type can be one of the following: | |
19 b Block device | |
20 c Character device | |
21 d Directory | |
22 f Regular file | |
23 p Fifo (named pipe) | |
24 | |
25 uid is the user id and gid is the group id for the target file. | |
26 The rest of the entries (major, minor, etc.) apply to device | |
27 special files. A '-' may be used for blank entries. | |
28 */ | |
29 #define FOR_makedevs | |
30 #include "toys.h" | |
31 | |
32 GLOBALS( | |
33 char *fname; | |
34 ) | |
35 | |
36 void makedevs_main() | |
37 { | |
38 int value, fd = 0, line_no; | |
39 char *line = NULL; | |
40 | |
41 if (toys.optflags & FLAG_d) { | |
42 xprintf("rootdir = %s\ntable = %s\n", *toys.optargs, | |
43 (!strcmp(TT.fname, "-")) ? "<stdin>": TT.fname); | |
44 fd = (!strcmp(TT.fname, "-")) ? 0 : xopen(TT.fname, O_RDONLY); | |
45 } else xprintf("rootdir = %s\ntable = %s\n", *toys.optargs, "<stdin>"); | |
46 | |
47 xchdir(*toys.optargs); // root dir | |
48 for (line_no = 0; (line = get_line(fd)); free(line)) { | |
49 char type, str[64], user[64], group [64], *node = str, *ptr = line; | |
50 unsigned int mode = 0755, major = 0, minor = 0, cnt = 0, incr = 0, | |
51 st_val = 0, i; | |
52 uid_t uid; | |
53 gid_t gid; | |
54 dev_t dev; | |
55 struct stat st; | |
56 | |
57 line_no++; | |
58 while (*ptr == ' ' || *ptr == '\t') ptr++; | |
59 if (!*ptr || *ptr == '#') continue; | |
60 sscanf(line, "%63s %c %o %63s %63s %u %u %u %u %u", node, &type, &mode, | |
61 user, group, &major, &minor, &st_val, &incr, &cnt); | |
62 if ((major | minor | st_val | cnt | incr) > 255) { | |
63 error_msg("invalid line %d: '%s'", line_no, line); | |
64 continue; | |
65 } | |
66 | |
67 if (*user) { | |
68 struct passwd *usr; | |
69 | |
70 if (!(usr = getpwnam(user)) && isdigit(*user)) { | |
71 sscanf (user, "%d", &value); | |
72 usr = xgetpwuid(value); | |
73 } | |
74 if (!usr) error_exit("bad user '%s'", user); | |
75 uid = usr->pw_uid; | |
76 } else uid = getuid(); | |
77 | |
78 if (*group) { | |
79 struct group *grp; | |
80 | |
81 if (!(grp = getgrnam(group)) && isdigit(*group)) { | |
82 sscanf (group, "%d", &value); | |
83 grp = getgrgid(value); | |
84 } | |
85 if (!grp) error_exit("bad group '%s'", group); | |
86 gid = grp->gr_gid; | |
87 } else gid = getgid(); | |
88 | |
89 if (*node == '/') node++; // using relative path | |
90 switch (type) { | |
91 case 'd': | |
92 if (mkpathat(AT_FDCWD, node, mode, 3)) | |
93 perror_msg("can't create directory '%s'", node); | |
94 else if (chown(node, uid, gid) || chmod(node, mode)) | |
95 perror_msg("line %d: can't chown/chmod '%s'", line_no, node); | |
96 break; | |
97 case 'f': | |
98 if ((stat(node, &st) || !S_ISREG(st.st_mode))) | |
99 perror_msg("line %d: regular file '%s' does not exist", | |
100 line_no, node); | |
101 else if (chown(node, uid, gid) || chmod(node, mode)) | |
102 perror_msg("line %d: can't chown/chmod '%s'", line_no, node); | |
103 break; | |
104 case 'p': mode |= S_IFIFO; goto CREATENODE; | |
105 case 'c': mode |= S_IFCHR; goto CREATENODE; | |
106 case 'b': mode |= S_IFBLK; | |
107 CREATENODE: | |
108 if (cnt) --cnt; | |
109 for (i = st_val; i <= st_val + cnt; i++) { | |
110 sprintf(toybuf, cnt ? "%s%u" : "%s", node, i); | |
111 dev = makedev(major, minor + (i - st_val) * incr); | |
112 if (mknod(toybuf, mode, dev)) | |
113 perror_msg("line %d: can't create node '%s'", line_no, toybuf); | |
114 else if (chown(toybuf, uid, gid) || chmod(toybuf, mode)) | |
115 perror_msg("line %d: can't chown/chmod '%s'", line_no, toybuf); | |
116 } | |
117 break; | |
118 default: | |
119 error_msg("line %d: file type %c is unsupported", line_no, type); | |
120 break; | |
121 } | |
122 } | |
123 xclose(fd); | |
124 } |