For years the man pages have said to #include <sys/types.h> to get
major/minor/makedev, but glibc has vowed to break existing programs
(https://sourceware.org/ml/libc-alpha/2015-11/msg00253.html)
and replace it with _another_ non-standard header (not in posix or lsb),
so let's just add functions to lib/ that do the transform ourselves.
diff --git a/lib/lib.c b/lib/lib.c
index 43db2e3..1c1f224 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -1043,3 +1043,18 @@
 
   return *s ? s : 0;
 }
+
+int dev_minor(int dev)
+{
+  return ((dev&0xfff00000)>>12)|(dev&0xff);
+}
+
+int dev_major(int dev)
+{
+  return (dev&0xfff00)>>8;
+}
+
+int dev_makedev(int major, int minor)
+{
+  return (minor&0xff)|((major&0xfff)<<8)|((minor&0xfff00)<<12);
+}
diff --git a/lib/lib.h b/lib/lib.h
index dac3b67..c8cff6e 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -200,6 +200,9 @@
 char *show_uuid(char *uuid);
 char *next_printf(char *s, char **start);
 char *strnstr(char *line, char *str);
+int dev_minor(int dev);
+int dev_major(int dev);
+int dev_makedev(int major, int minor);
 
 #define HR_SPACE 1 // Space between number and units
 #define HR_B     2 // Use "B" for single byte units
diff --git a/toys/lsb/mknod.c b/toys/lsb/mknod.c
index 1a467b0..8148c85 100644
--- a/toys/lsb/mknod.c
+++ b/toys/lsb/mknod.c
@@ -53,6 +53,6 @@
   if (toys.optflags & FLAG_Z)
     if (-1 == lsm_set_create(TT.arg_context))
       perror_exit("-Z '%s' failed", TT.arg_context);
-  if (mknod(*toys.optargs, mode|modes[type], makedev(major, minor)))
+  if (mknod(*toys.optargs, mode|modes[type], dev_makedev(major, minor)))
     perror_exit_raw(*toys.optargs);
 }
diff --git a/toys/other/makedevs.c b/toys/other/makedevs.c
index 0f0a661..0f79b25 100644
--- a/toys/other/makedevs.c
+++ b/toys/other/makedevs.c
@@ -99,7 +99,7 @@
           perror_msg("line %d: file '%s' does not exist", line_no, ptr);
           continue;
         }
-      } else if (mknod(ptr, mode, makedev(major, minor + i*incr))) {
+      } else if (mknod(ptr, mode, dev_makedev(major, minor + i*incr))) {
         perror_msg("line %d: can't create node '%s'", line_no, ptr);
         continue;
       }
diff --git a/toys/other/mountpoint.c b/toys/other/mountpoint.c
index ce1d23c..98e1d30 100644
--- a/toys/other/mountpoint.c
+++ b/toys/other/mountpoint.c
@@ -37,7 +37,8 @@
 
   if (toys.optflags & FLAG_x) {
     if (S_ISBLK(st1.st_mode)) {
-      if (!quiet) printf("%u:%u\n", major(st1.st_rdev), minor(st1.st_rdev));
+      if (!quiet)
+        printf("%u:%u\n", dev_major(st1.st_rdev), dev_minor(st1.st_rdev));
 
       return;
     }
@@ -57,7 +58,7 @@
   // absence of a spec I guess that's the expected behavior?
   toys.exitval = !(st1.st_dev != st2.st_dev || st1.st_ino == st2.st_ino);
   if (toys.optflags & FLAG_d)
-    printf("%u:%u\n", major(st1.st_dev), minor(st1.st_dev));
+    printf("%u:%u\n", dev_major(st1.st_dev), dev_minor(st1.st_dev));
   else if (!quiet)
     printf("%s is %sa mountpoint\n", *toys.optargs, toys.exitval ? "not " : "");
 }
diff --git a/toys/pending/mdev.c b/toys/pending/mdev.c
index e7adc99..975d31d 100644
--- a/toys/pending/mdev.c
+++ b/toys/pending/mdev.c
@@ -190,7 +190,7 @@
 
   if (strchr(device_name, '/'))
     mkpathat(AT_FDCWD, toybuf, 0, 2);
-  if (mknod(toybuf, mode | type, makedev(major, minor)) && errno != EEXIST)
+  if (mknod(toybuf, mode | type, dev_makedev(major, minor)) && errno != EEXIST)
     perror_exit("mknod %s failed", toybuf);
 
  
diff --git a/toys/pending/tar.c b/toys/pending/tar.c
index 4f4de0b..c504308 100644
--- a/toys/pending/tar.c
+++ b/toys/pending/tar.c
@@ -228,8 +228,8 @@
   else if (S_ISFIFO(st->st_mode)) hdr.type = '6';
   else if (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) {
     hdr.type = (S_ISCHR(st->st_mode))?'3':'4';
-    itoo(hdr.major, sizeof(hdr.major), major(st->st_rdev));
-    itoo(hdr.minor, sizeof(hdr.minor), minor(st->st_rdev));
+    itoo(hdr.major, sizeof(hdr.major), dev_major(st->st_rdev));
+    itoo(hdr.minor, sizeof(hdr.minor), dev_minor(st->st_rdev));
   } else {
     error_msg("unknown file type '%o'", st->st_mode & S_IFMT);
     return;
@@ -623,7 +623,7 @@
     file_hdr->gname = xstrdup(tar.gname);
     maj = otoi(tar.major, sizeof(tar.major));
     min = otoi(tar.minor, sizeof(tar.minor));
-    file_hdr->device = makedev(maj, min);
+    file_hdr->device = dev_makedev(maj, min);
 
     if (tar.type <= '7') {
       if (tar.link[0]) {
diff --git a/toys/posix/cpio.c b/toys/posix/cpio.c
index 981d6c5..3bd40f4 100644
--- a/toys/posix/cpio.c
+++ b/toys/posix/cpio.c
@@ -114,6 +114,7 @@
 
     // Read header and name.
     xreadall(afd, toybuf, 110);
+    if (memcmp(toybuf, "070701", 6)) error_exit("bad cpio magic");
     tofree = name = strpad(afd, x8u(toybuf+94), 110);
     if (!strcmp("TRAILER!!!", name)) {
       if (CFG_TOYBOX_FREE) free(tofree);
@@ -180,7 +181,7 @@
         close(fd);
       }
     } else if (!test)
-      err = mknod(name, mode, makedev(x8u(toybuf+78), x8u(toybuf+86)));
+      err = mknod(name, mode, dev_makedev(x8u(toybuf+78), x8u(toybuf+86)));
 
     // Set ownership and timestamp.
     if (!test && !err) {
@@ -243,8 +244,9 @@
         llen = sprintf(toybuf,
           "070701%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
           (int)st.st_ino, st.st_mode, st.st_uid, st.st_gid, (int)st.st_nlink,
-          (int)st.st_mtime, (int)st.st_size, major(st.st_dev),
-          minor(st.st_dev), major(st.st_rdev), minor(st.st_rdev), nlen, 0);
+          (int)st.st_mtime, (int)st.st_size, dev_major(st.st_dev),
+          dev_minor(st.st_dev), dev_major(st.st_rdev), dev_minor(st.st_rdev),
+          nlen, 0);
         xwrite(afd, toybuf, llen);
         xwrite(afd, name, nlen);
 
diff --git a/toys/posix/ls.c b/toys/posix/ls.c
index 08ae695..4dcbe88 100644
--- a/toys/posix/ls.c
+++ b/toys/posix/ls.c
@@ -144,7 +144,7 @@
     if (S_ISBLK(st->st_mode) || S_ISCHR(st->st_mode)) {
       // cheating slightly here: assuming minor is always 3 digits to avoid
       // tracking another column
-      len[5] = numlen(major(st->st_rdev))+5;
+      len[5] = numlen(dev_major(st->st_rdev))+5;
     } else if (flags & FLAG_h) {
         human_readable(tmp, st->st_size, 0);
         len[5] = strwidth(tmp);
@@ -453,7 +453,8 @@
 
       // print major/minor, or size
       if (S_ISCHR(st->st_mode) || S_ISBLK(st->st_mode))
-        printf("% *d,% 4d", totals[5]-4, major(st->st_rdev),minor(st->st_rdev));
+        printf("% *d,% 4d", totals[5]-4, dev_major(st->st_rdev),
+          dev_minor(st->st_rdev));
       else if (flags&FLAG_h) {
         human_readable(tmp, st->st_size, 0);
         xprintf("%*s", totals[5]+1, tmp);
diff --git a/toys/posix/ps.c b/toys/posix/ps.c
index d2ef9fc..26b4a4e 100644
--- a/toys/posix/ps.c
+++ b/toys/posix/ps.c
@@ -701,7 +701,7 @@
         // Couldn't find it, try all the tty drivers.
         if (i == 3) {
           FILE *fp = fopen("/proc/tty/drivers", "r");
-          int tty_major = 0, maj = major(rdev), min = minor(rdev);
+          int tty_major = 0, maj = dev_major(rdev), min = dev_minor(rdev);
 
           if (fp) {
             while (fscanf(fp, "%*s %256s %d %*s %*s", buf, &tty_major) == 2) {