aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--coreutils/stat.c2
-rw-r--r--examples/inittab8
-rwxr-xr-xexamples/mdev.conf.change_blockdev.sh29
-rw-r--r--examples/mdev_fat.conf30
-rw-r--r--include/applets.src.h2
-rw-r--r--include/libbb.h3
-rw-r--r--init/init.c9
-rw-r--r--libbb/dump.c2
-rw-r--r--libbb/lineedit.c124
-rw-r--r--libbb/login.c3
-rw-r--r--libbb/time.c21
-rw-r--r--miscutils/setserial.c4
-rw-r--r--networking/httpd.c7
-rw-r--r--networking/ntpd.c4
-rw-r--r--networking/ntpd_simple.c2
-rw-r--r--procps/watch.c12
-rw-r--r--util-linux/hexdump.c7
-rw-r--r--util-linux/mdev.c6
18 files changed, 201 insertions, 74 deletions
diff --git a/coreutils/stat.c b/coreutils/stat.c
index 69a8a1a36..0d13fdf65 100644
--- a/coreutils/stat.c
+++ b/coreutils/stat.c
@@ -131,7 +131,7 @@ static const char *human_time(time_t t)
131 /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/ 131 /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/
132#define buf bb_common_bufsiz1 132#define buf bb_common_bufsiz1
133 133
134 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S.000000000", localtime(&t)); 134 strcpy(strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &t), ".000000000");
135 return buf; 135 return buf;
136#undef buf 136#undef buf
137} 137}
diff --git a/examples/inittab b/examples/inittab
index c4e0af514..01ceaef25 100644
--- a/examples/inittab
+++ b/examples/inittab
@@ -15,10 +15,7 @@
15# the specified process to run on. The contents of this field are 15# the specified process to run on. The contents of this field are
16# appended to "/dev/" and used as-is. There is no need for this field to 16# appended to "/dev/" and used as-is. There is no need for this field to
17# be unique, although if it isn't you may have strange results. If this 17# be unique, although if it isn't you may have strange results. If this
18# field is left blank, it is completely ignored. Also note that if 18# field is left blank, then the init's stdin/out will be used.
19# BusyBox detects that a serial console is in use, then all entries
20# containing non-empty id fields will be ignored. BusyBox init does
21# nothing with utmp. We don't need no stinkin' utmp.
22# 19#
23# <runlevels>: The runlevels field is completely ignored. 20# <runlevels>: The runlevels field is completely ignored.
24# 21#
@@ -43,9 +40,6 @@
43# ::shutdown:/sbin/swapoff -a 40# ::shutdown:/sbin/swapoff -a
44# ::shutdown:/bin/umount -a -r 41# ::shutdown:/bin/umount -a -r
45# ::restart:/sbin/init 42# ::restart:/sbin/init
46#
47# if it detects that /dev/console is _not_ a serial console, it will
48# also run:
49# tty2::askfirst:/bin/sh 43# tty2::askfirst:/bin/sh
50# tty3::askfirst:/bin/sh 44# tty3::askfirst:/bin/sh
51# tty4::askfirst:/bin/sh 45# tty4::askfirst:/bin/sh
diff --git a/examples/mdev.conf.change_blockdev.sh b/examples/mdev.conf.change_blockdev.sh
new file mode 100755
index 000000000..512e43fcc
--- /dev/null
+++ b/examples/mdev.conf.change_blockdev.sh
@@ -0,0 +1,29 @@
1#!/bin/sh
2
3# Seconds to try to reread partition table
4cnt=60
5
6exec </dev/null
7exec >"/tmp/${0##*/}.$$.out"
8exec 2>&1
9
10(
11echo "Running: $0"
12echo "Env:"
13env | sort
14
15while sleep 1; test $cnt != 0; do
16 echo "Trying to reread partition table on $DEVNAME ($cnt)"
17 : $((cnt--))
18 # If device node doesn't exist, it means the device was removed.
19 # Stop trying.
20 test -e "$DEVNAME" || { echo "$DEVNAME doesn't exist, aborting"; exit 1; }
21 #echo "$DEVNAME exists"
22 if blockdev --rereadpt "$DEVNAME"; then
23 echo "blockdev --rereadpt succeeded"
24 exit 0
25 fi
26 echo "blockdev --rereadpt failed, exit code: $?"
27done
28echo "Timed out"
29) &
diff --git a/examples/mdev_fat.conf b/examples/mdev_fat.conf
index bceddb2d7..f2a15f35d 100644
--- a/examples/mdev_fat.conf
+++ b/examples/mdev_fat.conf
@@ -112,3 +112,33 @@ usbdev[0-9].[0-9]_.* root:root 660
112# zaptel devices 112# zaptel devices
113zap(.*) root:dialout 660 =zap/%1 113zap(.*) root:dialout 660 =zap/%1
114dahdi!(.*) root:dialout 660 =dahdi/%1 114dahdi!(.*) root:dialout 660 =dahdi/%1
115
116# HTC Android
117# Attaching it via USB cable causes a flurry of activity:
118#
119# mdev[1271]: 48.639459 ACTION:add SUBSYSTEM:usb DEVNAME:bus/usb/001/009 DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5
120# mdev[1271]: mknod bus/usb/001/009 (189,8) 20660 0:0
121# mdev[1272]: 48.642354 ACTION:add SUBSYSTEM:usb DEVNAME:(null) DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0
122# mdev[1272]: running: modprobe "$MODALIAS"
123# mdev[1273]: 48.650078 ACTION:add SUBSYSTEM:scsi DEVNAME:(null) DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host11
124# mdev[1274]: 48.651297 ACTION:add SUBSYSTEM:scsi_host DEVNAME:(null) DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host11/scsi_host/host11
125# mdev[1275]: 49.649422 ACTION:add SUBSYSTEM:scsi DEVNAME:(null) DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host11/target11:0:0
126# mdev[1276]: 49.650703 ACTION:add SUBSYSTEM:scsi DEVNAME:(null) DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host11/target11:0:0/11:0:0:0
127# mdev[1276]: running: modprobe "$MODALIAS"
128# modprobe: module scsi:t-0x00 not found in modules.dep
129# mdev[1277]: 49.658002 ACTION:add SUBSYSTEM:scsi_disk DEVNAME:(null) DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host11/target11:0:0/11:0:0:0/scsi_disk/11:0:0:0
130# mdev[1278]: 49.659244 ACTION:add SUBSYSTEM:scsi_device DEVNAME:(null) DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host11/target11:0:0/11:0:0:0/scsi_device/11:0:0:
131# mdev[1279]: 49.660535 ACTION:add SUBSYSTEM:bsg DEVNAME:bsg/11:0:0:0 DEVPATH:/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host11/target11:0:0/11:0:0:0/bsg/11:0:0:0
132# mdev[1279]: mknod bsg/11:0:0:0 (253,1) 20660 0:0
133# mdev[1280]: 49.663516 ACTION:add SUBSYSTEM:bdi DEVNAME:(null) DEVPATH:/devices/virtual/bdi/8:16
134# mdev[1281]: 49.664748 ACTION:add SUBSYSTEM:block DEVNAME:sdb DEVPATH:/block/sdb
135# mdev[1281]: mknod sdb (8,16) 60660 0:0
136# mdev[1282]: 49.677597 ACTION:change SUBSYSTEM:block DEVNAME:sdb DEVPATH:/block/sdb
137# mdev[1283]: 50.692936 ACTION:change SUBSYSTEM:block DEVNAME:sdb DEVPATH:/block/sdb
138#
139# We are hooking to the last events. To avoid having two scripts running,
140# we check for DISK_MEDIA_CHANGE=1 (prev to last event has it,
141# and it's the _only_ difference in env for these two events as of kernel 3.7.7)
142# Unfortunately, there is no event for "user pressed [Turn USB storage] btn"!
143# Script merely backgrounds and tries to rescan partition table for 1 minute:
144ACTION=change;SUBSYSTEM=block;DISK_MEDIA_CHANGE=1;.* 0:0 660 */etc/mdev.conf.change_blockdev.sh
diff --git a/include/applets.src.h b/include/applets.src.h
index 29ab16706..00172b1bc 100644
--- a/include/applets.src.h
+++ b/include/applets.src.h
@@ -236,7 +236,7 @@ IF_LZOP(APPLET(lzop, BB_DIR_BIN, BB_SUID_DROP))
236IF_LZOP(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat)) 236IF_LZOP(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat))
237IF_MAKEDEVS(APPLET(makedevs, BB_DIR_SBIN, BB_SUID_DROP)) 237IF_MAKEDEVS(APPLET(makedevs, BB_DIR_SBIN, BB_SUID_DROP))
238IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP)) 238IF_MAKEMIME(APPLET(makemime, BB_DIR_BIN, BB_SUID_DROP))
239IF_MAN(APPLET(man, BB_DIR_SBIN, BB_SUID_DROP)) 239IF_MAN(APPLET(man, BB_DIR_USR_BIN, BB_SUID_DROP))
240IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP)) 240IF_MATCHPATHCON(APPLET(matchpathcon, BB_DIR_USR_SBIN, BB_SUID_DROP))
241IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum)) 241IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum))
242IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP)) 242IF_MICROCOM(APPLET(microcom, BB_DIR_USR_BIN, BB_SUID_DROP))
diff --git a/include/libbb.h b/include/libbb.h
index 15a5a6623..f5b7d8dc7 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -536,7 +536,8 @@ struct BUG_too_small {
536 536
537void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC; 537void parse_datestr(const char *date_str, struct tm *ptm) FAST_FUNC;
538time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC; 538time_t validate_tm_time(const char *date_str, struct tm *ptm) FAST_FUNC;
539 539char *strftime_HHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
540char *strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp) FAST_FUNC;
540 541
541int xsocket(int domain, int type, int protocol) FAST_FUNC; 542int xsocket(int domain, int type, int protocol) FAST_FUNC;
542void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC; 543void xbind(int sockfd, struct sockaddr *my_addr, socklen_t addrlen) FAST_FUNC;
diff --git a/init/init.c b/init/init.c
index b84bdccbc..15aad474f 100644
--- a/init/init.c
+++ b/init/init.c
@@ -1234,9 +1234,6 @@ int init_main(int argc UNUSED_PARAM, char **argv)
1234//usage: " ::shutdown:/sbin/swapoff -a\n" 1234//usage: " ::shutdown:/sbin/swapoff -a\n"
1235//usage: " ::shutdown:/bin/umount -a -r\n" 1235//usage: " ::shutdown:/bin/umount -a -r\n"
1236//usage: " ::restart:/sbin/init\n" 1236//usage: " ::restart:/sbin/init\n"
1237//usage: "\n"
1238//usage: "if it detects that /dev/console is _not_ a serial console, it will also run:\n"
1239//usage: "\n"
1240//usage: " tty2::askfirst:/bin/sh\n" 1237//usage: " tty2::askfirst:/bin/sh\n"
1241//usage: " tty3::askfirst:/bin/sh\n" 1238//usage: " tty3::askfirst:/bin/sh\n"
1242//usage: " tty4::askfirst:/bin/sh\n" 1239//usage: " tty4::askfirst:/bin/sh\n"
@@ -1252,11 +1249,7 @@ int init_main(int argc UNUSED_PARAM, char **argv)
1252//usage: " the specified process to run on. The contents of this field are\n" 1249//usage: " the specified process to run on. The contents of this field are\n"
1253//usage: " appended to \"/dev/\" and used as-is. There is no need for this field to\n" 1250//usage: " appended to \"/dev/\" and used as-is. There is no need for this field to\n"
1254//usage: " be unique, although if it isn't you may have strange results. If this\n" 1251//usage: " be unique, although if it isn't you may have strange results. If this\n"
1255//usage: " field is left blank, the controlling tty is set to the console. Also\n" 1252//usage: " field is left blank, then the init's stdin/out will be used.\n"
1256//usage: " note that if BusyBox detects that a serial console is in use, then only\n"
1257//usage: " entries whose controlling tty is either the serial console or /dev/null\n"
1258//usage: " will be run. BusyBox init does nothing with utmp. We don't need no\n"
1259//usage: " stinkin' utmp.\n"
1260//usage: "\n" 1253//usage: "\n"
1261//usage: " <runlevels>:\n" 1254//usage: " <runlevels>:\n"
1262//usage: "\n" 1255//usage: "\n"
diff --git a/libbb/dump.c b/libbb/dump.c
index 7e435643b..566881a78 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -333,7 +333,7 @@ static void do_skip(priv_dumper_t *dumper, const char *fname, int statok)
333 return; 333 return;
334 } 334 }
335 } 335 }
336 if (fseek(stdin, dumper->pub.dump_skip, SEEK_SET)) { 336 if (fseeko(stdin, dumper->pub.dump_skip, SEEK_SET)) {
337 bb_simple_perror_msg_and_die(fname); 337 bb_simple_perror_msg_and_die(fname);
338 } 338 }
339 dumper->address += dumper->pub.dump_skip; 339 dumper->address += dumper->pub.dump_skip;
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 09e203159..7f64a9691 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -133,9 +133,6 @@ struct lineedit_statics {
133 CHAR_T *command_ps; 133 CHAR_T *command_ps;
134 134
135 const char *cmdedit_prompt; 135 const char *cmdedit_prompt;
136#if ENABLE_FEATURE_EDITING_FANCY_PROMPT
137 int num_ok_lines; /* = 1; */
138#endif
139 136
140#if ENABLE_USERNAME_OR_HOMEDIR 137#if ENABLE_USERNAME_OR_HOMEDIR
141 char *user_buf; 138 char *user_buf;
@@ -172,7 +169,6 @@ extern struct lineedit_statics *const lineedit_ptr_to_statics;
172#define command_len (S.command_len ) 169#define command_len (S.command_len )
173#define command_ps (S.command_ps ) 170#define command_ps (S.command_ps )
174#define cmdedit_prompt (S.cmdedit_prompt ) 171#define cmdedit_prompt (S.cmdedit_prompt )
175#define num_ok_lines (S.num_ok_lines )
176#define user_buf (S.user_buf ) 172#define user_buf (S.user_buf )
177#define home_pwd_buf (S.home_pwd_buf ) 173#define home_pwd_buf (S.home_pwd_buf )
178#define matches (S.matches ) 174#define matches (S.matches )
@@ -185,7 +181,6 @@ extern struct lineedit_statics *const lineedit_ptr_to_statics;
185 (*(struct lineedit_statics**)&lineedit_ptr_to_statics) = xzalloc(sizeof(S)); \ 181 (*(struct lineedit_statics**)&lineedit_ptr_to_statics) = xzalloc(sizeof(S)); \
186 barrier(); \ 182 barrier(); \
187 cmdedit_termw = 80; \ 183 cmdedit_termw = 80; \
188 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines = 1;) \
189 IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \ 184 IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \
190 IF_FEATURE_EDITING_VI(delptr = delbuf;) \ 185 IF_FEATURE_EDITING_VI(delptr = delbuf;) \
191} while (0) 186} while (0)
@@ -1546,7 +1541,6 @@ static void remember_in_history(char *str)
1546# if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT 1541# if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
1547 save_history(str); 1542 save_history(str);
1548# endif 1543# endif
1549 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)
1550} 1544}
1551 1545
1552#else /* MAX_HISTORY == 0 */ 1546#else /* MAX_HISTORY == 0 */
@@ -1782,17 +1776,16 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1782 size_t cur_prmt_len = 0; 1776 size_t cur_prmt_len = 0;
1783 char flg_not_length = '['; 1777 char flg_not_length = '[';
1784 char *prmt_mem_ptr = xzalloc(1); 1778 char *prmt_mem_ptr = xzalloc(1);
1785 char *cwd_buf = xrealloc_getcwd_or_warn(NULL); 1779# if ENABLE_USERNAME_OR_HOMEDIR
1780 char *cwd_buf = NULL;
1781# endif
1782 char timebuf[sizeof("HH:MM:SS")];
1786 char cbuf[2]; 1783 char cbuf[2];
1787 char c; 1784 char c;
1788 char *pbuf; 1785 char *pbuf;
1789 1786
1790 cmdedit_prmt_len = 0; 1787 cmdedit_prmt_len = 0;
1791 1788
1792 if (!cwd_buf) {
1793 cwd_buf = (char *)bb_msg_unknown;
1794 }
1795
1796 cbuf[1] = '\0'; /* never changes */ 1789 cbuf[1] = '\0'; /* never changes */
1797 1790
1798 while (*prmt_ptr) { 1791 while (*prmt_ptr) {
@@ -1801,10 +1794,50 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1801 pbuf = cbuf; 1794 pbuf = cbuf;
1802 c = *prmt_ptr++; 1795 c = *prmt_ptr++;
1803 if (c == '\\') { 1796 if (c == '\\') {
1804 const char *cp = prmt_ptr; 1797 const char *cp;
1805 int l; 1798 int l;
1806 1799/*
1807 c = bb_process_escape_sequence(&prmt_ptr); 1800 * Supported via bb_process_escape_sequence:
1801 * \a ASCII bell character (07)
1802 * \e ASCII escape character (033)
1803 * \n newline
1804 * \r carriage return
1805 * \\ backslash
1806 * \nnn char with octal code nnn
1807 * Supported:
1808 * \$ if the effective UID is 0, a #, otherwise a $
1809 * \w current working directory, with $HOME abbreviated with a tilde
1810 * Note: we do not support $PROMPT_DIRTRIM=n feature
1811 * \W basename of the current working directory, with $HOME abbreviated with a tilde
1812 * \h hostname up to the first '.'
1813 * \H hostname
1814 * \u username
1815 * \[ begin a sequence of non-printing characters
1816 * \] end a sequence of non-printing characters
1817 * \T current time in 12-hour HH:MM:SS format
1818 * \@ current time in 12-hour am/pm format
1819 * \A current time in 24-hour HH:MM format
1820 * \t current time in 24-hour HH:MM:SS format
1821 * (all of the above work as \A)
1822 * Not supported:
1823 * \! history number of this command
1824 * \# command number of this command
1825 * \j number of jobs currently managed by the shell
1826 * \l basename of the shell's terminal device name
1827 * \s name of the shell, the basename of $0 (the portion following the final slash)
1828 * \V release of bash, version + patch level (e.g., 2.00.0)
1829 * \d date in "Weekday Month Date" format (e.g., "Tue May 26")
1830 * \D{format}
1831 * format is passed to strftime(3).
1832 * An empty format results in a locale-specific time representation.
1833 * The braces are required.
1834 * Mishandled by bb_process_escape_sequence:
1835 * \v version of bash (e.g., 2.00)
1836 */
1837 cp = prmt_ptr;
1838 c = *cp;
1839 if (c != 't') /* don't treat \t as tab */
1840 c = bb_process_escape_sequence(&prmt_ptr);
1808 if (prmt_ptr == cp) { 1841 if (prmt_ptr == cp) {
1809 if (*cp == '\0') 1842 if (*cp == '\0')
1810 break; 1843 break;
@@ -1816,43 +1849,58 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1816 pbuf = user_buf ? user_buf : (char*)""; 1849 pbuf = user_buf ? user_buf : (char*)"";
1817 break; 1850 break;
1818# endif 1851# endif
1852 case 'H':
1819 case 'h': 1853 case 'h':
1820 pbuf = free_me = safe_gethostname(); 1854 pbuf = free_me = safe_gethostname();
1821 *strchrnul(pbuf, '.') = '\0'; 1855 if (c == 'h')
1856 strchrnul(pbuf, '.')[0] = '\0';
1822 break; 1857 break;
1823 case '$': 1858 case '$':
1824 c = (geteuid() == 0 ? '#' : '$'); 1859 c = (geteuid() == 0 ? '#' : '$');
1825 break; 1860 break;
1861 case 'T': /* 12-hour HH:MM:SS format */
1862 case '@': /* 12-hour am/pm format */
1863 case 'A': /* 24-hour HH:MM format */
1864 case 't': /* 24-hour HH:MM:SS format */
1865 /* We show all of them as 24-hour HH:MM */
1866 strftime_HHMMSS(timebuf, sizeof(timebuf), NULL)[-3] = '\0';
1867 pbuf = timebuf;
1868 break;
1826# if ENABLE_USERNAME_OR_HOMEDIR 1869# if ENABLE_USERNAME_OR_HOMEDIR
1827 case 'w': 1870 case 'w': /* current dir */
1828 /* /home/user[/something] -> ~[/something] */ 1871 case 'W': /* basename of cur dir */
1829 pbuf = cwd_buf; 1872 if (!cwd_buf) {
1830 l = strlen(home_pwd_buf); 1873 cwd_buf = xrealloc_getcwd_or_warn(NULL);
1831 if (l != 0 1874 if (!cwd_buf)
1875 cwd_buf = (char *)bb_msg_unknown;
1876 else {
1877 /* /home/user[/something] -> ~[/something] */
1878 l = strlen(home_pwd_buf);
1879 if (l != 0
1832#if !ENABLE_PLATFORM_MINGW32 1880#if !ENABLE_PLATFORM_MINGW32
1833 && strncmp(home_pwd_buf, cwd_buf, l) == 0 1881 && strncmp(home_pwd_buf, cwd_buf, l) == 0
1834#else 1882#else
1835 && strncasecmp(home_pwd_buf, cwd_buf, l) == 0 1883 && strncasecmp(home_pwd_buf, cwd_buf, l) == 0
1836#endif 1884#endif
1837 && (cwd_buf[l]=='/' || cwd_buf[l]=='\0') 1885 && (cwd_buf[l] == '/' || cwd_buf[l] == '\0')
1838 && strlen(cwd_buf + l) < PATH_MAX 1886 ) {
1839 ) { 1887 cwd_buf[0] = '~';
1840 pbuf = free_me = xasprintf("~%s", cwd_buf + l); 1888 overlapping_strcpy(cwd_buf + 1, cwd_buf + l);
1889 }
1890 }
1841 } 1891 }
1842 break;
1843# endif
1844 case 'W':
1845 pbuf = cwd_buf; 1892 pbuf = cwd_buf;
1893 if (c == 'w')
1894 break;
1846 cp = strrchr(pbuf, '/'); 1895 cp = strrchr(pbuf, '/');
1847 if (cp != NULL && cp != pbuf) 1896 if (cp)
1848 pbuf += (cp-pbuf) + 1; 1897 pbuf = (char*)cp + 1;
1849 break;
1850 case '!':
1851 pbuf = free_me = xasprintf("%d", num_ok_lines);
1852 break;
1853 case 'e': case 'E': /* \e \E = \033 */
1854 c = '\033';
1855 break; 1898 break;
1899# endif
1900// bb_process_escape_sequence does this now:
1901// case 'e': case 'E': /* \e \E = \033 */
1902// c = '\033';
1903// break;
1856 case 'x': case 'X': { 1904 case 'x': case 'X': {
1857 char buf2[4]; 1905 char buf2[4];
1858 for (l = 0; l < 3;) { 1906 for (l = 0; l < 3;) {
@@ -1890,8 +1938,10 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1890 free(free_me); 1938 free(free_me);
1891 } /* while */ 1939 } /* while */
1892 1940
1941# if ENABLE_USERNAME_OR_HOMEDIR
1893 if (cwd_buf != (char *)bb_msg_unknown) 1942 if (cwd_buf != (char *)bb_msg_unknown)
1894 free(cwd_buf); 1943 free(cwd_buf);
1944# endif
1895 cmdedit_prompt = prmt_mem_ptr; 1945 cmdedit_prompt = prmt_mem_ptr;
1896 put_prompt(); 1946 put_prompt();
1897} 1947}
diff --git a/libbb/login.c b/libbb/login.c
index 8a82c6add..8f080b775 100644
--- a/libbb/login.c
+++ b/libbb/login.c
@@ -16,7 +16,6 @@
16#define LOGIN " login: " 16#define LOGIN " login: "
17 17
18static const char fmtstr_d[] ALIGN1 = "%A, %d %B %Y"; 18static const char fmtstr_d[] ALIGN1 = "%A, %d %B %Y";
19static const char fmtstr_t[] ALIGN1 = "%H:%M:%S";
20 19
21void FAST_FUNC print_login_issue(const char *issue_file, const char *tty) 20void FAST_FUNC print_login_issue(const char *issue_file, const char *tty)
22{ 21{
@@ -73,7 +72,7 @@ void FAST_FUNC print_login_issue(const char *issue_file, const char *tty)
73 strftime(buf, sizeof(buf), fmtstr_d, localtime(&t)); 72 strftime(buf, sizeof(buf), fmtstr_d, localtime(&t));
74 break; 73 break;
75 case 't': 74 case 't':
76 strftime(buf, sizeof(buf), fmtstr_t, localtime(&t)); 75 strftime_HHMMSS(buf, sizeof(buf), &t);
77 break; 76 break;
78 case 'l': 77 case 'l':
79 outbuf = tty; 78 outbuf = tty;
diff --git a/libbb/time.c b/libbb/time.c
index e2b938471..57e14b66c 100644
--- a/libbb/time.c
+++ b/libbb/time.c
@@ -187,6 +187,27 @@ time_t FAST_FUNC validate_tm_time(const char *date_str, struct tm *ptm)
187 return t; 187 return t;
188} 188}
189 189
190static char* strftime_fmt(char *buf, unsigned len, time_t *tp, const char *fmt)
191{
192 time_t t;
193 if (!tp) {
194 tp = &t;
195 time(tp);
196 }
197 /* Returns pointer to NUL */
198 return buf + strftime(buf, len, fmt, localtime(tp));
199}
200
201char* FAST_FUNC strftime_HHMMSS(char *buf, unsigned len, time_t *tp)
202{
203 return strftime_fmt(buf, len, tp, "%H:%M:%S");
204}
205
206char* FAST_FUNC strftime_YYYYMMDDHHMMSS(char *buf, unsigned len, time_t *tp)
207{
208 return strftime_fmt(buf, len, tp, "%Y-%m-%d %H:%M:%S");
209}
210
190#if ENABLE_MONOTONIC_SYSCALL 211#if ENABLE_MONOTONIC_SYSCALL
191 212
192#include <sys/syscall.h> 213#include <sys/syscall.h>
diff --git a/miscutils/setserial.c b/miscutils/setserial.c
index 2a034e32c..dfed3306e 100644
--- a/miscutils/setserial.c
+++ b/miscutils/setserial.c
@@ -223,7 +223,7 @@ struct serial_struct {
223//usage: " -v Verbose\n" 223//usage: " -v Verbose\n"
224//usage: "\n" 224//usage: "\n"
225//usage: "Parameters: (* = takes an argument, ^ = can be turned off by preceding ^)\n" 225//usage: "Parameters: (* = takes an argument, ^ = can be turned off by preceding ^)\n"
226//usage: " *port, *irq, *divisor, *uart, *baund_base, *close_delay, *closing_wait,\n" 226//usage: " *port, *irq, *divisor, *uart, *baud_base, *close_delay, *closing_wait,\n"
227//usage: " ^fourport, ^auto_irq, ^skip_test, ^sak, ^session_lockout, ^pgrp_lockout,\n" 227//usage: " ^fourport, ^auto_irq, ^skip_test, ^sak, ^session_lockout, ^pgrp_lockout,\n"
228//usage: " ^callout_nohup, ^split_termios, ^hup_notify, ^low_latency, autoconfig,\n" 228//usage: " ^callout_nohup, ^split_termios, ^hup_notify, ^low_latency, autoconfig,\n"
229//usage: " spd_normal, spd_hi, spd_vhi, spd_shi, spd_warp, spd_cust\n" 229//usage: " spd_normal, spd_hi, spd_vhi, spd_shi, spd_warp, spd_cust\n"
@@ -311,7 +311,7 @@ static const char commands[] =
311 "irq\0" 311 "irq\0"
312 "divisor\0" 312 "divisor\0"
313 "uart\0" 313 "uart\0"
314 "baund_base\0" 314 "baud_base\0"
315 "close_delay\0" 315 "close_delay\0"
316 "closing_wait\0" 316 "closing_wait\0"
317 317
diff --git a/networking/httpd.c b/networking/httpd.c
index 1934bb27e..b46eb0fab 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -1964,7 +1964,9 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1964 send_headers_and_exit(HTTP_BAD_REQUEST); 1964 send_headers_and_exit(HTTP_BAD_REQUEST);
1965 1965
1966 /* Determine type of request (GET/POST) */ 1966 /* Determine type of request (GET/POST) */
1967 urlp = strpbrk(iobuf, " \t"); 1967 // rfc2616: method and URI is separated by exactly one space
1968 //urlp = strpbrk(iobuf, " \t"); - no, tab isn't allowed
1969 urlp = strchr(iobuf, ' ');
1968 if (urlp == NULL) 1970 if (urlp == NULL)
1969 send_headers_and_exit(HTTP_BAD_REQUEST); 1971 send_headers_and_exit(HTTP_BAD_REQUEST);
1970 *urlp++ = '\0'; 1972 *urlp++ = '\0';
@@ -1982,7 +1984,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1982 if (strcasecmp(iobuf, request_GET) != 0) 1984 if (strcasecmp(iobuf, request_GET) != 0)
1983 send_headers_and_exit(HTTP_NOT_IMPLEMENTED); 1985 send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
1984#endif 1986#endif
1985 urlp = skip_whitespace(urlp); 1987 // rfc2616: method and URI is separated by exactly one space
1988 //urlp = skip_whitespace(urlp); - should not be necessary
1986 if (urlp[0] != '/') 1989 if (urlp[0] != '/')
1987 send_headers_and_exit(HTTP_BAD_REQUEST); 1990 send_headers_and_exit(HTTP_BAD_REQUEST);
1988 1991
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 79b7c3793..0f4319ef2 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -887,11 +887,11 @@ step_time(double offset)
887 887
888 VERB2 { 888 VERB2 {
889 tval = tvc.tv_sec; 889 tval = tvc.tv_sec;
890 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval)); 890 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);
891 bb_error_msg("current time is %s.%06u", buf, (unsigned)tvc.tv_usec); 891 bb_error_msg("current time is %s.%06u", buf, (unsigned)tvc.tv_usec);
892 } 892 }
893 tval = tvn.tv_sec; 893 tval = tvn.tv_sec;
894 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", localtime(&tval)); 894 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);
895 bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset); 895 bb_error_msg("setting time to %s.%06u (offset %+fs)", buf, (unsigned)tvn.tv_usec, offset);
896 896
897 /* Correct various fields which contain time-relative values: */ 897 /* Correct various fields which contain time-relative values: */
diff --git a/networking/ntpd_simple.c b/networking/ntpd_simple.c
index 55bded8ff..3e7fc4719 100644
--- a/networking/ntpd_simple.c
+++ b/networking/ntpd_simple.c
@@ -378,7 +378,7 @@ step_time_once(double offset)
378 bb_perror_msg_and_die("settimeofday"); 378 bb_perror_msg_and_die("settimeofday");
379 379
380 tval = tv.tv_sec; 380 tval = tv.tv_sec;
381 strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y", localtime(&tval)); 381 strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &tval);
382 382
383 bb_error_msg("setting clock to %s (offset %fs)", buf, offset); 383 bb_error_msg("setting clock to %s (offset %fs)", buf, offset);
384 384
diff --git a/procps/watch.c b/procps/watch.c
index 36af1cca7..0397f21bf 100644
--- a/procps/watch.c
+++ b/procps/watch.c
@@ -69,7 +69,6 @@ int watch_main(int argc UNUSED_PARAM, char **argv)
69 printf("\033[H""\033[J"); 69 printf("\033[H""\033[J");
70 if (!(opt & 0x2)) { // no -t 70 if (!(opt & 0x2)) { // no -t
71 const unsigned time_len = sizeof("1234-67-90 23:56:89"); 71 const unsigned time_len = sizeof("1234-67-90 23:56:89");
72 time_t t;
73 72
74 // STDERR_FILENO is procps3 compat: 73 // STDERR_FILENO is procps3 compat:
75 // "watch ls 2>/dev/null" does not detect tty size 74 // "watch ls 2>/dev/null" does not detect tty size
@@ -79,10 +78,13 @@ int watch_main(int argc UNUSED_PARAM, char **argv)
79 free(header); 78 free(header);
80 header = xasprintf("Every %us: %-*s", period, (int)width, cmd); 79 header = xasprintf("Every %us: %-*s", period, (int)width, cmd);
81 } 80 }
82 time(&t); 81 if (time_len < width) {
83 if (time_len < width) 82 strftime_YYYYMMDDHHMMSS(
84 strftime(header + width - time_len, time_len, 83 header + width - time_len,
85 "%Y-%m-%d %H:%M:%S", localtime(&t)); 84 time_len,
85 /*time_t*:*/ NULL
86 );
87 }
86 88
87 // compat: empty line between header and cmd output 89 // compat: empty line between header and cmd output
88 printf("%s\n\n", header); 90 printf("%s\n\n", header);
diff --git a/util-linux/hexdump.c b/util-linux/hexdump.c
index 9a312f95c..4d998b916 100644
--- a/util-linux/hexdump.c
+++ b/util-linux/hexdump.c
@@ -116,7 +116,12 @@ int hexdump_main(int argc, char **argv)
116 dumper->dump_length = xatoi_positive(optarg); 116 dumper->dump_length = xatoi_positive(optarg);
117 } /* else */ 117 } /* else */
118 if (ch == 's') { /* compat: -s accepts hex numbers too */ 118 if (ch == 's') { /* compat: -s accepts hex numbers too */
119 dumper->dump_skip = xstrtoul_range_sfx(optarg, /*base:*/ 0, /*lo:*/ 0, /*hi:*/ LONG_MAX, suffixes); 119 dumper->dump_skip = xstrtoull_range_sfx(
120 optarg,
121 /*base:*/ 0,
122 /*lo:*/ 0, /*hi:*/ OFF_T_MAX,
123 suffixes
124 );
120 } /* else */ 125 } /* else */
121 if (ch == 'v') { 126 if (ch == 'v') {
122 dumper->dump_vflag = ALL; 127 dumper->dump_vflag = ALL;
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 5fe6bbbde..1d741367e 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -1060,15 +1060,15 @@ int mdev_main(int argc UNUSED_PARAM, char **argv)
1060 * ACTION can be "add", "remove", "change" 1060 * ACTION can be "add", "remove", "change"
1061 * DEVPATH is like "/block/sda" or "/class/input/mice" 1061 * DEVPATH is like "/block/sda" or "/class/input/mice"
1062 */ 1062 */
1063 action = getenv("ACTION");
1064 op = index_in_strings(keywords, action);
1065 env_devname = getenv("DEVNAME"); /* can be NULL */ 1063 env_devname = getenv("DEVNAME"); /* can be NULL */
1066 env_devpath = getenv("DEVPATH");
1067 G.subsystem = getenv("SUBSYSTEM"); 1064 G.subsystem = getenv("SUBSYSTEM");
1065 action = getenv("ACTION");
1066 env_devpath = getenv("DEVPATH");
1068 if (!action || !env_devpath /*|| !G.subsystem*/) 1067 if (!action || !env_devpath /*|| !G.subsystem*/)
1069 bb_show_usage(); 1068 bb_show_usage();
1070 fw = getenv("FIRMWARE"); 1069 fw = getenv("FIRMWARE");
1071 seq = getenv("SEQNUM"); 1070 seq = getenv("SEQNUM");
1071 op = index_in_strings(keywords, action);
1072 1072
1073 my_pid = getpid(); 1073 my_pid = getpid();
1074 open_mdev_log(seq, my_pid); 1074 open_mdev_log(seq, my_pid);