Busybox 1.21.0 squashed commit for jellybean
Change-Id: I423c7fc1254050c6495126b1b18dd33af07fed6b
Signed-off-by: Tanguy Pruvot <tanguy.pruvot@gmail.com>
diff --git a/util-linux/Config.src b/util-linux/Config.src
index 64baae4..135d6a5 100644
--- a/util-linux/Config.src
+++ b/util-linux/Config.src
@@ -741,6 +741,15 @@
help
TODO
+config FEATURE_VOLUMEID_EXFAT
+ bool "exFAT filesystem"
+ default y
+ depends on VOLUMEID
+ help
+ exFAT (extended FAT) is a proprietary file system designed especially
+ for flash drives. It has many features from NTFS, but with less
+ overhead. exFAT is used on most SDXC cards for consumer electronics.
+
config FEATURE_VOLUMEID_HFS
bool "hfs filesystem"
default y
@@ -769,6 +778,13 @@
help
TODO
+config FEATURE_VOLUMEID_NILFS
+ bool "nilfs filesystem"
+ default y
+ depends on VOLUMEID
+ help
+ TODO
+
config FEATURE_VOLUMEID_NTFS
bool "ntfs filesystem"
default y
@@ -832,6 +848,16 @@
help
TODO
+config FEATURE_VOLUMEID_SQUASHFS
+ bool "SquashFS filesystem"
+ default y
+ depends on VOLUMEID && FEATURE_BLKID_TYPE
+ help
+ Squashfs is a compressed read-only filesystem for Linux. Squashfs is
+ intended for general read-only filesystem use and in constrained block
+ device/memory systems (e.g. embedded systems) where low overhead is
+ needed.
+
config FEATURE_VOLUMEID_SYSV
bool "sysv filesystem"
default y
diff --git a/util-linux/acpid.c b/util-linux/acpid.c
index 1b22f3a..38421c2 100644
--- a/util-linux/acpid.c
+++ b/util-linux/acpid.c
@@ -75,6 +75,7 @@
static const struct acpi_event f_evt_tab[] = {
{ "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRF 00000080" },
{ "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRB 00000080" },
+ { "EV_SW", 0x05, "SW_LID", 0x00, 1, "button/lid LID0 00000080" },
};
struct acpi_action {
@@ -234,7 +235,7 @@
const char *opt_action = "/etc/acpid.conf";
const char *opt_map = "/etc/acpi.map";
#if ENABLE_FEATURE_PIDFILE
- const char *opt_pidfile = "/var/run/acpid.pid";
+ const char *opt_pidfile = CONFIG_PID_FILE_PATH "/acpid.pid";
#endif
INIT_G();
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c
index 14051b5..84173ce 100644
--- a/util-linux/dmesg.c
+++ b/util-linux/dmesg.c
@@ -70,7 +70,7 @@
int in = 0, l, color;
char pfx[16], *lvl;
- /* Skip <#> at the start of lines */
+ /* Skip <[0-9]+> at the start of lines */
while (1) {
if (last == '\n' && buf[in] == '<') {
if (opts & OPT_C) {
@@ -96,13 +96,12 @@
full_write(STDOUT_FILENO, pfx, l);
}
- in += 3;
- if (in >= len)
- break;
+ while (buf[in++] != '>' && in < len)
+ ;
+ } else {
+ last = buf[in++];
+ putchar(last);
}
- last = buf[in];
- putchar(last);
- in++;
if (in >= len)
break;
}
diff --git a/util-linux/fdformat.c b/util-linux/fdformat.c
index 2f0854a..b3e918f 100644
--- a/util-linux/fdformat.c
+++ b/util-linux/fdformat.c
@@ -116,7 +116,7 @@
/* Check backwards so we don't need a counter */
while (--read_bytes >= 0) {
if (data[read_bytes] != FD_FILL_BYTE) {
- printf("bad data in cyl %d\nContinuing... ", cyl);
+ printf("bad data in cyl %d\nContinuing... ", cyl);
}
}
}
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index 1fb256e..c1cca10 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -3023,7 +3023,7 @@
printf("\nThe current boot file is: %s\n",
sgi_get_bootfile());
if (read_maybe_empty("Please enter the name of the "
- "new boot file: ") == '\n')
+ "new boot file: ") == '\n')
printf("Boot file unchanged\n");
else
sgi_set_bootfile(line_ptr);
diff --git a/util-linux/fdisk_osf.c b/util-linux/fdisk_osf.c
index 65e6bd7..ff16389 100644
--- a/util-linux/fdisk_osf.c
+++ b/util-linux/fdisk_osf.c
@@ -898,8 +898,7 @@
pp->p_fstype = BSD_FS_UNUSED;
#else
d->d_npartitions = 3;
- pp = &d->d_partitions[2]; /* Partition C should be
- the whole disk */
+ pp = &d->d_partitions[2]; /* Partition C should be the whole disk */
pp->p_offset = 0;
pp->p_size = d->d_secperunit;
pp->p_fstype = BSD_FS_UNUSED;
@@ -935,7 +934,7 @@
fdisk_fatal(unable_to_read);
memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET],
- sizeof(struct xbsd_disklabel));
+ sizeof(struct xbsd_disklabel));
if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC)
return 0;
diff --git a/util-linux/flock.c b/util-linux/flock.c
index e9be4ee..05a747f 100644
--- a/util-linux/flock.c
+++ b/util-linux/flock.c
@@ -45,7 +45,7 @@
if (argv[1]) {
fd = open(argv[0], O_RDONLY|O_NOCTTY|O_CREAT, 0666);
if (fd < 0 && errno == EISDIR)
- fd = open(argv[0], O_RDONLY|O_NOCTTY);
+ fd = open(argv[0], O_RDONLY|O_NOCTTY);
if (fd < 0)
bb_perror_msg_and_die("can't open '%s'", argv[0]);
//TODO? close_on_exec_on(fd);
diff --git a/util-linux/fsck_minix.c b/util-linux/fsck_minix.c
index 1508ecb..c1d1b2c 100644
--- a/util-linux/fsck_minix.c
+++ b/util-linux/fsck_minix.c
@@ -13,7 +13,7 @@
* 10.11.91 - updated, does checking, no repairs yet.
* Sent out to the mailing-list for testing.
*
- * 14.11.91 - Testing seems to have gone well. Added some
+ * 14.11.91 - Testing seems to have gone well. Added some
* correction-code, and changed some functions.
*
* 15.11.91 - More correction code. Hopefully it notices most
@@ -22,11 +22,10 @@
* 16.11.91 - More corrections (thanks to Mika Jalava). Most
* things seem to work now. Yeah, sure.
*
- *
- * 19.04.92 - Had to start over again from this old version, as a
+ * 19.04.92 - Had to start over again from this old version, as a
* kernel bug ate my enhanced fsck in february.
*
- * 28.02.93 - added support for different directory entry sizes..
+ * 28.02.93 - added support for different directory entry sizes..
*
* Sat Mar 6 18:59:42 1993, faith@cs.unc.edu: Output namelen with
* superblock information
@@ -35,31 +34,31 @@
* to that required by fsutil
*
* Mon Jan 3 11:06:52 1994 - Dr. Wettstein (greg%wind.uucp@plains.nodak.edu)
- * Added support for file system valid flag. Also
- * added program_version variable and output of
- * program name and version number when program
- * is executed.
+ * Added support for file system valid flag. Also
+ * added program_version variable and output of
+ * program name and version number when program
+ * is executed.
*
- * 30.10.94 - added support for v2 filesystem
- * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de)
+ * 30.10.94 - added support for v2 filesystem
+ * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de)
*
- * 10.12.94 - added test to prevent checking of mounted fs adapted
- * from Theodore Ts'o's (tytso@athena.mit.edu) e2fsck
- * program. (Daniel Quinlan, quinlan@yggdrasil.com)
+ * 10.12.94 - added test to prevent checking of mounted fs adapted
+ * from Theodore Ts'o's (tytso@athena.mit.edu) e2fsck
+ * program. (Daniel Quinlan, quinlan@yggdrasil.com)
*
* 01.07.96 - Fixed the v2 fs stuff to use the right #defines and such
- * for modern libcs (janl@math.uio.no, Nicolai Langfeldt)
+ * for modern libcs (janl@math.uio.no, Nicolai Langfeldt)
*
* 02.07.96 - Added C bit fiddling routines from rmk@ecs.soton.ac.uk
* (Russell King). He made them for ARM. It would seem
- * that the ARM is powerful enough to do this in C whereas
+ * that the ARM is powerful enough to do this in C whereas
* i386 and m64k must use assembly to get it fast >:-)
- * This should make minix fsck system-independent.
- * (janl@math.uio.no, Nicolai Langfeldt)
+ * This should make minix fsck system-independent.
+ * (janl@math.uio.no, Nicolai Langfeldt)
*
* 04.11.96 - Added minor fixes from Andreas Schwab to avoid compiler
* warnings. Added mc68k bitops from
- * Joerg Dorchain <dorchain@mpi-sb.mpg.de>.
+ * Joerg Dorchain <dorchain@mpi-sb.mpg.de>.
*
* 06.11.96 - Added v2 code submitted by Joerg Dorchain, but written by
* Andreas Schwab.
@@ -1131,7 +1130,7 @@
continue;
}
printf("Zone %d: %sin use, counted=%d\n",
- i, zone_in_use(i) ? "" : "not ", zone_count[i]);
+ i, zone_in_use(i) ? "" : "not ", zone_count[i]);
}
}
@@ -1183,7 +1182,7 @@
continue;
}
printf("Zone %d: %sin use, counted=%d\n",
- i, zone_in_use(i) ? "" : "not ", zone_count[i]);
+ i, zone_in_use(i) ? "" : "not ", zone_count[i]);
}
}
#endif
@@ -1253,7 +1252,7 @@
printf("Forcing filesystem check on %s\n", device_name);
else if (OPT_repair)
printf("Filesystem on %s is dirty, needs checking\n",
- device_name);
+ device_name);
read_tables();
@@ -1280,23 +1279,23 @@
if (!inode_in_use(i))
free_cnt++;
printf("\n%6u inodes used (%u%%)\n", (INODES - free_cnt),
- 100 * (INODES - free_cnt) / INODES);
+ 100 * (INODES - free_cnt) / INODES);
for (i = FIRSTZONE, free_cnt = 0; i < ZONES; i++)
if (!zone_in_use(i))
free_cnt++;
printf("%6u zones used (%u%%)\n\n"
- "%6u regular files\n"
- "%6u directories\n"
- "%6u character device files\n"
- "%6u block device files\n"
- "%6u links\n"
- "%6u symbolic links\n"
- "------\n"
- "%6u files\n",
- (ZONES - free_cnt), 100 * (ZONES - free_cnt) / ZONES,
- regular, directory, chardev, blockdev,
- links - 2 * directory + 1, symlinks,
- total - 2 * directory + 1);
+ "%6u regular files\n"
+ "%6u directories\n"
+ "%6u character device files\n"
+ "%6u block device files\n"
+ "%6u links\n"
+ "%6u symbolic links\n"
+ "------\n"
+ "%6u files\n",
+ (ZONES - free_cnt), 100 * (ZONES - free_cnt) / ZONES,
+ regular, directory, chardev, blockdev,
+ links - 2 * directory + 1, symlinks,
+ total - 2 * directory + 1);
}
if (changed) {
write_tables();
diff --git a/util-linux/getopt.c b/util-linux/getopt.c
index d662c81..1ae0c59 100644
--- a/util-linux/getopt.c
+++ b/util-linux/getopt.c
@@ -372,7 +372,7 @@
if (!argv[1]) {
if (compatible) {
/* For some reason, the original getopt gave no error
- when there were no arguments. */
+ * when there were no arguments. */
printf(" --\n");
return 0;
}
diff --git a/util-linux/ipcrm.c b/util-linux/ipcrm.c
index 274050c..888f70e 100644
--- a/util-linux/ipcrm.c
+++ b/util-linux/ipcrm.c
@@ -160,7 +160,7 @@
/* convert key to id */
id = ((c == 'q') ? msgget(key, 0) :
- (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
+ (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0));
if (id < 0) {
const char *errmsg;
@@ -189,8 +189,8 @@
}
result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) :
- (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
- semctl(id, 0, IPC_RMID, arg));
+ (c == 'm') ? shmctl(id, IPC_RMID, NULL) :
+ semctl(id, 0, IPC_RMID, arg));
if (result) {
const char *errmsg;
diff --git a/util-linux/ipcs.c b/util-linux/ipcs.c
index ee7df5e..2668caf 100644
--- a/util-linux/ipcs.c
+++ b/util-linux/ipcs.c
@@ -152,54 +152,54 @@
if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0)
return;
/* glibc 2.1.3 and all earlier libc's have ints as fields
- of struct shminfo; glibc 2.1.91 has unsigned long; ach */
+ * of struct shminfo; glibc 2.1.91 has unsigned long; ach */
printf("max number of segments = %lu\n"
- "max seg size (kbytes) = %lu\n"
- "max total shared memory (pages) = %lu\n"
- "min seg size (bytes) = %lu\n",
- (unsigned long) shminfo.shmmni,
- (unsigned long) (shminfo.shmmax >> 10),
- (unsigned long) shminfo.shmall,
- (unsigned long) shminfo.shmmin);
+ "max seg size (kbytes) = %lu\n"
+ "max total shared memory (pages) = %lu\n"
+ "min seg size (bytes) = %lu\n",
+ (unsigned long) shminfo.shmmni,
+ (unsigned long) (shminfo.shmmax >> 10),
+ (unsigned long) shminfo.shmall,
+ (unsigned long) shminfo.shmmin);
return;
case STATUS:
printf("------ Shared Memory %s --------\n", "Status");
- printf( "segments allocated %d\n"
- "pages allocated %ld\n"
- "pages resident %ld\n"
- "pages swapped %ld\n"
- "Swap performance: %ld attempts\t%ld successes\n",
- shm_info.used_ids,
- shm_info.shm_tot,
- shm_info.shm_rss,
- shm_info.shm_swp,
- shm_info.swap_attempts, shm_info.swap_successes);
+ printf("segments allocated %d\n"
+ "pages allocated %ld\n"
+ "pages resident %ld\n"
+ "pages swapped %ld\n"
+ "Swap performance: %ld attempts\t%ld successes\n",
+ shm_info.used_ids,
+ shm_info.shm_tot,
+ shm_info.shm_rss,
+ shm_info.shm_swp,
+ shm_info.swap_attempts, shm_info.swap_successes);
return;
case CREATOR:
printf("------ Shared Memory %s --------\n", "Segment Creators/Owners");
- printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n",
- "shmid", "perms", "cuid", "cgid", "uid", "gid");
+ printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
+ "shmid", "perms", "cuid", "cgid", "uid", "gid");
break;
case TIME:
printf("------ Shared Memory %s --------\n", "Attach/Detach/Change Times");
- printf( "%-10s %-10s %-20s %-20s %-20s\n",
- "shmid", "owner", "attached", "detached", "changed");
+ printf("%-10s %-10s %-20s %-20s %-20s\n",
+ "shmid", "owner", "attached", "detached", "changed");
break;
case PID:
printf("------ Shared Memory %s --------\n", "Creator/Last-op");
- printf( "%-10s %-10s %-10s %-10s\n",
- "shmid", "owner", "cpid", "lpid");
+ printf("%-10s %-10s %-10s %-10s\n",
+ "shmid", "owner", "cpid", "lpid");
break;
default:
printf("------ Shared Memory %s --------\n", "Segments");
- printf( "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
- "key", "shmid", "owner", "perms", "bytes", "nattch",
- "status");
+ printf("%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n",
+ "key", "shmid", "owner", "perms", "bytes", "nattch",
+ "status");
break;
}
@@ -220,11 +220,11 @@
printf("%-10d %-10d", shmid, ipcp->uid);
/* ctime uses static buffer: use separate calls */
printf(" %-20.16s", shmseg.shm_atime
- ? ctime(&shmseg.shm_atime) + 4 : "Not set");
+ ? ctime(&shmseg.shm_atime) + 4 : "Not set");
printf(" %-20.16s", shmseg.shm_dtime
- ? ctime(&shmseg.shm_dtime) + 4 : "Not set");
+ ? ctime(&shmseg.shm_dtime) + 4 : "Not set");
printf(" %-20.16s\n", shmseg.shm_ctime
- ? ctime(&shmseg.shm_ctime) + 4 : "Not set");
+ ? ctime(&shmseg.shm_ctime) + 4 : "Not set");
break;
case PID:
if (pw)
@@ -241,17 +241,17 @@
else
printf("%-10d %-10d", shmid, ipcp->uid);
printf(" %-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777,
- /*
- * earlier: int, Austin has size_t
- */
- (unsigned long) shmseg.shm_segsz,
- /*
- * glibc-2.1.3 and earlier has unsigned short;
- * Austin has shmatt_t
- */
- (long) shmseg.shm_nattch,
- ipcp->mode & SHM_DEST ? "dest" : " ",
- ipcp->mode & SHM_LOCKED ? "locked" : " ");
+ /*
+ * earlier: int, Austin has size_t
+ */
+ (unsigned long) shmseg.shm_segsz,
+ /*
+ * glibc-2.1.3 and earlier has unsigned short;
+ * Austin has shmatt_t
+ */
+ (long) shmseg.shm_nattch,
+ ipcp->mode & SHM_DEST ? "dest" : " ",
+ ipcp->mode & SHM_LOCKED ? "locked" : " ");
break;
}
}
@@ -281,32 +281,32 @@
if ((semctl(0, 0, IPC_INFO, arg)) < 0)
return;
printf("max number of arrays = %d\n"
- "max semaphores per array = %d\n"
- "max semaphores system wide = %d\n"
- "max ops per semop call = %d\n"
- "semaphore max value = %d\n",
- seminfo.semmni,
- seminfo.semmsl,
- seminfo.semmns, seminfo.semopm, seminfo.semvmx);
+ "max semaphores per array = %d\n"
+ "max semaphores system wide = %d\n"
+ "max ops per semop call = %d\n"
+ "semaphore max value = %d\n",
+ seminfo.semmni,
+ seminfo.semmsl,
+ seminfo.semmns, seminfo.semopm, seminfo.semvmx);
return;
case STATUS:
printf("------ Semaphore %s --------\n", "Status");
- printf( "used arrays = %d\n"
- "allocated semaphores = %d\n",
- seminfo.semusz, seminfo.semaem);
+ printf("used arrays = %d\n"
+ "allocated semaphores = %d\n",
+ seminfo.semusz, seminfo.semaem);
return;
case CREATOR:
printf("------ Semaphore %s --------\n", "Arrays Creators/Owners");
- printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n",
- "semid", "perms", "cuid", "cgid", "uid", "gid");
+ printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
+ "semid", "perms", "cuid", "cgid", "uid", "gid");
break;
case TIME:
printf("------ Shared Memory %s --------\n", "Operation/Change Times");
- printf( "%-8s %-10s %-26.24s %-26.24s\n",
- "shmid", "owner", "last-op", "last-changed");
+ printf("%-8s %-10s %-26.24s %-26.24s\n",
+ "shmid", "owner", "last-op", "last-changed");
break;
case PID:
@@ -314,8 +314,8 @@
default:
printf("------ Semaphore %s --------\n", "Arrays");
- printf( "%-10s %-10s %-10s %-10s %-10s\n",
- "key", "semid", "owner", "perms", "nsems");
+ printf("%-10s %-10s %-10s %-10s %-10s\n",
+ "key", "semid", "owner", "perms", "nsems");
break;
}
@@ -337,9 +337,9 @@
printf("%-8d %-10d", semid, ipcp->uid);
/* ctime uses static buffer: use separate calls */
printf(" %-26.24s", semary.sem_otime
- ? ctime(&semary.sem_otime) : "Not set");
+ ? ctime(&semary.sem_otime) : "Not set");
printf(" %-26.24s\n", semary.sem_ctime
- ? ctime(&semary.sem_ctime) : "Not set");
+ ? ctime(&semary.sem_ctime) : "Not set");
break;
case PID:
break;
@@ -351,13 +351,13 @@
else
printf("%-10d %-9d", semid, ipcp->uid);
printf(" %-10o %-10ld\n", ipcp->mode & 0777,
- /*
- * glibc-2.1.3 and earlier has unsigned short;
- * glibc-2.1.91 has variation between
- * unsigned short and unsigned long
- * Austin prescribes unsigned short.
- */
- (long) semary.sem_nsems);
+ /*
+ * glibc-2.1.3 and earlier has unsigned short;
+ * glibc-2.1.91 has variation between
+ * unsigned short and unsigned long
+ * Austin prescribes unsigned short.
+ */
+ (long) semary.sem_nsems);
break;
}
}
@@ -383,42 +383,42 @@
if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0)
return;
printf("------ Message%s --------\n", "s: Limits");
- printf( "max queues system wide = %d\n"
- "max size of message (bytes) = %d\n"
- "default max size of queue (bytes) = %d\n",
- msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb);
+ printf("max queues system wide = %d\n"
+ "max size of message (bytes) = %d\n"
+ "default max size of queue (bytes) = %d\n",
+ msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb);
return;
case STATUS:
printf("------ Message%s --------\n", "s: Status");
- printf( "allocated queues = %d\n"
- "used headers = %d\n"
- "used space = %d bytes\n",
- msginfo.msgpool, msginfo.msgmap, msginfo.msgtql);
+ printf("allocated queues = %d\n"
+ "used headers = %d\n"
+ "used space = %d bytes\n",
+ msginfo.msgpool, msginfo.msgmap, msginfo.msgtql);
return;
case CREATOR:
printf("------ Message%s --------\n", " Queues: Creators/Owners");
- printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n",
- "msqid", "perms", "cuid", "cgid", "uid", "gid");
+ printf("%-10s %-10s %-10s %-10s %-10s %-10s\n",
+ "msqid", "perms", "cuid", "cgid", "uid", "gid");
break;
case TIME:
printf("------ Message%s --------\n", " Queues Send/Recv/Change Times");
- printf( "%-8s %-10s %-20s %-20s %-20s\n",
- "msqid", "owner", "send", "recv", "change");
+ printf("%-8s %-10s %-20s %-20s %-20s\n",
+ "msqid", "owner", "send", "recv", "change");
break;
case PID:
printf("------ Message%s --------\n", " Queues PIDs");
- printf( "%-10s %-10s %-10s %-10s\n",
- "msqid", "owner", "lspid", "lrpid");
+ printf("%-10s %-10s %-10s %-10s\n",
+ "msqid", "owner", "lspid", "lrpid");
break;
default:
printf("------ Message%s --------\n", " Queues");
- printf( "%-10s %-10s %-10s %-10s %-12s %-12s\n",
- "key", "msqid", "owner", "perms", "used-bytes", "messages");
+ printf("%-10s %-10s %-10s %-10s %-12s %-12s\n",
+ "key", "msqid", "owner", "perms", "used-bytes", "messages");
break;
}
@@ -438,11 +438,11 @@
else
printf("%-8d %-10d", msqid, ipcp->uid);
printf(" %-20.16s", msgque.msg_stime
- ? ctime(&msgque.msg_stime) + 4 : "Not set");
+ ? ctime(&msgque.msg_stime) + 4 : "Not set");
printf(" %-20.16s", msgque.msg_rtime
- ? ctime(&msgque.msg_rtime) + 4 : "Not set");
+ ? ctime(&msgque.msg_rtime) + 4 : "Not set");
printf(" %-20.16s\n", msgque.msg_ctime
- ? ctime(&msgque.msg_ctime) + 4 : "Not set");
+ ? ctime(&msgque.msg_ctime) + 4 : "Not set");
break;
case PID:
if (pw)
@@ -459,13 +459,13 @@
else
printf("%-10d %-10d", msqid, ipcp->uid);
printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777,
- /*
- * glibc-2.1.3 and earlier has unsigned short;
- * glibc-2.1.91 has variation between
- * unsigned short, unsigned long
- * Austin has msgqnum_t
- */
- (long) msgque.msg_cbytes, (long) msgque.msg_qnum);
+ /*
+ * glibc-2.1.3 and earlier has unsigned short;
+ * glibc-2.1.91 has variation between
+ * unsigned short, unsigned long
+ * Austin has msgqnum_t
+ */
+ (long) msgque.msg_cbytes, (long) msgque.msg_qnum);
break;
}
}
@@ -483,18 +483,18 @@
}
printf("\nShared memory Segment shmid=%d\n"
- "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
- "mode=%#o\taccess_perms=%#o\n"
- "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n",
- shmid,
- ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
- ipcp->mode, ipcp->mode & 0777,
- (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
- (long) shmds.shm_nattch);
+ "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n"
+ "mode=%#o\taccess_perms=%#o\n"
+ "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n",
+ shmid,
+ ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
+ ipcp->mode, ipcp->mode & 0777,
+ (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid,
+ (long) shmds.shm_nattch);
printf("att_time=%-26.24s\n",
- shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set");
+ shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set");
printf("det_time=%-26.24s\n",
- shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set");
+ shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set");
printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime));
}
@@ -510,24 +510,24 @@
}
printf("\nMessage Queue msqid=%d\n"
- "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
- "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n",
- msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
- /*
- * glibc-2.1.3 and earlier has unsigned short;
- * glibc-2.1.91 has variation between
- * unsigned short, unsigned long
- * Austin has msgqnum_t (for msg_qbytes)
- */
- (long) buf.msg_cbytes, (long) buf.msg_qbytes,
- (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid);
+ "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n"
+ "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n",
+ msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode,
+ /*
+ * glibc-2.1.3 and earlier has unsigned short;
+ * glibc-2.1.91 has variation between
+ * unsigned short, unsigned long
+ * Austin has msgqnum_t (for msg_qbytes)
+ */
+ (long) buf.msg_cbytes, (long) buf.msg_qbytes,
+ (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid);
printf("send_time=%-26.24s\n",
- buf.msg_stime ? ctime(&buf.msg_stime) : "Not set");
+ buf.msg_stime ? ctime(&buf.msg_stime) : "Not set");
printf("rcv_time=%-26.24s\n",
- buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set");
+ buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set");
printf("change_time=%-26.24s\n\n",
- buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set");
+ buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set");
}
static void print_sem(int semid)
@@ -544,19 +544,19 @@
}
printf("\nSemaphore Array semid=%d\n"
- "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
- "mode=%#o, access_perms=%#o\n"
- "nsems = %ld\n"
- "otime = %-26.24s\n",
- semid,
- ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
- ipcp->mode, ipcp->mode & 0777,
- (long) semds.sem_nsems,
- semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
+ "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n"
+ "mode=%#o, access_perms=%#o\n"
+ "nsems = %ld\n"
+ "otime = %-26.24s\n",
+ semid,
+ ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid,
+ ipcp->mode, ipcp->mode & 0777,
+ (long) semds.sem_nsems,
+ semds.sem_otime ? ctime(&semds.sem_otime) : "Not set");
printf("ctime = %-26.24s\n"
- "%-10s %-10s %-10s %-10s %-10s\n",
- ctime(&semds.sem_ctime),
- "semnum", "value", "ncount", "zcount", "pid");
+ "%-10s %-10s %-10s %-10s %-10s\n",
+ ctime(&semds.sem_ctime),
+ "semnum", "value", "ncount", "zcount", "pid");
arg.val = 0;
for (i = 0; i < semds.sem_nsems; i++) {
diff --git a/util-linux/lspci.c b/util-linux/lspci.c
index 5184858..514678a 100644
--- a/util-linux/lspci.c
+++ b/util-linux/lspci.c
@@ -74,11 +74,11 @@
if (option_mask32 & OPT_m) {
printf("%s \"Class %04x\" \"%04x\" \"%04x\" \"%04x\" \"%04x\"",
- pci_slot_name, pci_class, pci_vid, pci_did,
- pci_subsys_vid, pci_subsys_did);
+ pci_slot_name, pci_class, pci_vid, pci_did,
+ pci_subsys_vid, pci_subsys_did);
} else {
printf("%s Class %04x: %04x:%04x",
- pci_slot_name, pci_class, pci_vid, pci_did);
+ pci_slot_name, pci_class, pci_vid, pci_did);
}
if ((option_mask32 & OPT_k) && driver) {
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index c4829a5..75de14f 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -92,7 +92,9 @@
//usage: "\n"
//usage: "If /dev/mdev.seq file exists, mdev will wait for its value\n"
//usage: "to match $SEQNUM variable. This prevents plug/unplug races.\n"
-//usage: "To activate this feature, create empty /dev/mdev.seq at boot."
+//usage: "To activate this feature, create empty /dev/mdev.seq at boot.\n"
+//usage: "\n"
+//usage: "If /dev/mdev.log file exists, debug log will be appended to it."
#include "libbb.h"
#include "xregex.h"
@@ -139,10 +141,101 @@
* This happens regardless of /sys/class/.../dev existence.
*/
+/* Kernel's hotplug environment constantly changes.
+ * Here are new cases I observed on 3.1.0:
+ *
+ * Case with $DEVNAME and $DEVICE, not just $DEVPATH:
+ * ACTION=add
+ * BUSNUM=001
+ * DEVICE=/proc/bus/usb/001/003
+ * DEVNAME=bus/usb/001/003
+ * DEVNUM=003
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5
+ * DEVTYPE=usb_device
+ * MAJOR=189
+ * MINOR=2
+ * PRODUCT=18d1/4e12/227
+ * SUBSYSTEM=usb
+ * TYPE=0/0/0
+ *
+ * Case with $DEVICE, but no $DEVNAME - apparenty, usb iface notification?
+ * "Please load me a module" thing?
+ * ACTION=add
+ * DEVICE=/proc/bus/usb/001/003
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0
+ * DEVTYPE=usb_interface
+ * INTERFACE=8/6/80
+ * MODALIAS=usb:v18D1p4E12d0227dc00dsc00dp00ic08isc06ip50
+ * PRODUCT=18d1/4e12/227
+ * SUBSYSTEM=usb
+ * TYPE=0/0/0
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5
+ * DEVTYPE=scsi_host
+ * SUBSYSTEM=scsi
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/scsi_host/host5
+ * SUBSYSTEM=scsi_host
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0
+ * DEVTYPE=scsi_target
+ * SUBSYSTEM=scsi
+ *
+ * Case with strange $MODALIAS:
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0
+ * DEVTYPE=scsi_device
+ * MODALIAS=scsi:t-0x00
+ * SUBSYSTEM=scsi
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/scsi_disk/5:0:0:0
+ * SUBSYSTEM=scsi_disk
+ *
+ * ACTION=add
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/scsi_device/5:0:0:0
+ * SUBSYSTEM=scsi_device
+ *
+ * Case with explicit $MAJOR/$MINOR (no need to read /sys/$DEVPATH/dev?):
+ * ACTION=add
+ * DEVNAME=bsg/5:0:0:0
+ * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/bsg/5:0:0:0
+ * MAJOR=253
+ * MINOR=1
+ * SUBSYSTEM=bsg
+ *
+ * ACTION=add
+ * DEVPATH=/devices/virtual/bdi/8:16
+ * SUBSYSTEM=bdi
+ *
+ * ACTION=add
+ * DEVNAME=sdb
+ * DEVPATH=/block/sdb
+ * DEVTYPE=disk
+ * MAJOR=8
+ * MINOR=16
+ * SUBSYSTEM=block
+ *
+ * Case with ACTION=change:
+ * ACTION=change
+ * DEVNAME=sdb
+ * DEVPATH=/block/sdb
+ * DEVTYPE=disk
+ * DISK_MEDIA_CHANGE=1
+ * MAJOR=8
+ * MINOR=16
+ * SUBSYSTEM=block
+ */
+
+static const char keywords[] ALIGN1 = "add\0remove\0change\0";
+enum { OP_add, OP_remove };
+
struct rule {
bool keep_matching;
bool regex_compiled;
- bool regex_has_slash;
mode_t mode;
int maj, min0, min1;
struct bb_uidgid_t ugid;
@@ -154,6 +247,7 @@
struct globals {
int root_major, root_minor;
+ smallint verbose;
char *subsystem;
#if ENABLE_FEATURE_MDEV_CONF
const char *filename;
@@ -245,7 +339,6 @@
}
xregcomp(&G.cur_rule.match, val, REG_EXTENDED);
G.cur_rule.regex_compiled = 1;
- G.cur_rule.regex_has_slash = (strchr(val, '/') != NULL);
}
/* 2nd field: uid:gid - device ownership */
@@ -336,6 +429,18 @@
#endif
+static void mkdir_recursive(char *name)
+{
+ /* if name has many levels ("dir1/dir2"),
+ * bb_make_directory() will create dir1 according to umask,
+ * not according to its "mode" parameter.
+ * Since we run with umask=0, need to temporarily switch it.
+ */
+ umask(022); /* "dir1" (if any) will be 0755 too */
+ bb_make_directory(name, 0755, FILEUTILS_RECUR);
+ umask(0);
+}
+
/* Builds an alias path.
* This function potentionally reallocates the alias parameter.
* Only used for ENABLE_FEATURE_MDEV_RENAME
@@ -349,7 +454,7 @@
dest = strrchr(alias, '/');
if (dest) { /* ">bar/[baz]" ? */
*dest = '\0'; /* mkdir bar */
- bb_make_directory(alias, 0755, FILEUTILS_RECUR);
+ mkdir_recursive(alias);
*dest = '/';
if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */
dest = alias;
@@ -366,13 +471,16 @@
* after NUL, but we promise to not mangle (IOW: to restore if needed)
* path string.
* NB2: "mdev -s" may call us many times, do not leak memory/fds!
+ *
+ * device_name = $DEVNAME (may be NULL)
+ * path = /sys/$DEVPATH
*/
-static void make_device(char *path, int delete)
+static void make_device(char *device_name, char *path, int operation)
{
- char *device_name, *subsystem_slash_devname;
int major, minor, type, len;
- dbg("%s('%s', delete:%d)", __func__, path, delete);
+ if (G.verbose)
+ bb_error_msg("device: %s, %s", device_name, path);
/* Try to read major/minor string. Note that the kernel puts \n after
* the data, so we don't need to worry about null terminating the string
@@ -380,7 +488,7 @@
* We also depend on path having writeable space after it.
*/
major = -1;
- if (!delete) {
+ if (operation == OP_add) {
char *dev_maj_min = path + strlen(path);
strcpy(dev_maj_min, "/dev");
@@ -391,40 +499,27 @@
return;
/* no "dev" file, but we can still run scripts
* based on device name */
- } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) != 2) {
+ } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) == 2) {
+ if (G.verbose)
+ bb_error_msg("maj,min: %u,%u", major, minor);
+ } else {
major = -1;
}
}
/* else: for delete, -1 still deletes the node, but < -1 suppresses that */
/* Determine device name, type, major and minor */
- device_name = (char*) bb_basename(path);
+ if (!device_name)
+ device_name = (char*) bb_basename(path);
/* http://kernel.org/doc/pending/hotplug.txt says that only
* "/sys/block/..." is for block devices. "/sys/bus" etc is not.
* But since 2.6.25 block devices are also in /sys/class/block.
- * We use strstr("/block/") to forestall future surprises. */
+ * We use strstr("/block/") to forestall future surprises.
+ */
type = S_IFCHR;
if (strstr(path, "/block/") || (G.subsystem && strncmp(G.subsystem, "block", 5) == 0))
type = S_IFBLK;
- /* Make path point to "subsystem/device_name" */
- subsystem_slash_devname = NULL;
- /* Check for coldplug invocations first */
- if (strncmp(path, "/sys/block/", 11) == 0) /* legacy case */
- path += sizeof("/sys/") - 1;
- else if (strncmp(path, "/sys/class/", 11) == 0)
- path += sizeof("/sys/class/") - 1;
- else {
- /* Example of a hotplug invocation:
- * SUBSYSTEM="block"
- * DEVPATH="/sys" + "/devices/virtual/mtd/mtd3/mtdblock3"
- * ("/sys" is added by mdev_main)
- * - path does not contain subsystem
- */
- subsystem_slash_devname = concat_path_file(G.subsystem, device_name);
- path = subsystem_slash_devname;
- }
-
#if ENABLE_FEATURE_MDEV_CONF
G.rule_idx = 0; /* restart from the beginning (think mdev -s) */
#endif
@@ -434,10 +529,10 @@
char *command;
char *alias;
char aliaslink = aliaslink; /* for compiler */
- const char *node_name;
+ char *node_name;
const struct rule *rule;
- str_to_match = "";
+ str_to_match = device_name;
rule = next_rule();
@@ -455,10 +550,8 @@
dbg("getenv('%s'):'%s'", rule->envvar, str_to_match);
if (!str_to_match)
continue;
- } else {
- /* regex to match [subsystem/]device_name */
- str_to_match = (rule->regex_has_slash ? path : device_name);
}
+ /* else: str_to_match = device_name */
if (rule->regex_compiled) {
int regex_match = regexec(&rule->match, str_to_match, ARRAY_SIZE(off), off, 0);
@@ -537,7 +630,7 @@
/* Are we running this command now?
* Run $cmd on delete, @cmd on create, *cmd on both
*/
- if (s2 - s != delete) {
+ if (s2 - s != (operation == OP_remove) || *s2 == '*') {
/* We are here if: '*',
* or: '@' and delete = 0,
* or: '$' and delete = 1
@@ -556,21 +649,30 @@
dbg("alias2:'%s'", alias);
}
- if (!delete && major >= 0) {
- dbg("mknod('%s',%o,(%d,%d))", node_name, rule->mode | type, major, minor);
+ if (operation == OP_add && major >= 0) {
+ char *slash = strrchr(node_name, '/');
+ if (slash) {
+ *slash = '\0';
+ mkdir_recursive(node_name);
+ *slash = '/';
+ }
+ if (G.verbose)
+ bb_error_msg("mknod: %s (%d,%d) %o", node_name, major, minor, rule->mode | type);
if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST)
bb_perror_msg("can't create '%s'", node_name);
- if (major == G.root_major && minor == G.root_minor)
- symlink(node_name, "root");
if (ENABLE_FEATURE_MDEV_CONF) {
chmod(node_name, rule->mode);
chown(node_name, rule->ugid.uid, rule->ugid.gid);
}
+ if (major == G.root_major && minor == G.root_minor)
+ symlink(node_name, "root");
if (ENABLE_FEATURE_MDEV_RENAME && alias) {
if (aliaslink == '>') {
//TODO: on devtmpfs, device_name already exists and symlink() fails.
//End result is that instead of symlink, we have two nodes.
//What should be done?
+ if (G.verbose)
+ bb_error_msg("symlink: %s", device_name);
symlink(node_name, device_name);
}
}
@@ -582,17 +684,24 @@
char *s1 = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem);
putenv(s);
putenv(s1);
+ if (G.verbose)
+ bb_error_msg("running: %s", command);
if (system(command) == -1)
bb_perror_msg("can't run '%s'", command);
bb_unsetenv_and_free(s1);
bb_unsetenv_and_free(s);
}
- if (delete && major >= -1) {
+ if (operation == OP_remove && major >= -1) {
if (ENABLE_FEATURE_MDEV_RENAME && alias) {
- if (aliaslink == '>')
+ if (aliaslink == '>') {
+ if (G.verbose)
+ bb_error_msg("unlink: %s", device_name);
unlink(device_name);
+ }
}
+ if (G.verbose)
+ bb_error_msg("unlink: %s", node_name);
unlink(node_name);
}
@@ -605,8 +714,6 @@
if (!ENABLE_FEATURE_MDEV_CONF || !rule->keep_matching)
break;
} /* for (;;) */
-
- free(subsystem_slash_devname);
}
/* File callback for /sys/ traversal */
@@ -624,7 +731,7 @@
strcpy(scratch, fileName);
scratch[len] = '\0';
- make_device(scratch, /*delete:*/ 0);
+ make_device(/*DEVNAME:*/ NULL, scratch, OP_add);
return TRUE;
}
@@ -696,7 +803,7 @@
}
/* Tell kernel result by "echo [0|-1] > /sys/$DEVPATH/loading"
- * Note: we emit -1 if firmware file wasn't found.
+ * Note: we emit -1 also if firmware file wasn't found.
* There are cases when otherwise kernel would wait for minutes
* before timing out.
*/
@@ -769,9 +876,8 @@
char *fw;
char *seq;
char *action;
- char *env_path;
- static const char keywords[] ALIGN1 = "remove\0add\0";
- enum { OP_remove = 0, OP_add };
+ char *env_devname;
+ char *env_devpath;
smalluint op;
/* Hotplug:
@@ -780,12 +886,13 @@
* DEVPATH is like "/block/sda" or "/class/input/mice"
*/
action = getenv("ACTION");
- env_path = getenv("DEVPATH");
+ op = index_in_strings(keywords, action);
+ env_devname = getenv("DEVNAME"); /* can be NULL */
+ env_devpath = getenv("DEVPATH");
G.subsystem = getenv("SUBSYSTEM");
- if (!action || !env_path /*|| !G.subsystem*/)
+ if (!action || !env_devpath /*|| !G.subsystem*/)
bb_show_usage();
fw = getenv("FIRMWARE");
- op = index_in_strings(keywords, action);
/* If it exists, does /dev/mdev.seq match $SEQNUM?
* If it does not match, earlier mdev is running
* in parallel, and we need to wait */
@@ -811,16 +918,25 @@
} while (--timeout);
}
- snprintf(temp, PATH_MAX, "/sys%s", env_path);
+ {
+ int logfd = open("/dev/mdev.log", O_WRONLY | O_APPEND);
+ if (logfd >= 0) {
+ xmove_fd(logfd, STDERR_FILENO);
+ G.verbose = 1;
+ bb_error_msg("seq: %s action: %s", seq, action);
+ }
+ }
+
+ snprintf(temp, PATH_MAX, "/sys%s", env_devpath);
if (op == OP_remove) {
/* Ignoring "remove firmware". It was reported
* to happen and to cause erroneous deletion
* of device nodes. */
if (!fw)
- make_device(temp, /*delete:*/ 1);
+ make_device(env_devname, temp, op);
}
else if (op == OP_add) {
- make_device(temp, /*delete:*/ 0);
+ make_device(env_devname, temp, op);
if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) {
if (fw)
load_firmware(fw, temp);
diff --git a/util-linux/mount.c b/util-linux/mount.c
index 34543bb..7e547fe 100644
--- a/util-linux/mount.c
+++ b/util-linux/mount.c
@@ -36,6 +36,10 @@
//usage: IF_FEATURE_MTAB_SUPPORT(
//usage: "\n -n Don't update /etc/mtab"
//usage: )
+//usage: IF_FEATURE_MOUNT_VERBOSE(
+//usage: "\n -v Verbose"
+//usage: )
+////usage: "\n -s Sloppy (ignored)"
//usage: "\n -r Read-only mount"
//usage: "\n -w Read-write mount (default)"
//usage: "\n -t FSTYPE[,...] Filesystem type(s)"
@@ -113,6 +117,12 @@
#ifndef MS_RELATIME
# define MS_RELATIME (1 << 21)
#endif
+#ifndef MS_STRICTATIME
+# define MS_STRICTATIME (1 << 24)
+#endif
+
+/* Any ~MS_FOO value has this bit set: */
+#define BB_MS_INVERTED_VALUE (1u << 31)
#include "libbb.h"
#if ENABLE_FEATURE_MOUNT_LABEL
@@ -218,6 +228,7 @@
IF_DESKTOP(/* "user" */ MOUNT_USERS,)
IF_DESKTOP(/* "users" */ MOUNT_USERS,)
/* "_netdev" */ 0,
+ IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */
)
IF_FEATURE_MOUNT_FLAGS(
@@ -239,6 +250,7 @@
/* "nomand" */ ~MS_MANDLOCK,
/* "relatime" */ MS_RELATIME,
/* "norelatime" */ ~MS_RELATIME,
+ /* "strictatime" */ MS_STRICTATIME,
/* "loud" */ ~MS_SILENT,
/* "rbind" */ MS_BIND|MS_RECURSIVE,
@@ -275,6 +287,7 @@
IF_DESKTOP("user\0")
IF_DESKTOP("users\0")
"_netdev\0"
+ IF_DESKTOP("comment=\0") /* systemd uses this in fstab */
)
IF_FEATURE_MOUNT_FLAGS(
// vfs flags
@@ -295,6 +308,7 @@
"nomand\0"
"relatime\0"
"norelatime\0"
+ "strictatime\0"
"loud\0"
"rbind\0"
@@ -450,9 +464,9 @@
// Use the mount_options list to parse options into flags.
// Also update list of unrecognized options if unrecognized != NULL
-static long parse_mount_options(char *options, char **unrecognized)
+static unsigned long parse_mount_options(char *options, char **unrecognized)
{
- long flags = MS_SILENT;
+ unsigned long flags = MS_SILENT;
// Loop through options
for (;;) {
@@ -465,15 +479,22 @@
// FIXME: use hasmntopt()
// Find this option in mount_options
for (i = 0; i < ARRAY_SIZE(mount_options); i++) {
- if (strcasecmp(option_str, options) == 0) {
- long fl = mount_options[i];
- if (fl < 0)
+ unsigned opt_len = strlen(option_str);
+
+ if (strncasecmp(option_str, options, opt_len) == 0
+ && (options[opt_len] == '\0'
+ /* or is it "comment=" thingy in fstab? */
+ IF_FEATURE_MOUNT_FSTAB(IF_DESKTOP( || option_str[opt_len-1] == '=' ))
+ )
+ ) {
+ unsigned long fl = mount_options[i];
+ if (fl & BB_MS_INVERTED_VALUE)
flags &= fl;
else
flags |= fl;
goto found;
}
- option_str += strlen(option_str) + 1;
+ option_str += opt_len + 1;
}
// We did not recognize this option.
// If "unrecognized" is not NULL, append option there.
@@ -548,7 +569,7 @@
// Perform actual mount of specific filesystem at specific location.
// NB: mp->xxx fields may be trashed on exit
-static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts)
+static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filteropts)
{
int rc = 0;
@@ -913,7 +934,7 @@
static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp)
{
if (!xdr_u_int(xdrs, &objp->fhs_status))
- return FALSE;
+ return FALSE;
if (objp->fhs_status == 0)
return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle);
return TRUE;
@@ -927,8 +948,8 @@
static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp)
{
return xdr_bytes(xdrs, (char **)&objp->fhandle3_val,
- (unsigned int *) &objp->fhandle3_len,
- FHSIZE3);
+ (unsigned int *) &objp->fhandle3_len,
+ FHSIZE3);
}
static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp)
@@ -936,10 +957,10 @@
if (!xdr_fhandle3(xdrs, &objp->fhandle))
return FALSE;
return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val),
- &(objp->auth_flavours.auth_flavours_len),
- ~0,
- sizeof(int),
- (xdrproc_t) xdr_int);
+ &(objp->auth_flavours.auth_flavours_len),
+ ~0,
+ sizeof(int),
+ (xdrproc_t) xdr_int);
}
static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp)
@@ -1080,7 +1101,7 @@
}
/* NB: mp->xxx fields may be trashed on exit */
-static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts)
+static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts)
{
CLIENT *mclient;
char *hostname;
@@ -1508,19 +1529,19 @@
switch (pm_mnt.pm_prot) {
case IPPROTO_UDP:
mclient = clntudp_create(&mount_server_addr,
- pm_mnt.pm_prog,
- pm_mnt.pm_vers,
- retry_timeout,
- &msock);
+ pm_mnt.pm_prog,
+ pm_mnt.pm_vers,
+ retry_timeout,
+ &msock);
if (mclient)
break;
mount_server_addr.sin_port = htons(pm_mnt.pm_port);
msock = RPC_ANYSOCK;
case IPPROTO_TCP:
mclient = clnttcp_create(&mount_server_addr,
- pm_mnt.pm_prog,
- pm_mnt.pm_vers,
- &msock, 0, 0);
+ pm_mnt.pm_prog,
+ pm_mnt.pm_vers,
+ &msock, 0, 0);
break;
default:
mclient = NULL;
@@ -1541,18 +1562,18 @@
if (pm_mnt.pm_vers == 3)
clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT,
- (xdrproc_t) xdr_dirpath,
- (caddr_t) &pathname,
- (xdrproc_t) xdr_mountres3,
- (caddr_t) &status,
- total_timeout);
+ (xdrproc_t) xdr_dirpath,
+ (caddr_t) &pathname,
+ (xdrproc_t) xdr_mountres3,
+ (caddr_t) &status,
+ total_timeout);
else
clnt_stat = clnt_call(mclient, MOUNTPROC_MNT,
- (xdrproc_t) xdr_dirpath,
- (caddr_t) &pathname,
- (xdrproc_t) xdr_fhstatus,
- (caddr_t) &status,
- total_timeout);
+ (xdrproc_t) xdr_dirpath,
+ (caddr_t) &pathname,
+ (xdrproc_t) xdr_fhstatus,
+ (caddr_t) &status,
+ total_timeout);
if (clnt_stat == RPC_SUCCESS)
goto prepare_kernel_data; /* we're done */
@@ -1711,7 +1732,7 @@
* For older kernels, you must build busybox with ENABLE_FEATURE_MOUNT_NFS.
* (However, note that then you lose any chances that NFS over IPv6 would work).
*/
-static int nfsmount(struct mntent *mp, long vfsflags, char *filteropts)
+static int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts)
{
len_and_sockaddr *lsa;
char *opts;
@@ -1753,7 +1774,7 @@
static int singlemount(struct mntent *mp, int ignore_busy)
{
int rc = -1;
- long vfsflags;
+ unsigned long vfsflags;
char *loopFile = NULL, *filteropts = NULL;
llist_t *fl = NULL;
struct stat st;
@@ -1803,17 +1824,44 @@
) {
int len;
char c;
+ char *hostname, *share;
+ char *dotted, *ip;
len_and_sockaddr *lsa;
- char *hostname, *dotted, *ip;
+
+ // Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]"
hostname = mp->mnt_fsname + 2;
len = strcspn(hostname, "/\\");
- if (len == 0 || hostname[len] == '\0')
+ share = hostname + len + 1;
+ if (len == 0 // 3rd char is a [back]slash (IOW: empty hostname)
+ || share[-1] == '\0' // no [back]slash after hostname
+ || share[0] == '\0' // empty share name
+ ) {
goto report_error;
- c = hostname[len];
- hostname[len] = '\0';
+ }
+ c = share[-1];
+ share[-1] = '\0';
+ len = strcspn(share, "/\\");
+
+ // "unc=\\hostname\share" option is mandatory
+ // after CIFS option parsing was rewritten in Linux 3.4.
+ // Must use backslashes.
+ // If /dir1/dir2 is present, also add "prefixpath=dir1/dir2"
+ {
+ char *unc = xasprintf(
+ share[len] != '\0' /* "/dir1/dir2" exists? */
+ ? "unc=\\\\%s\\%.*s,prefixpath=%s"
+ : "unc=\\\\%s\\%.*s",
+ hostname,
+ len, share,
+ share + len + 1 /* "dir1/dir2" */
+ );
+ parse_mount_options(unc, &filteropts);
+ if (ENABLE_FEATURE_CLEAN_UP) free(unc);
+ }
+
lsa = host2sockaddr(hostname, 0);
- hostname[len] = c;
+ share[-1] = c;
if (!lsa)
goto report_error;
@@ -1825,8 +1873,6 @@
parse_mount_options(ip, &filteropts);
if (ENABLE_FEATURE_CLEAN_UP) free(ip);
- // "-o mand" is required [why?]
- vfsflags |= MS_MANDLOCK;
mp->mnt_type = (char*)"cifs";
rc = mount_it_now(mp, vfsflags, filteropts);
@@ -1854,7 +1900,7 @@
if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) {
loopFile = bb_simplify_path(mp->mnt_fsname);
mp->mnt_fsname = NULL; // will receive malloced loop dev name
- if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ 0) < 0) {
+ if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ (vfsflags & MS_RDONLY)) < 0) {
if (errno == EPERM || errno == EACCES)
bb_error_msg("%s", bb_msg_perm_denied_are_you_root);
else
@@ -1992,6 +2038,7 @@
FILE *fstab;
int i, j;
int rc = EXIT_SUCCESS;
+ unsigned long cmdopt_flags;
unsigned opt;
struct mntent mtpair[2], *mtcur = mtpair;
IF_NOT_DESKTOP(const int nonroot = 0;)
@@ -2066,16 +2113,16 @@
// Past this point, we are handling either "mount -a [opts]"
// or "mount [opts] single_param"
- i = parse_mount_options(cmdopts, NULL); // FIXME: should be "long", not "int"
- if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags
+ cmdopt_flags = parse_mount_options(cmdopts, NULL);
+ if (nonroot && (cmdopt_flags & ~MS_SILENT)) // Non-root users cannot specify flags
bb_error_msg_and_die("%s", bb_msg_you_must_be_root);
// If we have a shared subtree flag, don't worry about fstab or mtab.
if (ENABLE_FEATURE_MOUNT_FLAGS
- && (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
+ && (cmdopt_flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
) {
// verbose_mount(source, target, type, flags, data)
- rc = verbose_mount("", argv[0], "", i, "");
+ rc = verbose_mount("", argv[0], "", cmdopt_flags, "");
if (rc)
bb_simple_perror_msg_and_die(argv[0]);
return rc;
@@ -2083,7 +2130,7 @@
// Open either fstab or mtab
fstabname = "/etc/fstab";
- if (i & MS_REMOUNT) {
+ if (cmdopt_flags & MS_REMOUNT) {
// WARNING. I am not sure this matches util-linux's
// behavior. It's possible util-linux does not
// take -o opts from mtab (takes only mount source).
@@ -2182,7 +2229,7 @@
// End of fstab/mtab is reached.
// Were we looking for something specific?
if (argv[0]) { // yes
- long l;
+ unsigned long l;
// If we didn't find anything, complain
if (!mtcur->mnt_fsname)
diff --git a/util-linux/rdate.c b/util-linux/rdate.c
index 1f36d8f..6e35cd5 100644
--- a/util-linux/rdate.c
+++ b/util-linux/rdate.c
@@ -1,7 +1,7 @@
/* vi: set sw=4 ts=4: */
/*
* The Rdate command will ask a time server for the RFC 868 time
- * and optionally set the system time.
+ * and optionally set the system time.
*
* by Sterling Huxley <sterling@europa.com>
*
@@ -11,9 +11,9 @@
//usage:#define rdate_trivial_usage
//usage: "[-sp] HOST"
//usage:#define rdate_full_usage "\n\n"
-//usage: "Get and possibly set the system date and time from a remote HOST\n"
-//usage: "\n -s Set the system date and time (default)"
-//usage: "\n -p Print the date and time"
+//usage: "Get and possibly set the system date/time from a remote HOST\n"
+//usage: "\n -s Set the system date/time (default)"
+//usage: "\n -p Print the date/time"
#include "libbb.h"
@@ -35,15 +35,16 @@
fd = create_and_connect_stream_or_die(host, bb_lookup_port("time", "tcp", 37));
- if (safe_read(fd, (void *)&nett, 4) != 4) /* read time from server */
+ if (safe_read(fd, &nett, 4) != 4) /* read time from server */
bb_error_msg_and_die("%s did not send the complete time", host);
- close(fd);
+ if (ENABLE_FEATURE_CLEAN_UP)
+ close(fd);
- /* convert from network byte order to local byte order.
+ /* Convert from network byte order to local byte order.
* RFC 868 time is the number of seconds
* since 00:00 (midnight) 1 January 1900 GMT
* the RFC 868 time 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT
- * Subtract the RFC 868 time to get Linux epoch
+ * Subtract the RFC 868 time to get Linux epoch.
*/
return ntohl(nett) - RFC_868_BIAS;
@@ -53,14 +54,14 @@
int rdate_main(int argc UNUSED_PARAM, char **argv)
{
time_t remote_time;
- unsigned long flags;
+ unsigned flags;
opt_complementary = "-1";
flags = getopt32(argv, "sp");
remote_time = askremotedate(argv[optind]);
- if ((flags & 2) == 0) {
+ if (!(flags & 2)) { /* no -p (-s may be present) */
time_t current_time;
time(¤t_time);
@@ -71,7 +72,7 @@
bb_perror_msg_and_die("can't set time of day");
}
- if ((flags & 1) == 0)
+ if (flags != 1) /* not lone -s */
printf("%s", ctime(&remote_time));
return EXIT_SUCCESS;
diff --git a/util-linux/readprofile.c b/util-linux/readprofile.c
index 4ed8011..974fe89 100644
--- a/util-linux/readprofile.c
+++ b/util-linux/readprofile.c
@@ -163,7 +163,7 @@
while (fgets(mapline, S_LEN, map)) {
if (sscanf(mapline, "%llx %s %s", &fn_add, mode, fn_name) != 3)
bb_error_msg_and_die("%s(%i): wrong map line",
- mapFile, maplineno);
+ mapFile, maplineno);
if (!strcmp(fn_name, "_stext")) /* only elf works like this */ {
add0 = fn_add;
@@ -198,7 +198,7 @@
if (indx >= len / sizeof(*buf))
bb_error_msg_and_die("profile address out of range. "
- "Wrong map file?");
+ "Wrong map file?");
while (indx < (next_add-add0)/step) {
if (optBins && (buf[indx] || optAll)) {
@@ -220,10 +220,10 @@
) {
if (optVerbose)
printf("%016llx %-40s %6i %8.4f\n", fn_add,
- fn_name, this, this/(double)fn_len);
+ fn_name, this, this/(double)fn_len);
else
printf("%6i %-40s %8.4f\n",
- this, fn_name, this/(double)fn_len);
+ this, fn_name, this/(double)fn_len);
if (optSub) {
unsigned long long scan;
@@ -233,8 +233,8 @@
addr = (scan - 1)*step + add0;
printf("\t%#llx\t%s+%#llx\t%u\n",
- addr, fn_name, addr - fn_add,
- buf[scan]);
+ addr, fn_name, addr - fn_add,
+ buf[scan]);
}
}
}
@@ -251,10 +251,10 @@
/* trailer */
if (optVerbose)
printf("%016x %-40s %6i %8.4f\n",
- 0, "total", total, total/(double)(fn_add-add0));
+ 0, "total", total, total/(double)(fn_add-add0));
else
printf("%6i %-40s %8.4f\n",
- total, "total", total/(double)(fn_add-add0));
+ total, "total", total/(double)(fn_add-add0));
fclose(map);
free(buf);
diff --git a/util-linux/volume_id/Kbuild.src b/util-linux/volume_id/Kbuild.src
index 70da654..759fdaa 100644
--- a/util-linux/volume_id/Kbuild.src
+++ b/util-linux/volume_id/Kbuild.src
@@ -31,7 +31,9 @@
### lib-$(CONFIG_FEATURE_VOLUMEID_LVM) += lvm.o
### lib-$(CONFIG_FEATURE_VOLUMEID_MAC) += mac.o
### lib-$(CONFIG_FEATURE_VOLUMEID_MSDOS) += msdos.o
+lib-$(CONFIG_FEATURE_VOLUMEID_NILFS) += nilfs.o
lib-$(CONFIG_FEATURE_VOLUMEID_NTFS) += ntfs.o
+lib-$(CONFIG_FEATURE_VOLUMEID_EXFAT) += exfat.o
lib-$(CONFIG_FEATURE_VOLUMEID_REISERFS) += reiserfs.o
lib-$(CONFIG_FEATURE_VOLUMEID_UDF) += udf.o
### lib-$(CONFIG_FEATURE_VOLUMEID_UFS) += ufs.o
diff --git a/util-linux/volume_id/btrfs.c b/util-linux/volume_id/btrfs.c
index 777b809..ee71d2e 100644
--- a/util-linux/volume_id/btrfs.c
+++ b/util-linux/volume_id/btrfs.c
@@ -102,6 +102,7 @@
// N.B.: btrfs natively supports 256 (>VOLUME_ID_LABEL_SIZE) size labels
volume_id_set_label_string(id, sb->label, VOLUME_ID_LABEL_SIZE);
volume_id_set_uuid(id, sb->fsid, UUID_DCE);
+ IF_FEATURE_BLKID_TYPE(id->type = "btrfs";)
return 0;
}
diff --git a/util-linux/volume_id/exfat.c b/util-linux/volume_id/exfat.c
new file mode 100644
index 0000000..a38a891
--- /dev/null
+++ b/util-linux/volume_id/exfat.c
@@ -0,0 +1,130 @@
+/*
+ * volume_id - reads filesystem label and uuid
+ *
+ * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "volume_id_internal.h"
+
+#define EXFAT_SB_OFFSET 0
+#define EXFAT_DIR_ENTRY_SZ 32
+#define EXFAT_MAX_DIR_ENTRIES 100
+
+struct exfat_super_block {
+/* 0x00 */ uint8_t boot_jump[3];
+/* 0x03 */ uint8_t fs_name[8];
+/* 0x0B */ uint8_t must_be_zero[53];
+/* 0x40 */ uint64_t partition_offset;
+/* 0x48 */ uint64_t volume_length;
+/* 0x50 */ uint32_t fat_offset; // Sector address of 1st FAT
+/* 0x54 */ uint32_t fat_size; // In sectors
+/* 0x58 */ uint32_t cluster_heap_offset; // Sector address of Data Region
+/* 0x5C */ uint32_t cluster_count;
+/* 0x60 */ uint32_t root_dir; // Cluster address of Root Directory
+/* 0x64 */ uint8_t vol_serial_nr[4]; // Volume ID
+/* 0x68 */ uint16_t fs_revision; // VV.MM
+/* 0x6A */ uint16_t vol_flags;
+/* 0x6C */ uint8_t bytes_per_sector; // Power of 2: 9 => 512, 12 => 4096
+/* 0x6D */ uint8_t sectors_per_cluster; // Power of 2
+/* 0x6E */ uint8_t nr_of_fats; // 2 for TexFAT
+/* 0x6F */ // ...
+} PACKED;
+
+struct exfat_dir_entry {
+/* 0x00 */ uint8_t entry_type;
+ union {
+ struct volume_label {
+/* 0x01 */ uint8_t char_count; // Length of label
+/* 0x02 */ uint16_t vol_label[11]; // UTF16 string without null termination
+/* 0x18 */ uint8_t reserved[8];
+/* 0x20 */ } PACKED label;
+ struct volume_guid {
+/* 0x01 */ uint8_t sec_count;
+/* 0x02 */ uint16_t set_checksum;
+/* 0x04 */ uint16_t flags;
+/* 0x06 */ uint8_t vol_guid[16];
+/* 0x16 */ uint8_t reserved[10];
+/* 0x20 */ } PACKED guid;
+ } PACKED type;
+} PACKED;
+
+int FAST_FUNC volume_id_probe_exfat(struct volume_id *id /*,uint64_t off*/)
+{
+ struct exfat_super_block *sb;
+ struct exfat_dir_entry *de;
+ unsigned sector_sz;
+ unsigned cluster_sz;
+ uint64_t root_dir_off;
+ unsigned count;
+ unsigned need_lbl_guid;
+
+ // Primary super block
+ dbg("exFAT: probing at offset 0x%x", EXFAT_SB_OFFSET);
+ sb = volume_id_get_buffer(id, EXFAT_SB_OFFSET, sizeof(*sb));
+
+ if (!sb)
+ return -1;
+
+ if (memcmp(sb->fs_name, "EXFAT ", 8) != 0)
+ return -1;
+
+ sector_sz = 1 << sb->bytes_per_sector;
+ cluster_sz = sector_sz << sb->sectors_per_cluster;
+ // There are no clusters 0 and 1, so the first cluster is 2.
+ root_dir_off = (uint64_t)EXFAT_SB_OFFSET +
+ // Hmm... should we cast sector_sz/cluster_sz to uint64_t?
+ (le32_to_cpu(sb->cluster_heap_offset)) * sector_sz +
+ (le32_to_cpu(sb->root_dir) - 2) * cluster_sz;
+ dbg("exFAT: sector size 0x%x bytes", sector_sz);
+ dbg("exFAT: cluster size 0x%x bytes", cluster_sz);
+ dbg("exFAT: root dir is at 0x%llx", (long long)root_dir_off);
+
+ // Use DOS uuid as fallback, if no GUID set
+ volume_id_set_uuid(id, sb->vol_serial_nr, UUID_DOS);
+
+ // EXFAT_MAX_DIR_ENTRIES is used as a safety belt.
+ // The Root Directory may hold an unlimited number of entries,
+ // so we do not want to check all. Usually label and GUID
+ // are in the beginning, but there are no guarantees.
+ need_lbl_guid = (1 << 0) | (1 << 1);
+ for (count = 0; count < EXFAT_MAX_DIR_ENTRIES; count++) {
+ de = volume_id_get_buffer(id, root_dir_off + (count * EXFAT_DIR_ENTRY_SZ), EXFAT_DIR_ENTRY_SZ);
+ if (de == NULL)
+ break;
+ if (de->entry_type == 0x00) {
+ // End of Directory Marker
+ dbg("exFAT: End of root directory reached after %u entries", count);
+ break;
+ }
+ if (de->entry_type == 0x83) {
+ // Volume Label Directory Entry
+ volume_id_set_label_unicode16(id, (uint8_t *)de->type.label.vol_label,
+ LE, 2 * de->type.label.char_count);
+ need_lbl_guid &= ~(1 << 0);
+ }
+ if (de->entry_type == 0xA0) {
+ // Volume GUID Directory Entry
+ volume_id_set_uuid(id, de->type.guid.vol_guid, UUID_DCE);
+ need_lbl_guid &= ~(1 << 1);
+ }
+ if (!need_lbl_guid)
+ break;
+ }
+
+ IF_FEATURE_BLKID_TYPE(id->type = "exfat";)
+ return 0;
+}
diff --git a/util-linux/volume_id/get_devname.c b/util-linux/volume_id/get_devname.c
index 230102d..665cb9b 100644
--- a/util-linux/volume_id/get_devname.c
+++ b/util-linux/volume_id/get_devname.c
@@ -49,7 +49,11 @@
if (volume_id_probe_all(vid, /*0,*/ size) != 0)
goto ret;
- if (vid->label[0] != '\0' || vid->uuid[0] != '\0') {
+ if (vid->label[0] != '\0' || vid->uuid[0] != '\0'
+#if ENABLE_FEATURE_BLKID_TYPE
+ || vid->type != NULL
+#endif
+ ) {
*label = xstrndup(vid->label, sizeof(vid->label));
*uuid = xstrndup(vid->uuid, sizeof(vid->uuid));
#if ENABLE_FEATURE_BLKID_TYPE
diff --git a/util-linux/volume_id/hfs.c b/util-linux/volume_id/hfs.c
index f3f19db..3d9704d 100644
--- a/util-linux/volume_id/hfs.c
+++ b/util-linux/volume_id/hfs.c
@@ -131,6 +131,27 @@
#define HFS_NODE_LEAF 0xff
#define HFSPLUS_POR_CNID 1
+static void FAST_FUNC hfs_set_uuid(struct volume_id *id, const uint8_t *hfs_id)
+{
+#define hfs_id_len 8
+ md5_ctx_t md5c;
+ uint8_t uuid[16];
+ unsigned i;
+
+ for (i = 0; i < hfs_id_len; i++)
+ if (hfs_id[i] != 0)
+ goto do_md5;
+ return;
+ do_md5:
+ md5_begin(&md5c);
+ md5_hash(&md5c, "\263\342\17\71\362\222\21\326\227\244\0\60\145\103\354\254", 16);
+ md5_hash(&md5c, hfs_id, hfs_id_len);
+ md5_end(&md5c, uuid);
+ uuid[6] = 0x30 | (uuid[6] & 0x0f);
+ uuid[8] = 0x80 | (uuid[8] & 0x3f);
+ volume_id_set_uuid(id, uuid, UUID_DCE);
+}
+
int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/)
{
uint64_t off = 0;
@@ -193,7 +214,7 @@
volume_id_set_label_string(id, hfs->label, hfs->label_len) ;
}
- volume_id_set_uuid(id, hfs->finder_info.id, UUID_HFS);
+ hfs_set_uuid(id, hfs->finder_info.id);
// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
IF_FEATURE_BLKID_TYPE(id->type = "hfs";)
@@ -207,7 +228,7 @@
return -1;
hfsplus:
- volume_id_set_uuid(id, hfsplus->finder_info.id, UUID_HFS);
+ hfs_set_uuid(id, hfsplus->finder_info.id);
blocksize = be32_to_cpu(hfsplus->blocksize);
dbg("blocksize %u", blocksize);
@@ -286,7 +307,7 @@
found:
// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM);
-// id->type = "hfsplus";
+ IF_FEATURE_BLKID_TYPE(id->type = "hfsplus";)
return 0;
}
diff --git a/util-linux/volume_id/linux_raid.c b/util-linux/volume_id/linux_raid.c
index 761e54f..209eaab 100644
--- a/util-linux/volume_id/linux_raid.c
+++ b/util-linux/volume_id/linux_raid.c
@@ -69,9 +69,9 @@
volume_id_set_uuid(id, uuid, UUID_DCE);
// snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u",
-// le32_to_cpu(mdp->major_version),
-// le32_to_cpu(mdp->minor_version),
-// le32_to_cpu(mdp->patch_version));
+// le32_to_cpu(mdp->major_version),
+// le32_to_cpu(mdp->minor_version),
+// le32_to_cpu(mdp->patch_version));
dbg("found raid signature");
// volume_id_set_usage(id, VOLUME_ID_RAID);
diff --git a/util-linux/volume_id/nilfs.c b/util-linux/volume_id/nilfs.c
new file mode 100644
index 0000000..b88a9e4
--- /dev/null
+++ b/util-linux/volume_id/nilfs.c
@@ -0,0 +1,96 @@
+/*
+ * volume_id - reads filesystem label and uuid
+ *
+ * Copyright (C) 2004 Kay Sievers <kay.sievers@vrfy.org>
+ * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "volume_id_internal.h"
+
+#define NILFS_UUID_SIZE 16
+#define NILFS_LABEL_SIZE 80
+#define NILFS_SB1_OFFSET 0x400
+#define NILFS_SB2_OFFSET 0x1000
+#define NILFS_MAGIC 0x3434
+
+struct nilfs2_super_block {
+/* 0x00 */ uint32_t s_rev_level; // Major revision level.
+/* 0x04 */ uint16_t s_minor_rev_level; // Minor revision level.
+/* 0x06 */ uint16_t s_magic; // Magic signature.
+/* 0x08 */ uint16_t s_bytes;
+/* 0x0A */ uint16_t s_flags;
+/* 0x0C */ uint32_t s_crc_seed;
+/* 0x10 */ uint32_t s_sum;
+/* 0x14 */ uint32_t s_log_block_size;
+/* 0x18 */ uint64_t s_nsegments;
+/* 0x20 */ uint64_t s_dev_size; // Block device size in bytes.
+/* 0x28 */ uint64_t s_first_data_block;
+/* 0x30 */ uint32_t s_blocks_per_segment;
+/* 0x34 */ uint32_t s_r_segments_percentage;
+/* 0x38 */ uint64_t s_last_cno;
+/* 0x40 */ uint64_t s_last_pseg;
+/* 0x48 */ uint64_t s_last_seq;
+/* 0x50 */ uint64_t s_free_blocks_count;
+/* 0x58 */ uint64_t s_ctime;
+/* 0x60 */ uint64_t s_mtime;
+/* 0x68 */ uint64_t s_wtime;
+/* 0x70 */ uint16_t s_mnt_count;
+/* 0x72 */ uint16_t s_max_mnt_count;
+/* 0x74 */ uint16_t s_state;
+/* 0x76 */ uint16_t s_errors;
+/* 0x78 */ uint64_t s_lastcheck;
+/* 0x80 */ uint32_t s_checkinterval;
+/* 0x84 */ uint32_t s_creator_os;
+/* 0x88 */ uint16_t s_def_resuid;
+/* 0x8A */ uint16_t s_def_resgid;
+/* 0x8C */ uint32_t s_first_ino;
+/* 0x90 */ uint16_t s_inode_size;
+/* 0x92 */ uint16_t s_dat_entry_size;
+/* 0x94 */ uint16_t s_checkpoint_size;
+/* 0x96 */ uint16_t s_segment_usage_size;
+/* 0x98 */ uint8_t s_uuid[NILFS_UUID_SIZE]; // 128-bit UUID for volume.
+/* 0xA8 */ uint8_t s_volume_name[NILFS_LABEL_SIZE]; // Volume label.
+/* 0xF8 */ // ...
+} PACKED;
+
+int FAST_FUNC volume_id_probe_nilfs(struct volume_id *id /*,uint64_t off*/)
+{
+ struct nilfs2_super_block *sb;
+
+ // Primary super block
+ dbg("nilfs: probing at offset 0x%x", NILFS_SB1_OFFSET);
+
+ sb = volume_id_get_buffer(id, NILFS_SB1_OFFSET, sizeof(*sb));
+
+ if (sb == NULL)
+ return -1;
+
+ if (sb->s_magic != NILFS_MAGIC)
+ return -1;
+
+ // The secondary superblock is not always used, so ignore it for now.
+ // When used it is at 4K from the end of the partition (sb->s_dev_size - NILFS_SB2_OFFSET).
+
+ volume_id_set_label_string(id, sb->s_volume_name, NILFS_LABEL_SIZE < VOLUME_ID_LABEL_SIZE ?
+ NILFS_LABEL_SIZE : VOLUME_ID_LABEL_SIZE);
+ volume_id_set_uuid(id, sb->s_uuid, UUID_DCE);
+
+ if (sb->s_rev_level == 2)
+ IF_FEATURE_BLKID_TYPE(id->type = "nilfs2");
+
+ return 0;
+}
diff --git a/util-linux/volume_id/ntfs.c b/util-linux/volume_id/ntfs.c
index 547f141..7b2612f 100644
--- a/util-linux/volume_id/ntfs.c
+++ b/util-linux/volume_id/ntfs.c
@@ -132,7 +132,7 @@
dbg("mft record size %i", mft_record_size);
buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size),
- mft_record_size);
+ mft_record_size);
if (buf == NULL)
goto found;
@@ -165,7 +165,7 @@
break;
dbg("found attribute type 0x%x, len %i, at offset %i",
- attr_type, attr_len, attr_off);
+ attr_type, attr_len, attr_off);
// if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) {
// struct volume_info *info;
diff --git a/util-linux/volume_id/squashfs.c b/util-linux/volume_id/squashfs.c
new file mode 100644
index 0000000..c5b4f9c
--- /dev/null
+++ b/util-linux/volume_id/squashfs.c
@@ -0,0 +1,49 @@
+/*
+ * volume_id - reads filesystem label and uuid
+ *
+ * Copyright (C) 2012 S-G Bergh <sgb@systemasis.org>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+
+//kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SQUASHFS) += squashfs.o
+
+#include "volume_id_internal.h"
+
+struct squashfs_superblock {
+ uint32_t magic;
+/*
+ uint32_t dummy[6];
+ uint16_t major;
+ uint16_t minor;
+*/
+} PACKED;
+
+int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/)
+{
+#define off ((uint64_t)0)
+ struct squashfs_superblock *sb;
+
+ dbg("SquashFS: probing at offset 0x%llx", (unsigned long long) off);
+ sb = volume_id_get_buffer(id, off, 0x200);
+ if (!sb)
+ return -1;
+
+ // Old SquashFS (pre 4.0) can be both big and little endian, so test for both.
+ // Likewise, it is commonly used in firwmare with some non-standard signatures.
+#define pack(a,b,c,d) ( (uint32_t)((a * 256 + b) * 256 + c) * 256 + d )
+#define SIG1 pack('s','q','s','h')
+#define SIG2 pack('h','s','q','s')
+#define SIG3 pack('s','h','s','q')
+#define SIG4 pack('q','s','h','s')
+ if (sb->magic == SIG1
+ || sb->magic == SIG2
+ || sb->magic == SIG3
+ || sb->magic == SIG4
+ ) {
+ IF_FEATURE_BLKID_TYPE(id->type = "squashfs";)
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/util-linux/volume_id/udf.c b/util-linux/volume_id/udf.c
index cd63c8d..d3747fb 100644
--- a/util-linux/volume_id/udf.c
+++ b/util-linux/volume_id/udf.c
@@ -109,7 +109,7 @@
return -1;
dbg("vsd: %c%c%c%c%c",
- vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]);
+ vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]);
if (vsd->id[0] == '\0')
return -1;
diff --git a/util-linux/volume_id/unused_msdos.c b/util-linux/volume_id/unused_msdos.c
index 65fb885..2e8cb19 100644
--- a/util-linux/volume_id/unused_msdos.c
+++ b/util-linux/volume_id/unused_msdos.c
@@ -109,7 +109,7 @@
extended = off + poff;
} else {
dbg("found 0x%x data partition at 0x%llx, len 0x%llx",
- part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
+ part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen);
// if (is_raid(part[i].sys_ind))
// volume_id_set_usage_part(p, VOLUME_ID_RAID);
diff --git a/util-linux/volume_id/unused_silicon_raid.c b/util-linux/volume_id/unused_silicon_raid.c
index d1c439e..878b881 100644
--- a/util-linux/volume_id/unused_silicon_raid.c
+++ b/util-linux/volume_id/unused_silicon_raid.c
@@ -62,7 +62,7 @@
// volume_id_set_usage(id, VOLUME_ID_RAID);
// snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u",
-// le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver));
+// le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver));
// id->type = "silicon_medley_raid_member";
return 0;
diff --git a/util-linux/volume_id/util.c b/util-linux/volume_id/util.c
index 11e2c00..9da5076 100644
--- a/util-linux/volume_id/util.c
+++ b/util-linux/volume_id/util.c
@@ -31,25 +31,29 @@
c = (buf[i+1] << 8) | buf[i];
else
c = (buf[i] << 8) | buf[i+1];
- if (c == 0) {
- str[j] = '\0';
+ if (c == 0)
break;
- } else if (c < 0x80) {
- if (j+1 >= len)
- break;
- str[j++] = (uint8_t) c;
- } else if (c < 0x800) {
+ if (j+1 >= len)
+ break;
+ if (c < 0x80) {
+ /* 0xxxxxxx */
+ } else {
+ uint8_t topbits = 0xc0;
if (j+2 >= len)
break;
- str[j++] = (uint8_t) (0xc0 | (c >> 6));
- str[j++] = (uint8_t) (0x80 | (c & 0x3f));
- } else {
- if (j+3 >= len)
- break;
- str[j++] = (uint8_t) (0xe0 | (c >> 12));
- str[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f));
- str[j++] = (uint8_t) (0x80 | (c & 0x3f));
+ if (c < 0x800) {
+ /* 110yyyxx 10xxxxxx */
+ } else {
+ if (j+3 >= len)
+ break;
+ /* 1110yyyy 10yyyyxx 10xxxxxx */
+ str[j++] = (uint8_t) (0xe0 | (c >> 12));
+ topbits = 0x80;
+ }
+ str[j++] = (uint8_t) (topbits | ((c >> 6) & 0x3f));
+ c = 0x80 | (c & 0x3f);
}
+ str[j++] = (uint8_t) c;
}
str[j] = '\0';
}
@@ -125,30 +129,14 @@
void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count)
{
- volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count);
+ volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count);
}
void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, enum uuid_format format)
{
unsigned i;
- unsigned count = 0;
+ unsigned count = (format == UUID_DCE_STRING ? VOLUME_ID_UUID_SIZE : 4 << format);
- switch (format) {
- case UUID_DOS:
- count = 4;
- break;
- case UUID_NTFS:
- case UUID_HFS:
- count = 8;
- break;
- case UUID_DCE:
- count = 16;
- break;
- case UUID_DCE_STRING:
- /* 36 is ok, id->uuid has one extra byte for NUL */
- count = VOLUME_ID_UUID_SIZE;
- break;
- }
// memcpy(id->uuid_raw, buf, count);
// id->uuid_raw_len = count;
@@ -169,11 +157,6 @@
buf[7], buf[6], buf[5], buf[4],
buf[3], buf[2], buf[1], buf[0]);
break;
- case UUID_HFS:
- sprintf(id->uuid, "%02X%02X%02X%02X%02X%02X%02X%02X",
- buf[0], buf[1], buf[2], buf[3],
- buf[4], buf[5], buf[6], buf[7]);
- break;
case UUID_DCE:
sprintf(id->uuid,
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c
index 06d91eb..e928af5 100644
--- a/util-linux/volume_id/volume_id.c
+++ b/util-linux/volume_id/volume_id.c
@@ -93,9 +93,15 @@
#if ENABLE_FEATURE_VOLUMEID_FAT
volume_id_probe_vfat,
#endif
+#if ENABLE_FEATURE_VOLUMEID_EXFAT
+ volume_id_probe_exfat,
+#endif
#if ENABLE_FEATURE_VOLUMEID_MAC
volume_id_probe_mac_partition_map,
#endif
+#if ENABLE_FEATURE_VOLUMEID_SQUASHFS
+ volume_id_probe_squashfs,
+#endif
#if ENABLE_FEATURE_VOLUMEID_XFS
volume_id_probe_xfs,
#endif
@@ -130,6 +136,9 @@
#if ENABLE_FEATURE_VOLUMEID_UFS
volume_id_probe_ufs,
#endif
+#if ENABLE_FEATURE_VOLUMEID_NILFS
+ volume_id_probe_nilfs,
+#endif
#if ENABLE_FEATURE_VOLUMEID_NTFS
volume_id_probe_ntfs,
#endif
diff --git a/util-linux/volume_id/volume_id_internal.h b/util-linux/volume_id/volume_id_internal.h
index 1c64046..3f02bd5 100644
--- a/util-linux/volume_id/volume_id_internal.h
+++ b/util-linux/volume_id/volume_id_internal.h
@@ -136,12 +136,15 @@
#define cpu_to_be32(x) (x)
#endif
+/* volume_id_set_uuid(id,buf,fmt) assumes size of uuid buf
+ * by shifting: 4 << fmt, except for fmt == UUID_DCE_STRING.
+ * The constants below should match sizes.
+ */
enum uuid_format {
- UUID_DCE_STRING,
- UUID_DCE,
- UUID_DOS,
- UUID_NTFS,
- UUID_HFS,
+ UUID_DOS = 0, /* 4 bytes */
+ UUID_NTFS = 1, /* 8 bytes */
+ UUID_DCE = 2, /* 16 bytes */
+ UUID_DCE_STRING = 3, /* 36 bytes (VOLUME_ID_UUID_SIZE) */
};
enum endian {
@@ -212,14 +215,20 @@
//int FAST_FUNC volume_id_probe_msdos_part_table(struct volume_id *id /*,uint64_t off*/);
+int FAST_FUNC volume_id_probe_nilfs(struct volume_id *id /*,uint64_t off*/);
+
int FAST_FUNC volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/);
+int FAST_FUNC volume_id_probe_exfat(struct volume_id *id /*,uint64_t off*/);
+
int FAST_FUNC volume_id_probe_ocfs2(struct volume_id *id /*,uint64_t off*/);
int FAST_FUNC volume_id_probe_reiserfs(struct volume_id *id /*,uint64_t off*/);
int FAST_FUNC volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/);
+int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/);
+
int FAST_FUNC volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/);
int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/);