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 }