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" 129bf93edd68742bbc9e814ec49c8a3a31ca8d3fffRob Landley default y 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{ 44be4048dd2509f2b9e968a4d03c06050d847971d3Rob Landley int 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, "-")) { 50027a73a903af306449710ce12bc09e0e3550c6c9Rob Landley fd = xopenro(TT.fname); 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 813d64b0cc95c5957e53474c3e50f143c61a057104Rob Landley uid = *user ? xgetuid(user) : getuid(); 823d64b0cc95c5957e53474c3e50f143c61a057104Rob Landley gid = *group ? xgetgid(group) : getgid(); 839f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma 846ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley while (*node == '/') node++; // using relative path 85936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley 86936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley for (i = 0; (!cnt && !i) || i < cnt; i++) { 87a829b89dbd324bcc005a5873fddf3faa81ea0536Rob Landley if (cnt>1) { 88a829b89dbd324bcc005a5873fddf3faa81ea0536Rob Landley snprintf(toybuf, sizeof(toybuf), "%.999s%u", node, st_val + i); 89936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley ptr = toybuf; 90936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley } else ptr = node; 91936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley 92936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (type == 'd') { 93936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (mkpathat(AT_FDCWD, ptr, mode, 3)) { 94936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley perror_msg("can't create directory '%s'", ptr); 95936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley continue; 96936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley } 97936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley } else if (type == 'f') { 98936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (stat(ptr, &st) || !S_ISREG(st.st_mode)) { 99936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley perror_msg("line %d: file '%s' does not exist", line_no, ptr); 1006ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley continue; 1019f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } 1027ca5dc4232b9ac5ee5cd25c8b5b33a58904cd251Rob Landley } else if (mknod(ptr, mode, dev_makedev(major, minor + i*incr))) { 103936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley perror_msg("line %d: can't create node '%s'", line_no, ptr); 104936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley continue; 1056ad3207b65438870dfc9f76a3dcf4bb04096297eRob Landley } 106936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley 107936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley if (chown(ptr, uid, gid) || chmod(ptr, mode)) 108936ab6d68b747ed7a315ef9c27bb9b90088686f3Rob Landley perror_msg("line %d: can't chown/chmod '%s'", line_no, ptr); 1099f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } 1109f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma } 1119f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma xclose(fd); 1129f1a00a859d1b085fdf7a1a5f66e51f41c6217eeAshwini Sharma} 113