makedevs.c revision 936ab6d68b747ed7a315ef9c27bb9b90088686f3
19f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma/* makedevs.c - Make ranges of device files. 29f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma * 39f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma * Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com> 49f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma * Copyright 2014 Kyungwan Han <asura321@gmail.com> 59f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma * 69f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma * No Standard 79f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 89f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini SharmaUSE_MAKEDEVS(NEWTOY(makedevs, "<1>1d:", TOYFLAG_USR|TOYFLAG_BIN)) 99f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 109f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharmaconfig MAKEDEVS 119f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma bool "makedevs" 129f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma default n 139f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma help 149f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma usage: makedevs [-d device_table] rootdir 156ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley 169f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma Create a range of special files as specified in a device table. 176ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley 186ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley -d file containing device table (default reads from stdin) 196ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley 206ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley Each line of of the device table has the fields: 219f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma <name> <type> <mode> <uid> <gid> <major> <minor> <start> <increment> <count> 226ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley Where name is the file name, and type is one of the following: 236ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley 246ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley b Block device 256ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley c Character device 266ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley d Directory 276ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley f Regular file 286ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley p Named pipe (fifo) 296ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley 306ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley Other fields specify permissions, user and group id owning the file, 316ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley and additional fields for device special files. Use '-' for blank entries, 326ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley unspecified fields are treated as '-'. 339f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma*/ 346ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley 359f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma#define FOR_makedevs 369f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma#include "toys.h" 379f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 389f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini SharmaGLOBALS( 399f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma char *fname; 409f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma) 419f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 429f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharmavoid makedevs_main() 439f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma{ 446ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley int value, fd = 0, line_no, i; 459f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma char *line = NULL; 469f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 476ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley // Open file and chdir, verbosely 486ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley xprintf("rootdir = %s\n", *toys.optargs); 496ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley if (toys.optflags & FLAG_d && strcmp(TT.fname, "-")) { 506ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley fd = xopen(TT.fname, O_RDONLY); 516ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley xprintf("table = %s\n", TT.fname); 52936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley } else xprintf("table = <stdin>\n"); 536ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley xchdir(*toys.optargs); 549f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 559f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma for (line_no = 0; (line = get_line(fd)); free(line)) { 56936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley char type=0, user[64], group[64], *node, *ptr = line; 579f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma unsigned int mode = 0755, major = 0, minor = 0, cnt = 0, incr = 0, 586ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley st_val = 0; 599f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma uid_t uid; 609f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma gid_t gid; 619f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma struct stat st; 629f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 639f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma line_no++; 646ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley while (isspace(*ptr)) ptr++; 659f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma if (!*ptr || *ptr == '#') continue; 66936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley node = ptr; 676ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley 686ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley while (*ptr && !isspace(*ptr)) ptr++; 69936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (*ptr) *(ptr++) = 0; 706ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley *user = *group = 0; 716ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley sscanf(ptr, "%c %o %63s %63s %u %u %u %u %u", &type, &mode, 726ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley user, group, &major, &minor, &st_val, &incr, &cnt); 736ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley 746ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley // type order here needs to line up with actions[] order. 756ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley i = stridx("pcbdf", type); 766ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley if (i == -1) { 776ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley error_msg("line %d: bad type %c", line_no, type); 789f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma continue; 796ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley } else mode |= (mode_t[]){S_IFIFO, S_IFCHR, S_IFBLK, 0, 0}[i]; 809f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 819f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma if (*user) { 829f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma struct passwd *usr; 839f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 849f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma if (!(usr = getpwnam(user)) && isdigit(*user)) { 856ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley sscanf(user, "%u", &value); 869f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma usr = xgetpwuid(value); 879f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } 889f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma if (!usr) error_exit("bad user '%s'", user); 899f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma uid = usr->pw_uid; 909f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } else uid = getuid(); 919f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 929f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma if (*group) { 939f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma struct group *grp; 949f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 959f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma if (!(grp = getgrnam(group)) && isdigit(*group)) { 966ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley sscanf (group, "%u", &value); 979f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma grp = getgrgid(value); 989f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } 999f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma if (!grp) error_exit("bad group '%s'", group); 1009f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma gid = grp->gr_gid; 1019f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } else gid = getgid(); 1029f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 1036ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley while (*node == '/') node++; // using relative path 104936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley 105936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley for (i = 0; (!cnt && !i) || i < cnt; i++) { 106936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (cnt) { 107936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley snprintf(toybuf, sizeof(toybuf), "%s%u", node, st_val + i); 108936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley ptr = toybuf; 109936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley } else ptr = node; 110936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley 111936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (type == 'd') { 112936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (mkpathat(AT_FDCWD, ptr, mode, 3)) { 113936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley perror_msg("can't create directory '%s'", ptr); 114936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley continue; 115936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley } 116936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley } else if (type == 'f') { 117936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (stat(ptr, &st) || !S_ISREG(st.st_mode)) { 118936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley perror_msg("line %d: file '%s' does not exist", line_no, ptr); 1196ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley continue; 1209f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } 121936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley } else if (mknod(ptr, mode, makedev(major, minor + i*incr))) { 122936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley perror_msg("line %d: can't create node '%s'", line_no, ptr); 123936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley continue; 1246ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley } 125936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley 126936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (chown(ptr, uid, gid) || chmod(ptr, mode)) 127936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley perror_msg("line %d: can't chown/chmod '%s'", line_no, ptr); 1289f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } 1299f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } 1309f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma xclose(fd); 1319f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma} 132