Imported from util-linux-2.12j tarball.
This commit is contained in:
parent
0b0bb92085
commit
d162fcb550
14
HISTORY
14
HISTORY
|
@ -1,3 +1,17 @@
|
||||||
|
util-linux 2.12j
|
||||||
|
|
||||||
|
* cal: highlight today (Pádraig Brady)
|
||||||
|
* lomount: stop reading passwd at NUL, fix lo_encrypt key_size (Wolfram Kleff)
|
||||||
|
* losetup: add -f option to find an unused loop device
|
||||||
|
(Alexander Wigen, Remco van Mook)
|
||||||
|
* more: code cleanup (Joachim Henke)
|
||||||
|
* mount: add "group" mount option (Martin Dickopp)
|
||||||
|
* sfdisk: fix 2.6.8 BLKRRPART ioctl damage (Eric Lammerts)
|
||||||
|
* swapon: let swapon -a skip the swapfiles marked "noauto" (Dale R. Worley)
|
||||||
|
* umount: fix problem with empty mtab (Bryan Kadzban)
|
||||||
|
* umount: use special umount program if it exists (Ram Pai)
|
||||||
|
* New Danish messages
|
||||||
|
|
||||||
util-linux 2.12i
|
util-linux 2.12i
|
||||||
|
|
||||||
* MCONFIG: fix build conditions
|
* MCONFIG: fix build conditions
|
||||||
|
|
7
MCONFIG
7
MCONFIG
|
@ -90,6 +90,11 @@ HAVE_KILL=no
|
||||||
# file descriptor after logging out to trick the next user.
|
# file descriptor after logging out to trick the next user.
|
||||||
ALLOW_VCS_USE=yes
|
ALLOW_VCS_USE=yes
|
||||||
|
|
||||||
|
# If DO_STAT_MAIL is set to "yes", then login will stat() the mailbox
|
||||||
|
# and tell the user that she has new mail. This can hang the login if
|
||||||
|
# the mailbox is on a NFS mounted filesystem.
|
||||||
|
DO_STAT_MAIL=no
|
||||||
|
|
||||||
# If HAVE_RESET is set to "yes", then reset won't be installed. The version
|
# If HAVE_RESET is set to "yes", then reset won't be installed. The version
|
||||||
# of reset that comes with the ncurses package is less aggressive.
|
# of reset that comes with the ncurses package is less aggressive.
|
||||||
HAVE_RESET=yes
|
HAVE_RESET=yes
|
||||||
|
@ -118,7 +123,7 @@ ifeq "$(ARCH)" "intel"
|
||||||
CPUHEAD=-m
|
CPUHEAD=-m
|
||||||
else
|
else
|
||||||
CPUHEAD=-mcpu=i
|
CPUHEAD=-mcpu=i
|
||||||
# recent versions want -march=i
|
# it is rumoured that recent gcc versions want -march=i
|
||||||
# must add the right test
|
# must add the right test
|
||||||
endif
|
endif
|
||||||
ifeq "$(CPU)" "i386"
|
ifeq "$(CPU)" "i386"
|
||||||
|
|
|
@ -145,7 +145,7 @@ if ./testincl "sys/user.h"; then
|
||||||
echo "#define HAVE_sys_user_h" >> defines.h
|
echo "#define HAVE_sys_user_h" >> defines.h
|
||||||
else if ./testincl "asm/page.h"; then
|
else if ./testincl "asm/page.h"; then
|
||||||
echo "#define HAVE_asm_page_h" >> defines.h
|
echo "#define HAVE_asm_page_h" >> defines.h
|
||||||
fi fi
|
fi; fi
|
||||||
|
|
||||||
#
|
#
|
||||||
# H7. For nfsmount.c: do we have <rpcsvc/nfs_prot.h>?
|
# H7. For nfsmount.c: do we have <rpcsvc/nfs_prot.h>?
|
||||||
|
@ -418,6 +418,7 @@ if [ $have_ncurses = 0 ]; then
|
||||||
echo "You don't have ncurses - I will not make ul and setterm."
|
echo "You don't have ncurses - I will not make ul and setterm."
|
||||||
else
|
else
|
||||||
echo "LIBCURSES=-lncurses" >> make_include
|
echo "LIBCURSES=-lncurses" >> make_include
|
||||||
|
echo "#define HAVE_ncurses" >> defines.h
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -1444,8 +1444,10 @@ new_part(int i) {
|
||||||
print_warning(_("No room to create the extended partition"));
|
print_warning(_("No room to create the extended partition"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
(void) add_part(ext, DOS_EXTENDED, 0, first, last,
|
errmsg = 0;
|
||||||
(first == 0 ? sectors : 0), 0, &errmsg);
|
if (add_part(ext, DOS_EXTENDED, 0, first, last,
|
||||||
|
(first == 0 ? sectors : 0), 0, &errmsg) && errmsg)
|
||||||
|
print_warning(errmsg);
|
||||||
first = ext_info.first_sector + ext_info.offset;
|
first = ext_info.first_sector + ext_info.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1456,7 +1458,9 @@ new_part(int i) {
|
||||||
if (first == 0 || IS_LOGICAL(num))
|
if (first == 0 || IS_LOGICAL(num))
|
||||||
offset = sectors;
|
offset = sectors;
|
||||||
|
|
||||||
(void) add_part(num, id, flags, first, last, offset, 0, &errmsg);
|
errmsg = 0;
|
||||||
|
if (add_part(num, id, flags, first, last, offset, 0, &errmsg) && errmsg)
|
||||||
|
print_warning(errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -295,6 +295,20 @@ set_changed(int i) {
|
||||||
ptes[i].changed = 1;
|
ptes[i].changed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_garbage_table(void) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
struct pte *pe = &ptes[i];
|
||||||
|
struct partition *p = pe->part_table;
|
||||||
|
|
||||||
|
if (p->boot_ind != 0 && p->boot_ind != 0x80)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Avoid warning about DOS partitions when no DOS partition was changed.
|
* Avoid warning about DOS partitions when no DOS partition was changed.
|
||||||
* Here a heuristic "is probably dos partition".
|
* Here a heuristic "is probably dos partition".
|
||||||
|
@ -630,7 +644,7 @@ read_extended(int ext) {
|
||||||
struct pte *pre = &ptes[partitions-1];
|
struct pte *pre = &ptes[partitions-1];
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("Warning: deleting partitions after %d\n"),
|
_("Warning: omitting partitions after %d\n"),
|
||||||
partitions);
|
partitions);
|
||||||
clear_partition(pre->ext_pointer);
|
clear_partition(pre->ext_pointer);
|
||||||
pre->changed = 1;
|
pre->changed = 1;
|
||||||
|
@ -1684,6 +1698,12 @@ list_table(int xtra) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_garbage_table()) {
|
||||||
|
printf(_("This doesn't look like a partition table\n"
|
||||||
|
"Probably you selected the wrong device.\n\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Heuristic: we list partition 3 of /dev/foo as /dev/foo3,
|
/* Heuristic: we list partition 3 of /dev/foo as /dev/foo3,
|
||||||
but if the device name ends in a digit, say /dev/foo1,
|
but if the device name ends in a digit, say /dev/foo1,
|
||||||
then the partition is called /dev/foo1p3. */
|
then the partition is called /dev/foo1p3. */
|
||||||
|
|
|
@ -74,6 +74,7 @@ struct systypes i386_sys_types[] = {
|
||||||
{0xb8, N_("BSDI swap")},
|
{0xb8, N_("BSDI swap")},
|
||||||
{0xbb, N_("Boot Wizard hidden")},
|
{0xbb, N_("Boot Wizard hidden")},
|
||||||
{0xbe, N_("Solaris boot")},
|
{0xbe, N_("Solaris boot")},
|
||||||
|
{0xbf, N_("Solaris")},
|
||||||
{0xc1, N_("DRDOS/sec (FAT-12)")},
|
{0xc1, N_("DRDOS/sec (FAT-12)")},
|
||||||
{0xc4, N_("DRDOS/sec (FAT-16 < 32M)")},
|
{0xc4, N_("DRDOS/sec (FAT-16 < 32M)")},
|
||||||
{0xc6, N_("DRDOS/sec (FAT-16)")},
|
{0xc6, N_("DRDOS/sec (FAT-16)")},
|
||||||
|
|
|
@ -792,7 +792,10 @@ static int
|
||||||
reread_ioctl(int fd) {
|
reread_ioctl(int fd) {
|
||||||
if (ioctl(fd, BLKRRPART)) {
|
if (ioctl(fd, BLKRRPART)) {
|
||||||
perror("BLKRRPART");
|
perror("BLKRRPART");
|
||||||
return -1;
|
|
||||||
|
/* 2.6.8 returns EIO for a zero table */
|
||||||
|
if (errno == EBUSY)
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,9 @@ endif
|
||||||
ifeq "$(ALLOW_VCS_USE)" "yes"
|
ifeq "$(ALLOW_VCS_USE)" "yes"
|
||||||
LOGINFLAGS += -DCHOWNVCS
|
LOGINFLAGS += -DCHOWNVCS
|
||||||
endif
|
endif
|
||||||
|
ifeq "$(DO_STAT_MAIL)" "yes"
|
||||||
|
LOGINFLAGS += -DDO_STAT_MAIL
|
||||||
|
endif
|
||||||
|
|
||||||
login.o: login.c $(LIB)/pathnames.h $(LIB)/setproctitle.c $(LIB)/setproctitle.h
|
login.o: login.c $(LIB)/pathnames.h $(LIB)/setproctitle.c $(LIB)/setproctitle.h
|
||||||
$(CC) -c $(CFLAGS) $(PAMFL) $(LOGINFLAGS) login.c
|
$(CC) -c $(CFLAGS) $(PAMFL) $(LOGINFLAGS) login.c
|
||||||
|
|
|
@ -1081,17 +1081,28 @@ Michael Riepe <michael@stud.uni-hannover.de>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quietlog) {
|
if (!quietlog) {
|
||||||
struct stat st;
|
|
||||||
char *mail;
|
|
||||||
|
|
||||||
motd();
|
motd();
|
||||||
mail = getenv("MAIL");
|
|
||||||
if (mail && stat(mail, &st) == 0 && st.st_size != 0) {
|
#ifdef DO_STAT_MAIL
|
||||||
|
/*
|
||||||
|
* This turns out to be a bad idea: when the mail spool
|
||||||
|
* is NFS mounted, and the NFS connection hangs, the
|
||||||
|
* login hangs, even root cannot login.
|
||||||
|
* Checking for mail should be done from the shell.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
char *mail;
|
||||||
|
|
||||||
|
mail = getenv("MAIL");
|
||||||
|
if (mail && stat(mail, &st) == 0 && st.st_size != 0) {
|
||||||
if (st.st_mtime > st.st_atime)
|
if (st.st_mtime > st.st_atime)
|
||||||
printf(_("You have new mail.\n"));
|
printf(_("You have new mail.\n"));
|
||||||
else
|
else
|
||||||
printf(_("You have mail.\n"));
|
printf(_("You have mail.\n"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
signal(SIGALRM, SIG_DFL);
|
signal(SIGALRM, SIG_DFL);
|
||||||
|
|
|
@ -51,7 +51,6 @@ LIBPTY:=$(LIBPTY) -lutil
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Programs requiring special compilation
|
# Programs requiring special compilation
|
||||||
|
|
||||||
NEEDS_CURSES= setterm
|
NEEDS_CURSES= setterm
|
||||||
NEEDS_OPENPTY= script
|
NEEDS_OPENPTY= script
|
||||||
|
|
||||||
|
@ -64,6 +63,16 @@ else
|
||||||
@echo $@ not made since it requires ncurses
|
@echo $@ not made since it requires ncurses
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq "$(HAVE_NCURSES)" "yes"
|
||||||
|
cal:
|
||||||
|
$(CC) $(LDFLAGS) $^ -o $@ $(LIBCURSES)
|
||||||
|
else
|
||||||
|
ifeq "$(HAVE_TERMCAP)" "yes"
|
||||||
|
cal:
|
||||||
|
$(CC) $(LDFLAGS) $^ -o $@ $(LIBTERMCAP)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
$(NEEDS_OPENPTY):
|
$(NEEDS_OPENPTY):
|
||||||
$(CC) $(LDFLAGS) $^ -o $@ $(LIBPTY)
|
$(CC) $(LDFLAGS) $^ -o $@ $(LIBPTY)
|
||||||
|
|
||||||
|
|
432
misc-utils/cal.c
432
misc-utils/cal.c
|
@ -35,11 +35,11 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 1999-02-01 Jean-Francois Bignolles: added option '-m' to display
|
/* 1999-02-01 Jean-Francois Bignolles: added option '-m' to display
|
||||||
* monday as the first day of the week.
|
* monday as the first day of the week.
|
||||||
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
|
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
|
||||||
* - added Native Language Support
|
* - added Native Language Support
|
||||||
*
|
*
|
||||||
* 2000-09-01 Michael Charles Pruznick <dummy@netwiz.net>
|
* 2000-09-01 Michael Charles Pruznick <dummy@netwiz.net>
|
||||||
* Added "-3" option to print prev/next month with current.
|
* Added "-3" option to print prev/next month with current.
|
||||||
* Added over-ridable default NUM_MONTHS and "-1" option to
|
* Added over-ridable default NUM_MONTHS and "-1" option to
|
||||||
* get traditional output when -3 is the default. I hope that
|
* get traditional output when -3 is the default. I hope that
|
||||||
|
@ -68,6 +68,57 @@
|
||||||
#include "nls.h"
|
#include "nls.h"
|
||||||
#include "../defines.h"
|
#include "../defines.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_ncurses)
|
||||||
|
|
||||||
|
#if NCH
|
||||||
|
#include <ncurses.h>
|
||||||
|
#else
|
||||||
|
#include <curses.h>
|
||||||
|
#endif
|
||||||
|
#include <term.h> /* include after <curses.h> */
|
||||||
|
|
||||||
|
static void
|
||||||
|
my_setupterm(const char *term, int fildes, int *errret) {
|
||||||
|
setupterm((char*)term, fildes, errret);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
my_putstring(char *s) {
|
||||||
|
putp(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
my_tgetstr(char *s, char *ss) {
|
||||||
|
return tigetstr(ss);
|
||||||
|
}
|
||||||
|
|
||||||
|
#elif defined(HAVE_termcap)
|
||||||
|
|
||||||
|
#include <termcap.h>
|
||||||
|
|
||||||
|
char termbuffer[4096];
|
||||||
|
char tcbuffer[4096];
|
||||||
|
char *strbuf = termbuffer;
|
||||||
|
|
||||||
|
static void
|
||||||
|
my_setupterm(const char *term, int fildes, int *errret) {
|
||||||
|
*errret = tgetent(tcbuffer, term);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
my_putstring(char *s) {
|
||||||
|
tputs (s, 1, putchar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
my_tgetstr(char *s, char *ss) {
|
||||||
|
return tgetstr(s, &strbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
const char *term="";
|
||||||
|
const char *Senter="", *Sexit="";/* enter and exit standout mode */
|
||||||
|
|
||||||
#ifdef HAVE_langinfo_h
|
#ifdef HAVE_langinfo_h
|
||||||
# include <langinfo.h>
|
# include <langinfo.h>
|
||||||
#else
|
#else
|
||||||
|
@ -77,7 +128,7 @@
|
||||||
#include "widechar.h"
|
#include "widechar.h"
|
||||||
|
|
||||||
#define SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
#define SIZE(a) (sizeof(a)/sizeof((a)[0]))
|
||||||
|
|
||||||
/* allow compile-time define to over-ride default */
|
/* allow compile-time define to over-ride default */
|
||||||
#ifndef NUM_MONTHS
|
#ifndef NUM_MONTHS
|
||||||
#define NUM_MONTHS 1
|
#define NUM_MONTHS 1
|
||||||
|
@ -88,10 +139,10 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define THURSDAY 4 /* for reformation */
|
#define THURSDAY 4 /* for reformation */
|
||||||
#define SATURDAY 6 /* 1 Jan 1 was a Saturday */
|
#define SATURDAY 6 /* 1 Jan 1 was a Saturday */
|
||||||
|
|
||||||
#define FIRST_MISSING_DAY 639799 /* 3 Sep 1752 */
|
#define FIRST_MISSING_DAY 639799 /* 3 Sep 1752 */
|
||||||
#define NUMBER_MISSING_DAYS 11 /* 11 day correction */
|
#define NUMBER_MISSING_DAYS 11 /* 11 day correction */
|
||||||
|
|
||||||
#define MAXDAYS 43 /* max slots in a month array */
|
#define MAXDAYS 43 /* max slots in a month array */
|
||||||
#define SPACE -1 /* used in day array */
|
#define SPACE -1 /* used in day array */
|
||||||
|
@ -162,6 +213,8 @@ const char *full_month[12];
|
||||||
int week1stday=0;
|
int week1stday=0;
|
||||||
int julian;
|
int julian;
|
||||||
|
|
||||||
|
#define TODAY_FLAG 0x400 /* flag day for highlighting */
|
||||||
|
|
||||||
#define FMT_ST_LINES 8
|
#define FMT_ST_LINES 8
|
||||||
#define FMT_ST_CHARS 300 /* 90 suffices in most locales */
|
#define FMT_ST_CHARS 300 /* 90 suffices in most locales */
|
||||||
struct fmt_st
|
struct fmt_st
|
||||||
|
@ -169,26 +222,27 @@ struct fmt_st
|
||||||
char s[FMT_ST_LINES][FMT_ST_CHARS];
|
char s[FMT_ST_LINES][FMT_ST_CHARS];
|
||||||
};
|
};
|
||||||
|
|
||||||
void ascii_day __P((char *, int));
|
char * ascii_day(char *, int);
|
||||||
void center __P((const char *, int, int));
|
void center_str(const char* src, char* dest, size_t dest_size, int width);
|
||||||
void day_array __P((int, int, int *));
|
void center(const char *, int, int);
|
||||||
int day_in_week __P((int, int, int));
|
void day_array(int, int, int, int *);
|
||||||
int day_in_year __P((int, int, int));
|
int day_in_week(int, int, int);
|
||||||
void j_yearly __P((int));
|
int day_in_year(int, int, int);
|
||||||
void do_monthly __P((int, int, struct fmt_st*));
|
void yearly(int, int);
|
||||||
void monthly __P((int, int));
|
void j_yearly(int, int);
|
||||||
void monthly3 __P((int, int));
|
void do_monthly(int, int, int, struct fmt_st*);
|
||||||
void trim_trailing_spaces __P((char *));
|
void monthly(int, int, int);
|
||||||
void usage __P((void));
|
void monthly3(int, int, int);
|
||||||
void yearly __P((int));
|
void trim_trailing_spaces(char *);
|
||||||
void headers_init(void);
|
void usage(void);
|
||||||
|
void headers_init(void);
|
||||||
extern char *__progname;
|
extern char *__progname;
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv) {
|
main(int argc, char **argv) {
|
||||||
struct tm *local_time;
|
struct tm *local_time;
|
||||||
time_t now;
|
time_t now;
|
||||||
int ch, month, year, yflag;
|
int ch, day, month, year, yflag;
|
||||||
char *progname, *p;
|
char *progname, *p;
|
||||||
int num_months = NUM_MONTHS;
|
int num_months = NUM_MONTHS;
|
||||||
|
|
||||||
|
@ -201,6 +255,17 @@ main(int argc, char **argv) {
|
||||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
textdomain(PACKAGE);
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
|
#if defined(HAVE_ncurses) || defined(HAVE_termcap)
|
||||||
|
if ((term = getenv("TERM"))) {
|
||||||
|
int ret;
|
||||||
|
my_setupterm(term, 1, &ret);
|
||||||
|
if (ret > 0) {
|
||||||
|
Senter = my_tgetstr("so","smso");
|
||||||
|
Sexit = my_tgetstr("se","rmso");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if 0 /* setting week1stday is against man page */
|
#if 0 /* setting week1stday is against man page */
|
||||||
/*
|
/*
|
||||||
* What *is* the first day of the week? Note that glibc does not
|
* What *is* the first day of the week? Note that glibc does not
|
||||||
|
@ -214,7 +279,7 @@ main(int argc, char **argv) {
|
||||||
*
|
*
|
||||||
* The traditional Unix cal utility starts at Sunday.
|
* The traditional Unix cal utility starts at Sunday.
|
||||||
* We start at Sunday and have an option -m for starting at Monday.
|
* We start at Sunday and have an option -m for starting at Monday.
|
||||||
*
|
*
|
||||||
* At some future time this may become -s for Sunday, -m for Monday,
|
* At some future time this may become -s for Sunday, -m for Monday,
|
||||||
* no option for glibc-determined locale-dependent version.
|
* no option for glibc-determined locale-dependent version.
|
||||||
*/
|
*/
|
||||||
|
@ -222,16 +287,16 @@ main(int argc, char **argv) {
|
||||||
week1stday = (int)(nl_langinfo(_NL_TIME_FIRST_WEEKDAY))[0];
|
week1stday = (int)(nl_langinfo(_NL_TIME_FIRST_WEEKDAY))[0];
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
yflag = 0;
|
yflag = 0;
|
||||||
while ((ch = getopt(argc, argv, "13mjsyV")) != -1)
|
while ((ch = getopt(argc, argv, "13mjsyV")) != -1)
|
||||||
switch(ch) {
|
switch(ch) {
|
||||||
case '1':
|
case '1':
|
||||||
num_months = 1; /* default */
|
num_months = 1; /* default */
|
||||||
break;
|
break;
|
||||||
case '3':
|
case '3':
|
||||||
num_months = 3;
|
num_months = 3;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
week1stday = 0; /* default */
|
week1stday = 0; /* default */
|
||||||
break;
|
break;
|
||||||
|
@ -255,7 +320,7 @@ main(int argc, char **argv) {
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
|
|
||||||
month = year = 0;
|
day = month = year = 0;
|
||||||
switch(argc) {
|
switch(argc) {
|
||||||
case 2:
|
case 2:
|
||||||
if ((month = atoi(*argv++)) < 1 || month > 12)
|
if ((month = atoi(*argv++)) < 1 || month > 12)
|
||||||
|
@ -266,8 +331,10 @@ main(int argc, char **argv) {
|
||||||
errx(1, _("illegal year value: use 1-9999"));
|
errx(1, _("illegal year value: use 1-9999"));
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
(void)time(&now);
|
time(&now);
|
||||||
local_time = localtime(&now);
|
local_time = localtime(&now);
|
||||||
|
if (isatty(1))
|
||||||
|
day = local_time->tm_yday + 1;
|
||||||
year = local_time->tm_year + 1900;
|
year = local_time->tm_year + 1900;
|
||||||
if (!yflag)
|
if (!yflag)
|
||||||
month = local_time->tm_mon + 1;
|
month = local_time->tm_mon + 1;
|
||||||
|
@ -278,13 +345,13 @@ main(int argc, char **argv) {
|
||||||
headers_init();
|
headers_init();
|
||||||
|
|
||||||
if (month && num_months == 1)
|
if (month && num_months == 1)
|
||||||
monthly(month, year);
|
monthly(day, month, year);
|
||||||
else if (month && num_months == 3)
|
else if (month && num_months == 3)
|
||||||
monthly3(month, year);
|
monthly3(day, month, year);
|
||||||
else if (julian)
|
else if (julian)
|
||||||
j_yearly(year);
|
j_yearly(day, year);
|
||||||
else
|
else
|
||||||
yearly(year);
|
yearly(day, year);
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,7 +383,7 @@ void headers_init(void)
|
||||||
#else
|
#else
|
||||||
# define weekday(wd) _time_info->abbrev_wkday[wd]
|
# define weekday(wd) _time_info->abbrev_wkday[wd]
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for(i = 0 ; i < 7 ; i++ ) {
|
for(i = 0 ; i < 7 ; i++ ) {
|
||||||
wd = (i + week1stday) % 7;
|
wd = (i + week1stday) % 7;
|
||||||
#ifdef ENABLE_WIDECHAR
|
#ifdef ENABLE_WIDECHAR
|
||||||
|
@ -342,8 +409,10 @@ void headers_init(void)
|
||||||
wcstombs(j_day_headings,j_day_headings_wc,sizeof(j_day_headings));
|
wcstombs(j_day_headings,j_day_headings_wc,sizeof(j_day_headings));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
trim_trailing_spaces(day_headings);
|
||||||
|
trim_trailing_spaces(j_day_headings);
|
||||||
#undef weekday
|
#undef weekday
|
||||||
|
|
||||||
for (i = 0; i < 12; i++) {
|
for (i = 0; i < 12; i++) {
|
||||||
#ifdef HAVE_langinfo_h
|
#ifdef HAVE_langinfo_h
|
||||||
full_month[i] = nl_langinfo(MON_1+i);
|
full_month[i] = nl_langinfo(MON_1+i);
|
||||||
|
@ -354,62 +423,51 @@ void headers_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
do_monthly(month, year, out)
|
do_monthly(int day, int month, int year, struct fmt_st *out) {
|
||||||
int month, year;
|
|
||||||
struct fmt_st* out;
|
|
||||||
{
|
|
||||||
int col, row, len, days[MAXDAYS];
|
int col, row, len, days[MAXDAYS];
|
||||||
char *p, lineout[300];
|
char *p, lineout[FMT_ST_CHARS];
|
||||||
#ifdef ENABLE_WIDECHAR
|
int width = (julian ? J_WEEK_LEN : WEEK_LEN) - 1;
|
||||||
wchar_t lineout_wc[300];
|
|
||||||
#endif
|
day_array(day, month, year, days);
|
||||||
|
|
||||||
day_array(month, year, days);
|
/*
|
||||||
/* %s is the month name, %d the year number.
|
* %s is the month name, %d the year number.
|
||||||
* you can change the order and/or add something here; eg for
|
* you can change the order and/or add something here; eg for
|
||||||
* Basque the translation should be: "%2$dko %1$s", and
|
* Basque the translation should be: "%2$dko %1$s", and
|
||||||
* the Vietnamese should be "%s na(m %d", etc.
|
* the Vietnamese should be "%s na(m %d", etc.
|
||||||
*/
|
*/
|
||||||
len = sprintf(lineout, _("%s %d"), full_month[month - 1], year);
|
len = sprintf(lineout, _("%s %d"), full_month[month - 1], year);
|
||||||
#ifdef ENABLE_WIDECHAR
|
center_str(lineout, out->s[0], SIZE(out->s[0]), width);
|
||||||
if (mbstowcs(lineout_wc,lineout,len) > 0) {
|
|
||||||
len = wcswidth(lineout_wc,len);
|
sprintf(out->s[1],"%s",
|
||||||
} else {
|
julian ? j_day_headings : day_headings);
|
||||||
len = strlen(lineout);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
(void)sprintf(out->s[0],"%*s%s",
|
|
||||||
((julian ? J_WEEK_LEN : WEEK_LEN) - len) / 2, "", lineout );
|
|
||||||
(void)sprintf(out->s[1],"%s",
|
|
||||||
julian ? j_day_headings : day_headings);
|
|
||||||
for (row = 0; row < 6; row++) {
|
for (row = 0; row < 6; row++) {
|
||||||
for (col = 0, p = lineout; col < 7; col++,
|
for (col = 0, p = lineout; col < 7; col++)
|
||||||
p += julian ? J_DAY_LEN : DAY_LEN)
|
p = ascii_day(p, days[row * 7 + col]);
|
||||||
ascii_day(p, days[row * 7 + col]);
|
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
trim_trailing_spaces(lineout);
|
trim_trailing_spaces(lineout);
|
||||||
(void)sprintf(out->s[row+2],"%s", lineout);
|
sprintf(out->s[row+2], "%s", lineout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
monthly(month, year)
|
monthly(int day, int month, int year) {
|
||||||
int month, year;
|
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
struct fmt_st out;
|
struct fmt_st out;
|
||||||
|
|
||||||
do_monthly(month, year, &out);
|
do_monthly(day, month, year, &out);
|
||||||
for ( i = 0; i < FMT_ST_LINES; i++ )
|
for (i = 0; i < FMT_ST_LINES; i++) {
|
||||||
{
|
#if defined(HAVE_ncurses) || defined(HAVE_termcap)
|
||||||
printf("%s\n", out.s[i]);
|
my_putstring(out.s[i]);putchar('\n');
|
||||||
|
#else
|
||||||
|
puts(out.s[i]);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
monthly3(month, year)
|
monthly3(int day, int month, int year) {
|
||||||
int month, year;
|
char lineout[FMT_ST_CHARS];
|
||||||
{
|
|
||||||
int i;
|
int i;
|
||||||
int width;
|
int width;
|
||||||
struct fmt_st out_prev;
|
struct fmt_st out_prev;
|
||||||
|
@ -418,109 +476,117 @@ monthly3(month, year)
|
||||||
int prev_month, prev_year;
|
int prev_month, prev_year;
|
||||||
int next_month, next_year;
|
int next_month, next_year;
|
||||||
|
|
||||||
if ( month == 1 )
|
if (month == 1) {
|
||||||
{
|
prev_month = 12;
|
||||||
prev_month = 12;
|
prev_year = year - 1;
|
||||||
prev_year = year - 1;
|
} else {
|
||||||
|
prev_month = month - 1;
|
||||||
|
prev_year = year;
|
||||||
}
|
}
|
||||||
else
|
if (month == 12) {
|
||||||
{
|
next_month = 1;
|
||||||
prev_month = month - 1;
|
next_year = year + 1;
|
||||||
prev_year = year;
|
} else {
|
||||||
}
|
next_month = month + 1;
|
||||||
if ( month == 12 )
|
next_year = year;
|
||||||
{
|
|
||||||
next_month = 1;
|
|
||||||
next_year = year + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
next_month = month + 1;
|
|
||||||
next_year = year;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
do_monthly(prev_month, prev_year, &out_prev);
|
do_monthly(day, prev_month, prev_year, &out_prev);
|
||||||
do_monthly(month, year, &out_curm);
|
do_monthly(day, month, year, &out_curm);
|
||||||
do_monthly(next_month, next_year, &out_next);
|
do_monthly(day, next_month, next_year, &out_next);
|
||||||
width = (julian ? J_WEEK_LEN : WEEK_LEN);
|
width = (julian ? J_WEEK_LEN : WEEK_LEN) -1;
|
||||||
for ( i = 0; i < FMT_ST_LINES; i++ )
|
for (i = 0; i < 2; i++)
|
||||||
{
|
printf("%s %s %s\n", out_prev.s[i], out_curm.s[i], out_next.s[i]);
|
||||||
printf("%-*.*s %-*.*s %-*.*s\n",
|
for (i = 2; i < FMT_ST_LINES; i++) {
|
||||||
width, width, out_prev.s[i],
|
snprintf(lineout, SIZE(lineout), "%-*s %-*s %-*s\n",
|
||||||
width, width, out_curm.s[i],
|
width, out_prev.s[i],
|
||||||
width, width, out_next.s[i] );
|
width, out_curm.s[i],
|
||||||
|
width, out_next.s[i]);
|
||||||
|
#if defined(HAVE_ncurses) || defined(HAVE_termcap)
|
||||||
|
my_putstring(lineout);
|
||||||
|
#else
|
||||||
|
fputs(lineout,stdout);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
j_yearly(year)
|
j_yearly(int day, int year) {
|
||||||
int year;
|
|
||||||
{
|
|
||||||
int col, *dp, i, month, row, which_cal;
|
int col, *dp, i, month, row, which_cal;
|
||||||
int days[12][MAXDAYS];
|
int days[12][MAXDAYS];
|
||||||
char *p, lineout[80];
|
char *p, lineout[80];
|
||||||
|
|
||||||
(void)sprintf(lineout, "%d", year);
|
sprintf(lineout, "%d", year);
|
||||||
center(lineout, J_WEEK_LEN * 2 + J_HEAD_SEP, 0);
|
center(lineout, J_WEEK_LEN * 2 + J_HEAD_SEP, 0);
|
||||||
(void)printf("\n\n");
|
printf("\n\n");
|
||||||
|
|
||||||
for (i = 0; i < 12; i++)
|
for (i = 0; i < 12; i++)
|
||||||
day_array(i + 1, year, days[i]);
|
day_array(day, i + 1, year, days[i]);
|
||||||
(void)memset(lineout, ' ', sizeof(lineout) - 1);
|
memset(lineout, ' ', sizeof(lineout) - 1);
|
||||||
lineout[sizeof(lineout) - 1] = '\0';
|
lineout[sizeof(lineout) - 1] = '\0';
|
||||||
for (month = 0; month < 12; month += 2) {
|
for (month = 0; month < 12; month += 2) {
|
||||||
center(full_month[month], J_WEEK_LEN, J_HEAD_SEP);
|
center(full_month[month], J_WEEK_LEN, J_HEAD_SEP);
|
||||||
center(full_month[month + 1], J_WEEK_LEN, 0);
|
center(full_month[month + 1], J_WEEK_LEN, 0);
|
||||||
(void)printf("\n%s%*s%s\n", j_day_headings, J_HEAD_SEP, "",
|
printf("\n%s%*s %s\n", j_day_headings, J_HEAD_SEP, "",
|
||||||
j_day_headings);
|
j_day_headings);
|
||||||
for (row = 0; row < 6; row++) {
|
for (row = 0; row < 6; row++) {
|
||||||
|
p = lineout;
|
||||||
for (which_cal = 0; which_cal < 2; which_cal++) {
|
for (which_cal = 0; which_cal < 2; which_cal++) {
|
||||||
p = lineout + which_cal * (J_WEEK_LEN + 2);
|
|
||||||
dp = &days[month + which_cal][row * 7];
|
dp = &days[month + which_cal][row * 7];
|
||||||
for (col = 0; col < 7; col++, p += J_DAY_LEN)
|
for (col = 0; col < 7; col++)
|
||||||
ascii_day(p, *dp++);
|
p = ascii_day(p, *dp++);
|
||||||
|
p += sprintf(p, " ");
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
trim_trailing_spaces(lineout);
|
trim_trailing_spaces(lineout);
|
||||||
(void)printf("%s\n", lineout);
|
#if defined(HAVE_ncurses) || defined(HAVE_termcap)
|
||||||
|
my_putstring(lineout);putchar('\n');
|
||||||
|
#else
|
||||||
|
puts(lineout);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
yearly(year)
|
yearly(int day, int year) {
|
||||||
int year;
|
|
||||||
{
|
|
||||||
int col, *dp, i, month, row, which_cal;
|
int col, *dp, i, month, row, which_cal;
|
||||||
int days[12][MAXDAYS];
|
int days[12][MAXDAYS];
|
||||||
char *p, lineout[80];
|
char *p, lineout[100];
|
||||||
|
|
||||||
(void)sprintf(lineout, "%d", year);
|
sprintf(lineout, "%d", year);
|
||||||
center(lineout, WEEK_LEN * 3 + HEAD_SEP * 2, 0);
|
center(lineout, WEEK_LEN * 3 + HEAD_SEP * 2, 0);
|
||||||
(void)printf("\n\n");
|
printf("\n\n");
|
||||||
|
|
||||||
for (i = 0; i < 12; i++)
|
for (i = 0; i < 12; i++)
|
||||||
day_array(i + 1, year, days[i]);
|
day_array(day, i + 1, year, days[i]);
|
||||||
(void)memset(lineout, ' ', sizeof(lineout) - 1);
|
memset(lineout, ' ', sizeof(lineout) - 1);
|
||||||
lineout[sizeof(lineout) - 1] = '\0';
|
lineout[sizeof(lineout) - 1] = '\0';
|
||||||
for (month = 0; month < 12; month += 3) {
|
for (month = 0; month < 12; month += 3) {
|
||||||
center(full_month[month], WEEK_LEN, HEAD_SEP);
|
center(full_month[month], WEEK_LEN, HEAD_SEP);
|
||||||
center(full_month[month + 1], WEEK_LEN, HEAD_SEP);
|
center(full_month[month + 1], WEEK_LEN, HEAD_SEP);
|
||||||
center(full_month[month + 2], WEEK_LEN, 0);
|
center(full_month[month + 2], WEEK_LEN, 0);
|
||||||
(void)printf("\n%s%*s%s%*s%s\n", day_headings, HEAD_SEP,
|
printf("\n%s%*s %s%*s %s\n", day_headings, HEAD_SEP,
|
||||||
"", day_headings, HEAD_SEP, "", day_headings);
|
"", day_headings, HEAD_SEP, "", day_headings);
|
||||||
for (row = 0; row < 6; row++) {
|
for (row = 0; row < 6; row++) {
|
||||||
|
p = lineout;
|
||||||
for (which_cal = 0; which_cal < 3; which_cal++) {
|
for (which_cal = 0; which_cal < 3; which_cal++) {
|
||||||
p = lineout + which_cal * (WEEK_LEN + 2);
|
|
||||||
dp = &days[month + which_cal][row * 7];
|
dp = &days[month + which_cal][row * 7];
|
||||||
for (col = 0; col < 7; col++, p += DAY_LEN)
|
for (col = 0; col < 7; col++)
|
||||||
ascii_day(p, *dp++);
|
p = ascii_day(p, *dp++);
|
||||||
|
p += sprintf(p, " ");
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
trim_trailing_spaces(lineout);
|
trim_trailing_spaces(lineout);
|
||||||
(void)printf("%s\n", lineout);
|
#if defined(HAVE_ncurses) || defined(HAVE_termcap)
|
||||||
|
my_putstring(lineout);putchar('\n');
|
||||||
|
#else
|
||||||
|
puts(lineout);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void)printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -531,11 +597,8 @@ yearly(year)
|
||||||
* builds that array for any month from Jan. 1 through Dec. 9999.
|
* builds that array for any month from Jan. 1 through Dec. 9999.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
day_array(month, year, days)
|
day_array(int day, int month, int year, int *days) {
|
||||||
int month, year;
|
int julday, daynum, dw, dm;
|
||||||
int *days;
|
|
||||||
{
|
|
||||||
int day, dw, dm;
|
|
||||||
int *d_sep1752;
|
int *d_sep1752;
|
||||||
|
|
||||||
if (month == 9 && year == 1752) {
|
if (month == 9 && year == 1752) {
|
||||||
|
@ -546,9 +609,14 @@ day_array(month, year, days)
|
||||||
memcpy(days, empty, MAXDAYS * sizeof(int));
|
memcpy(days, empty, MAXDAYS * sizeof(int));
|
||||||
dm = days_in_month[leap_year(year)][month];
|
dm = days_in_month[leap_year(year)][month];
|
||||||
dw = (day_in_week(1, month, year) - week1stday + 7) % 7;
|
dw = (day_in_week(1, month, year) - week1stday + 7) % 7;
|
||||||
day = julian ? day_in_year(1, month, year) : 1;
|
julday = day_in_year(1, month, year);
|
||||||
while (dm--)
|
daynum = julian ? julday : 1;
|
||||||
days[dw++] = day++;
|
while (dm--) {
|
||||||
|
days[dw] = daynum++;
|
||||||
|
if (julday++ == day)
|
||||||
|
days[dw] |= TODAY_FLAG;
|
||||||
|
dw++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -556,15 +624,13 @@ day_array(month, year, days)
|
||||||
* return the 1 based day number within the year
|
* return the 1 based day number within the year
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
day_in_year(day, month, year)
|
day_in_year(int day, int month, int year) {
|
||||||
int day, month, year;
|
|
||||||
{
|
|
||||||
int i, leap;
|
int i, leap;
|
||||||
|
|
||||||
leap = leap_year(year);
|
leap = leap_year(year);
|
||||||
for (i = 1; i < month; i++)
|
for (i = 1; i < month; i++)
|
||||||
day += days_in_month[leap][i];
|
day += days_in_month[leap][i];
|
||||||
return (day);
|
return day;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -575,9 +641,7 @@ day_in_year(day, month, year)
|
||||||
* missing days.
|
* missing days.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
day_in_week(day, month, year)
|
day_in_week(int day, int month, int year) {
|
||||||
int day, month, year;
|
|
||||||
{
|
|
||||||
long temp;
|
long temp;
|
||||||
|
|
||||||
temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1)
|
temp = (long)(year - 1) * 365 + leap_years_since_year_1(year - 1)
|
||||||
|
@ -589,12 +653,10 @@ day_in_week(day, month, year)
|
||||||
return (THURSDAY);
|
return (THURSDAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
char *
|
||||||
ascii_day(p, day)
|
ascii_day(char *p, int day) {
|
||||||
char *p;
|
|
||||||
int day;
|
|
||||||
{
|
|
||||||
int display, val;
|
int display, val;
|
||||||
|
int highlight = 0;
|
||||||
static char *aday[] = {
|
static char *aday[] = {
|
||||||
"",
|
"",
|
||||||
" 1", " 2", " 3", " 4", " 5", " 6", " 7",
|
" 1", " 2", " 3", " 4", " 5", " 6", " 7",
|
||||||
|
@ -605,8 +667,14 @@ ascii_day(p, day)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (day == SPACE) {
|
if (day == SPACE) {
|
||||||
memset(p, ' ', julian ? J_DAY_LEN : DAY_LEN);
|
int len = julian ? J_DAY_LEN : DAY_LEN;
|
||||||
return;
|
memset(p, ' ', len);
|
||||||
|
return p+len;
|
||||||
|
}
|
||||||
|
if (day & TODAY_FLAG) {
|
||||||
|
day &= ~TODAY_FLAG;
|
||||||
|
p += sprintf(p, Senter);
|
||||||
|
highlight = 1;
|
||||||
}
|
}
|
||||||
if (julian) {
|
if (julian) {
|
||||||
if ((val = day / 100)) {
|
if ((val = day / 100)) {
|
||||||
|
@ -627,7 +695,10 @@ ascii_day(p, day)
|
||||||
*p++ = aday[day][0];
|
*p++ = aday[day][0];
|
||||||
*p++ = aday[day][1];
|
*p++ = aday[day][1];
|
||||||
}
|
}
|
||||||
*p = ' ';
|
if (highlight)
|
||||||
|
p += sprintf(p, Sexit);
|
||||||
|
*p++ = ' ';
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -645,26 +716,59 @@ trim_trailing_spaces(s)
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Center string, handling multibyte characters appropriately.
|
||||||
|
* In addition if the string is too large for the width it's truncated.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
center_str(const char* src, char* dest, size_t dest_size, int width)
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_WIDECHAR
|
||||||
|
wchar_t str_wc[FMT_ST_CHARS];
|
||||||
|
#endif
|
||||||
|
char str[FMT_ST_CHARS];
|
||||||
|
const char* str_to_print=src;
|
||||||
|
int len, spaces, wide_char_enabled=0;
|
||||||
|
|
||||||
|
len = strlen(src);
|
||||||
|
|
||||||
|
#ifdef ENABLE_WIDECHAR
|
||||||
|
if (mbstowcs(str_wc, src, FMT_ST_CHARS) > 0) {
|
||||||
|
wide_char_enabled = 1;
|
||||||
|
len = wcswidth(str_wc, SIZE(str_wc));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (len > width) {
|
||||||
|
str_to_print=str;
|
||||||
|
if (wide_char_enabled) {
|
||||||
|
#ifdef ENABLE_WIDECHAR
|
||||||
|
str_wc[width]=L'\0';
|
||||||
|
wcstombs(str, str_wc, SIZE(str));
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
strncpy(str, src, SIZE(str));
|
||||||
|
str[width]='\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
spaces = width - len;
|
||||||
|
spaces = ( spaces < 0 ? 0 : spaces );
|
||||||
|
|
||||||
|
snprintf(dest, dest_size, "%*s%s%*s",
|
||||||
|
spaces / 2, "",
|
||||||
|
str_to_print,
|
||||||
|
spaces / 2 + spaces % 2, "" );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
center(str, len, separate)
|
center(str, len, separate)
|
||||||
const char *str;
|
const char *str;
|
||||||
int len;
|
int len;
|
||||||
int separate;
|
int separate;
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_WIDECHAR
|
char lineout[FMT_ST_CHARS];
|
||||||
wchar_t str_wc[300];
|
center_str(str, lineout, SIZE(lineout), len);
|
||||||
int str_len;
|
fputs(lineout, stdout);
|
||||||
|
|
||||||
if (mbstowcs(str_wc,str,300) > 0) {
|
|
||||||
str_len = wcswidth(str_wc,300);
|
|
||||||
} else {
|
|
||||||
str_len = strlen(str);
|
|
||||||
}
|
|
||||||
len -= str_len;
|
|
||||||
#else
|
|
||||||
len -= strlen(str);
|
|
||||||
#endif
|
|
||||||
(void)printf("%*s%s%*s", len / 2, "", str, len / 2 + len % 2, "");
|
|
||||||
if (separate)
|
if (separate)
|
||||||
(void)printf("%*s", separate, "");
|
(void)printf("%*s", separate, "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
LANG=ga_IE.utf8 ./cal -3 11 2004 #truncation
|
||||||
|
LANG=zh_HK.utf8 ./cal -3 #centering
|
||||||
|
./cal | cat #no highlight
|
||||||
|
TERM= ./cal #no highlight
|
||||||
|
TERM=vt100 ./cal #highlight with characters to be stripped by putp
|
||||||
|
./cal -y | head -10 | tr ' ' . #3 spaces
|
||||||
|
./cal -3 | tr ' ' . #2 spaces ?
|
|
@ -46,7 +46,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h> /* for isdigit() */
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include "kill.h"
|
#include "kill.h"
|
||||||
|
|
|
@ -1,319 +0,0 @@
|
||||||
diff -uNr util-linux-2.12/mount/get_label_uuid.c ../patch/util-linux-2.12/mount/get_label_uuid.c
|
|
||||||
--- util-linux-2.12/mount/get_label_uuid.c 2002-11-26 12:18:01.000000000 +0100
|
|
||||||
+++ ../patch/util-linux-2.12/mount/get_label_uuid.c 2003-10-20 18:27:56.000000000 +0200
|
|
||||||
@@ -43,7 +43,139 @@
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
-/* for now, only ext2, ext3, xfs, ocfs are supported */
|
|
||||||
+/* Remove trailing spaces */
|
|
||||||
+static void remtrailspc(char *label) {
|
|
||||||
+ char *c;
|
|
||||||
+
|
|
||||||
+ c = strchr(label, 0)-1;
|
|
||||||
+ while (c >= label && *c == ' ')
|
|
||||||
+ *(c--) = 0;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int handle_fat_dirent(struct fat_dirent *dirent, char **label) {
|
|
||||||
+ size_t namesize;
|
|
||||||
+
|
|
||||||
+ /* end-of-directory marker */
|
|
||||||
+ if (!dirent->s_filename[0])
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ /* valid volume label */
|
|
||||||
+ if ((dirent->s_attr == 0x08 || dirent->s_attr == 0x28) && dirent->s_filename[0] != 0xe5) {
|
|
||||||
+
|
|
||||||
+ /* sanity check */
|
|
||||||
+ if (dirent->s_size[0] || dirent->s_size[1] || dirent->s_size[2] || dirent->s_size[3] ||
|
|
||||||
+ dirent->s_cluster[0] || dirent->s_cluster[1])
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ namesize = sizeof(dirent->s_filename);
|
|
||||||
+ if (!(*label = calloc(namesize + 1, 1)))
|
|
||||||
+ return -1;
|
|
||||||
+ memcpy(*label, dirent->s_filename, namesize);
|
|
||||||
+ (*label)[namesize] = 0;
|
|
||||||
+ remtrailspc(*label);
|
|
||||||
+
|
|
||||||
+ return 0;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return 1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int read_volume_label_fat(int fd, struct fat_super_block *fatsb, char **label) {
|
|
||||||
+ unsigned i, m;
|
|
||||||
+ off_t o;
|
|
||||||
+
|
|
||||||
+ m = assemble2le(fatsb->s_dirents); /* root directory entries */
|
|
||||||
+
|
|
||||||
+ o = (off_t) assemble2le(fatsb->s_ssec) * /* bytes per sector */
|
|
||||||
+ ((off_t) assemble2le(fatsb->s_rsecs) + /* reserved sectors */
|
|
||||||
+ (off_t) assemble2le(fatsb->s_spfat) * /* sectors per fat */
|
|
||||||
+ (off_t) fatsb->s_nfats); /* number of fats */
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < m; i++) {
|
|
||||||
+ struct fat_dirent dirent;
|
|
||||||
+ int rv;
|
|
||||||
+
|
|
||||||
+ if (lseek(fd, o, SEEK_SET) != o ||
|
|
||||||
+ read(fd, &dirent, sizeof(dirent)) != sizeof(dirent))
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ if ((rv = handle_fat_dirent(&dirent, label)) != 1)
|
|
||||||
+ return rv;
|
|
||||||
+
|
|
||||||
+ o += sizeof(dirent);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ return -1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+static int read_volume_label_fat32(int fd, struct fat32_super_block *fat32sb, char **label) {
|
|
||||||
+ unsigned c;
|
|
||||||
+ off_t fo, b, o;
|
|
||||||
+ int i, ifat;
|
|
||||||
+ size_t m, cs;
|
|
||||||
+
|
|
||||||
+ ifat = fat32sb->s_mirror[0] & 128 ? (fat32sb->s_mirror[0] & 0xF) : 0;
|
|
||||||
+
|
|
||||||
+ if (ifat >= fat32sb->s_nfats)
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ fo = (off_t) assemble2le(fat32sb->s_ssec) * /* bytes per sector */
|
|
||||||
+ ((off_t) assemble2le(fat32sb->s_rsecs) + /* reserved sectors */
|
|
||||||
+ (off_t) assemble4le(fat32sb->s_spfat) * /* sectors per fat */
|
|
||||||
+ (off_t) ifat); /* number of FAT used */
|
|
||||||
+
|
|
||||||
+ b = (off_t) assemble2le(fat32sb->s_ssec) * /* bytes per sector */
|
|
||||||
+ ((off_t) assemble2le(fat32sb->s_rsecs) + /* reserved sectors */
|
|
||||||
+ (off_t) assemble4le(fat32sb->s_spfat) * /* sectors per fat */
|
|
||||||
+ (off_t) fat32sb->s_nfats); /* number of FATs */
|
|
||||||
+
|
|
||||||
+ c = assemble4le(fat32sb->s_rcluster) & 0x0fffffffL;
|
|
||||||
+ if (c < 2 || c >= 0x0ffffff0)
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ m = cs = assemble2le(fat32sb->s_ssec) * (size_t) fat32sb->s_scluster;
|
|
||||||
+ o = b + (off_t) cs*(c-2);
|
|
||||||
+
|
|
||||||
+ for (i = 0; i < 0xFFFF; i++) { /* safety against DoS attack */
|
|
||||||
+ struct fat_dirent dirent;
|
|
||||||
+ int rv;
|
|
||||||
+
|
|
||||||
+ if (lseek(fd, o, SEEK_SET) != o ||
|
|
||||||
+ read(fd, &dirent, sizeof(dirent)) != sizeof(dirent))
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ if ((rv = handle_fat_dirent(&dirent, label)) != 1)
|
|
||||||
+ return rv;
|
|
||||||
+
|
|
||||||
+ if (m > sizeof(dirent)) {
|
|
||||||
+ m -= sizeof(dirent);
|
|
||||||
+ o += sizeof(dirent);
|
|
||||||
+ } else {
|
|
||||||
+ off_t d;
|
|
||||||
+
|
|
||||||
+ /* next cluster */
|
|
||||||
+
|
|
||||||
+ d = fo+4*c;
|
|
||||||
+ if (lseek(fd, d, SEEK_SET) != d ||
|
|
||||||
+ read(fd, &c, 4) != 4)
|
|
||||||
+ return -1;
|
|
||||||
+
|
|
||||||
+ c = assemble4le((char*) &c) & 0x0fffffffL;
|
|
||||||
+ if (c < 2 || c >= 0x0ffffff0) {
|
|
||||||
+ return -1;
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ m = cs;
|
|
||||||
+ o = b + cs*(c-2);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+ return -1;
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+
|
|
||||||
+/* for now, only ext2, ext3, xfs, ocfs, fat, fat32 are supported */
|
|
||||||
int
|
|
||||||
get_label_uuid(const char *device, char **label, char *uuid) {
|
|
||||||
int fd;
|
|
||||||
@@ -54,8 +186,10 @@
|
|
||||||
struct jfs_super_block jfssb;
|
|
||||||
struct ocfs_volume_header ovh; /* Oracle */
|
|
||||||
struct ocfs_volume_label olbl;
|
|
||||||
+ struct fat_super_block fatsb;
|
|
||||||
+ struct fat32_super_block fat32sb;
|
|
||||||
|
|
||||||
- fd = open(device, O_RDONLY);
|
|
||||||
+ fd = open(device, O_RDONLY);
|
|
||||||
if (fd < 0)
|
|
||||||
return rv;
|
|
||||||
|
|
||||||
@@ -111,7 +245,87 @@
|
|
||||||
memcpy(*label, jfssb.s_label, namesize);
|
|
||||||
}
|
|
||||||
rv = 0;
|
|
||||||
- }
|
|
||||||
+ } else if (lseek(fd, 0, SEEK_SET) == 0
|
|
||||||
+ && read(fd, (char*) &fat32sb, sizeof(fat32sb)) == sizeof(fat32sb)
|
|
||||||
+ && fat32sb.s_sig[0] == 0x55
|
|
||||||
+ && fat32sb.s_sig[1] == 0xAA
|
|
||||||
+ && (fat32sb.s_media & 0xF0) == 0xF0
|
|
||||||
+ && (fat32sb.s_spfat_old[0] == 0)
|
|
||||||
+ && (fat32sb.s_spfat_old[1] == 0)
|
|
||||||
+ && fat32sb.s_extsig == 0x29
|
|
||||||
+ && (memcmp(fat32sb.s_fs, "FAT32 ", 8) == 0)) {
|
|
||||||
+
|
|
||||||
+ *label = NULL;
|
|
||||||
+
|
|
||||||
+ /* If no root directory entry volume name was found use the one from the boot sector */
|
|
||||||
+ if (read_volume_label_fat32(fd, &fat32sb, label) != 0) {
|
|
||||||
+ if (memcmp(fat32sb.s_label, "NO NAME ", 11) != 0 &&
|
|
||||||
+ memcmp(fat32sb.s_label, " ", 11) != 0 &&
|
|
||||||
+ memcmp(fat32sb.s_label, "\0\0\0\0\0\0\0\0", 8) != 0) {
|
|
||||||
+
|
|
||||||
+ namesize = sizeof(fat32sb.s_label);
|
|
||||||
+ if ((*label = calloc(namesize + 1, 1)) != NULL) {
|
|
||||||
+ memcpy(*label, fat32sb.s_label, namesize);
|
|
||||||
+ (*label)[namesize] = 0;
|
|
||||||
+ remtrailspc(*label);
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (*label) {
|
|
||||||
+
|
|
||||||
+ /* Set UUID from serial */
|
|
||||||
+ uuid[0] = fat32sb.s_serial[3];
|
|
||||||
+ uuid[1] = fat32sb.s_serial[2];
|
|
||||||
+ uuid[2] = fat32sb.s_serial[1];
|
|
||||||
+ uuid[3] = fat32sb.s_serial[0];
|
|
||||||
+ memset(uuid+4, 0, 12);
|
|
||||||
+
|
|
||||||
+ rv = 0;
|
|
||||||
+ }
|
|
||||||
+ } else if (lseek(fd, 0, SEEK_SET) == 0
|
|
||||||
+ && read(fd, (char*) &fatsb, sizeof(fatsb)) == sizeof(fatsb)
|
|
||||||
+ && fatsb.s_sig[0] == 0x55
|
|
||||||
+ && fatsb.s_sig[1] == 0xAA
|
|
||||||
+ && (fatsb.s_media & 0xF0) == 0xF0
|
|
||||||
+ && fatsb.s_extsig == 0x29
|
|
||||||
+ && (memcmp(fatsb.s_fs, "FAT12 ", 8) == 0
|
|
||||||
+ || memcmp(fatsb.s_fs, "FAT16 ", 8) == 0
|
|
||||||
+ || memcmp(fatsb.s_fs, "FAT ", 8) == 0
|
|
||||||
+ || memcmp(fatsb.s_fs, "\0\0\0\0\0\0\0\0", 8) == 0)
|
|
||||||
+ && memcmp(fatsb.s_fs2, "FAT32 ", 8) != 0) {
|
|
||||||
+
|
|
||||||
+ *label = NULL;
|
|
||||||
+
|
|
||||||
+ if (read_volume_label_fat(fd, &fatsb, label) != 0) {
|
|
||||||
+
|
|
||||||
+ /* If no root directory entry volume name was found use the one from the boot sector */
|
|
||||||
+ if (memcmp(fatsb.s_label, "NO NAME ", 11) != 0 &&
|
|
||||||
+ memcmp(fatsb.s_label, " ", 11) != 0 &&
|
|
||||||
+ memcmp(fatsb.s_label, "\0\0\0\0\0\0\0\0", 8) != 0) {
|
|
||||||
+
|
|
||||||
+ namesize = sizeof(fatsb.s_label);
|
|
||||||
+ if ((*label = calloc(namesize + 1, 1)) != NULL) {
|
|
||||||
+ memcpy(*label, fatsb.s_label, namesize);
|
|
||||||
+ (*label)[namesize] = 0;
|
|
||||||
+ remtrailspc(*label);
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+
|
|
||||||
+ if (*label) {
|
|
||||||
+
|
|
||||||
+ /* Set UUID from serial */
|
|
||||||
+ uuid[0] = fatsb.s_serial[3];
|
|
||||||
+ uuid[1] = fatsb.s_serial[2];
|
|
||||||
+ uuid[2] = fatsb.s_serial[1];
|
|
||||||
+ uuid[3] = fatsb.s_serial[0];
|
|
||||||
+ memset(uuid+4, 0, 12);
|
|
||||||
+
|
|
||||||
+ rv = 0;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return rv;
|
|
||||||
diff -uNr util-linux-2.12/mount/linux_fs.h ../patch/util-linux-2.12/mount/linux_fs.h
|
|
||||||
--- util-linux-2.12/mount/linux_fs.h 2003-07-05 22:16:32.000000000 +0200
|
|
||||||
+++ ../patch/util-linux-2.12/mount/linux_fs.h 2003-10-20 18:07:06.000000000 +0200
|
|
||||||
@@ -122,13 +122,65 @@
|
|
||||||
u_char s_dummy[3];
|
|
||||||
u_char s_os[8]; /* "MSDOS5.0" or "MSWIN4.0" or "MSWIN4.1" */
|
|
||||||
/* mtools-3.9.4 writes "MTOOL394" */
|
|
||||||
- u_char s_dummy2[32];
|
|
||||||
+ u_char s_ssec[2]; /* bytes per sector */
|
|
||||||
+ u_char s_scluster; /* sectors per cluster */
|
|
||||||
+ u_char s_rsecs[2]; /* reserved sectors */
|
|
||||||
+ u_char s_nfats; /* number of FATs */
|
|
||||||
+ u_char s_dirents[2]; /* maximum root directory entries */
|
|
||||||
+ u_char s_nsecs[2]; /* total number of sectors */
|
|
||||||
+ u_char s_media; /* media type, upper nibble is 0xF */
|
|
||||||
+ u_char s_spfat[2]; /* sectors per fat */
|
|
||||||
+
|
|
||||||
+ u_char s_dummy2[14];
|
|
||||||
+ u_char s_extsig; /* extended signature */
|
|
||||||
+ u_char s_serial[4]; /* serial number */
|
|
||||||
u_char s_label[11]; /* for DOS? */
|
|
||||||
- u_char s_fs[8]; /* "FAT12 " or "FAT16 " or all zero */
|
|
||||||
+ u_char s_fs[8]; /* "FAT12 " or "FAT16 " or all zero */
|
|
||||||
/* OS/2 BM has "FAT " here. */
|
|
||||||
- u_char s_dummy3[9];
|
|
||||||
- u_char s_label2[11]; /* for Windows? */
|
|
||||||
- u_char s_fs2[8]; /* garbage or "FAT32 " */
|
|
||||||
+
|
|
||||||
+ u_char s_dummy3[20];
|
|
||||||
+ u_char s_fs2[8]; /* "FAT32 " */
|
|
||||||
+
|
|
||||||
+ u_char s_dummy4[420];
|
|
||||||
+ u_char s_sig[2]; /* 55 AA */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+struct fat32_super_block {
|
|
||||||
+ u_char s_dummy[3];
|
|
||||||
+ u_char s_os[8]; /* "MSDOS5.0" or "MSWIN4.0" or "MSWIN4.1" */
|
|
||||||
+ /* mtools-3.9.4 writes "MTOOL394" */
|
|
||||||
+
|
|
||||||
+ u_char s_ssec[2]; /* bytes per sector */
|
|
||||||
+ u_char s_scluster; /* sectors per cluster */
|
|
||||||
+ u_char s_rsecs[2]; /* reserved sectors */
|
|
||||||
+ u_char s_nfats; /* number of FATs */
|
|
||||||
+ u_char s_dirents[2]; /* maximum root directory entries */
|
|
||||||
+ u_char s_nsecs[2]; /* total number of sectors */
|
|
||||||
+ u_char s_media; /* media type, upper nibble is 0xF */
|
|
||||||
+ u_char s_spfat_old[2]; /* sectors per fat */
|
|
||||||
+
|
|
||||||
+ u_char s_dummy2[12];
|
|
||||||
+ u_char s_spfat[4]; /* sectors per FAT */
|
|
||||||
+ u_char s_mirror[2]; /* mirror flag */
|
|
||||||
+ u_char s_version[2]; /* fs version */
|
|
||||||
+ u_char s_rcluster[4]; /* root directory cluster */
|
|
||||||
+
|
|
||||||
+ u_char s_dummy3[18];
|
|
||||||
+ u_char s_extsig; /* extended signature 0x29 */
|
|
||||||
+ u_char s_serial[4]; /* serial number */
|
|
||||||
+ u_char s_label[11]; /* label */
|
|
||||||
+ u_char s_fs[8]; /* filesystem type "FAT32 " */
|
|
||||||
+
|
|
||||||
+ u_char s_dummy4[420];
|
|
||||||
+ u_char s_sig[2]; /* 55 AA */
|
|
||||||
+};
|
|
||||||
+
|
|
||||||
+struct fat_dirent {
|
|
||||||
+ u_char s_filename[11]; /* Filename with extension */
|
|
||||||
+ u_char s_attr; /* File attribute flags */
|
|
||||||
+ u_char s_dummy[14];
|
|
||||||
+ u_char s_cluster[2]; /* Starting cluster */
|
|
||||||
+ u_char s_size[4]; /* File size */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define XFS_SUPER_MAGIC "XFSB"
|
|
|
@ -105,7 +105,7 @@ static void
|
||||||
discard_mntentchn(struct mntentchn *mc0) {
|
discard_mntentchn(struct mntentchn *mc0) {
|
||||||
struct mntentchn *mc, *mc1;
|
struct mntentchn *mc, *mc1;
|
||||||
|
|
||||||
for (mc = mc0->nxt; mc != mc0; mc = mc1) {
|
for (mc = mc0->nxt; mc && mc != mc0; mc = mc1) {
|
||||||
mc1 = mc->nxt;
|
mc1 = mc->nxt;
|
||||||
my_free(mc->m.mnt_fsname);
|
my_free(mc->m.mnt_fsname);
|
||||||
my_free(mc->m.mnt_dir);
|
my_free(mc->m.mnt_dir);
|
||||||
|
|
126
mount/lomount.c
126
mount/lomount.c
|
@ -1,17 +1,4 @@
|
||||||
/* Taken from Ted's losetup.c - Mitch <m.dsouza@mrc-apu.cam.ac.uk> */
|
/* Originally from Ted's losetup.c */
|
||||||
/* Added vfs mount options - aeb - 960223 */
|
|
||||||
/* Removed lomount - aeb - 960224 */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
|
|
||||||
* - added Native Language Support
|
|
||||||
* 1999-03-21 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
|
|
||||||
* - fixed strerr(errno) in gettext calls
|
|
||||||
* 2000-09-24 Marc Mutz <Marc@Mutz.com>
|
|
||||||
* - added -p option to pass passphrases via fd's to losetup/mount.
|
|
||||||
* Used for encryption in non-interactive environments.
|
|
||||||
* The idea behind xgetpass() is stolen from GnuPG, v.1.0.3.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define LOOPMAJOR 7
|
#define LOOPMAJOR 7
|
||||||
|
|
||||||
|
@ -37,6 +24,7 @@
|
||||||
#include "nls.h"
|
#include "nls.h"
|
||||||
|
|
||||||
extern int verbose;
|
extern int verbose;
|
||||||
|
extern char *progname;
|
||||||
extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
|
extern char *xstrdup (const char *s); /* not: #include "sundries.h" */
|
||||||
extern void error (const char *fmt, ...); /* idem */
|
extern void error (const char *fmt, ...); /* idem */
|
||||||
|
|
||||||
|
@ -186,15 +174,15 @@ find_unused_loop_device (void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!somedev)
|
if (!somedev)
|
||||||
error(_("mount: could not find any device /dev/loop#"));
|
error(_("%s: could not find any device /dev/loop#"), progname);
|
||||||
else if (!someloop) {
|
else if (!someloop)
|
||||||
error(_(
|
error(_(
|
||||||
"mount: Could not find any loop device. Maybe this kernel "
|
"%s: Could not find any loop device. Maybe this kernel "
|
||||||
"does not know\n"
|
"does not know\n"
|
||||||
" about the loop device? (If so, recompile or "
|
" about the loop device? (If so, recompile or "
|
||||||
"`modprobe loop'.)"));
|
"`modprobe loop'.)"), progname);
|
||||||
} else
|
else
|
||||||
error(_("mount: could not find any free loop device"));
|
error(_("%s: could not find any free loop device"), progname);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,15 +214,16 @@ xgetpass(int pfd, const char *prompt) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (read(pfd, pass+i, 1) != 1 || pass[i] == '\n')
|
if (read(pfd, pass+i, 1) != 1 ||
|
||||||
|
pass[i] == '\n' || pass[i] == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pass == NULL)
|
if (pass == NULL)
|
||||||
return "";
|
return "";
|
||||||
else {
|
|
||||||
pass[i] = 0;
|
pass[i] = 0;
|
||||||
return pass;
|
return pass;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -249,7 +238,7 @@ int
|
||||||
set_loop(const char *device, const char *file, unsigned long long offset,
|
set_loop(const char *device, const char *file, unsigned long long offset,
|
||||||
const char *encryption, int pfd, int *loopro) {
|
const char *encryption, int pfd, int *loopro) {
|
||||||
struct loop_info64 loopinfo64;
|
struct loop_info64 loopinfo64;
|
||||||
int fd, ffd, mode, i;
|
int fd, ffd, mode, i, n;
|
||||||
char *pass;
|
char *pass;
|
||||||
|
|
||||||
mode = (*loopro ? O_RDONLY : O_RDWR);
|
mode = (*loopro ? O_RDONLY : O_RDWR);
|
||||||
|
@ -302,16 +291,15 @@ set_loop(const char *device, const char *file, unsigned long long offset,
|
||||||
break;
|
break;
|
||||||
case LO_CRYPT_XOR:
|
case LO_CRYPT_XOR:
|
||||||
pass = getpass(_("Password: "));
|
pass = getpass(_("Password: "));
|
||||||
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
goto gotpass;
|
||||||
memset(pass, 0, strlen(pass));
|
|
||||||
loopinfo64.lo_encrypt_key_size =
|
|
||||||
strlen(loopinfo64.lo_encrypt_key);
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
pass = xgetpass(pfd, _("Password: "));
|
pass = xgetpass(pfd, _("Password: "));
|
||||||
|
gotpass:
|
||||||
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
xstrncpy(loopinfo64.lo_encrypt_key, pass, LO_KEY_SIZE);
|
||||||
memset(pass, 0, strlen(pass));
|
n = strlen(pass);
|
||||||
loopinfo64.lo_encrypt_key_size = LO_KEY_SIZE;
|
memset(pass, 0, n);
|
||||||
|
loopinfo64.lo_encrypt_key_size =
|
||||||
|
(n < LO_KEY_SIZE) ? n : LO_KEY_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
|
if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
|
||||||
|
@ -413,10 +401,11 @@ static char *progname;
|
||||||
static void
|
static void
|
||||||
usage(void) {
|
usage(void) {
|
||||||
fprintf(stderr, _("usage:\n\
|
fprintf(stderr, _("usage:\n\
|
||||||
%s loop_device # give info\n\
|
%s loop_device # give info\n\
|
||||||
%s -d loop_device # delete\n\
|
%s -d loop_device # delete\n\
|
||||||
%s [ -e encryption ] [ -o offset ] loop_device file # setup\n"),
|
%s -f # find unused\n\
|
||||||
progname, progname, progname);
|
%s [-e encryption] [-o offset] {-f|loop_device} file # setup\n"),
|
||||||
|
progname, progname, progname, progname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,8 +438,8 @@ error (const char *fmt, ...) {
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv) {
|
main(int argc, char **argv) {
|
||||||
char *offset, *encryption, *passfd;
|
char *p, *offset, *encryption, *passfd, *device, *file;
|
||||||
int delete, c;
|
int delete, find, c;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
int ro = 0;
|
int ro = 0;
|
||||||
int pfd = -1;
|
int pfd = -1;
|
||||||
|
@ -460,10 +449,15 @@ main(int argc, char **argv) {
|
||||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
textdomain(PACKAGE);
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
delete = off = 0;
|
delete = find = 0;
|
||||||
|
off = 0;
|
||||||
offset = encryption = passfd = NULL;
|
offset = encryption = passfd = NULL;
|
||||||
|
|
||||||
progname = argv[0];
|
progname = argv[0];
|
||||||
while ((c = getopt(argc,argv,"de:E:o:p:v")) != -1) {
|
if ((p = strrchr(progname, '/')) != NULL)
|
||||||
|
progname = p+1;
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, "de:E:fo:p:v")) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'd':
|
case 'd':
|
||||||
delete = 1;
|
delete = 1;
|
||||||
|
@ -472,6 +466,9 @@ main(int argc, char **argv) {
|
||||||
case 'e':
|
case 'e':
|
||||||
encryption = optarg;
|
encryption = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
find = 1;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
offset = optarg;
|
offset = optarg;
|
||||||
break;
|
break;
|
||||||
|
@ -485,22 +482,49 @@ main(int argc, char **argv) {
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (argc == 1) usage();
|
|
||||||
if ((delete && (argc != optind+1 || encryption || offset)) ||
|
if (argc == 1) {
|
||||||
(!delete && (argc < optind+1 || argc > optind+2)))
|
|
||||||
usage();
|
usage();
|
||||||
if (argc == optind+1) {
|
} else if (delete) {
|
||||||
if (delete)
|
if (argc != optind+1 || encryption || offset || find)
|
||||||
res = del_loop(argv[optind]);
|
usage();
|
||||||
else
|
} else if (find) {
|
||||||
res = show_loop(argv[optind]);
|
if (argc < optind || argc > optind+1)
|
||||||
|
usage();
|
||||||
} else {
|
} else {
|
||||||
|
if (argc < optind+1 || argc > optind+2)
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (find) {
|
||||||
|
device = find_unused_loop_device();
|
||||||
|
if (device == NULL)
|
||||||
|
return -1;
|
||||||
|
if (verbose)
|
||||||
|
printf("Loop device is %s\n", device);
|
||||||
|
if (argc == optind) {
|
||||||
|
printf("%s\n", device);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
file = argv[optind];
|
||||||
|
} else {
|
||||||
|
device = argv[optind];
|
||||||
|
if (argc == optind+1)
|
||||||
|
file = NULL;
|
||||||
|
else
|
||||||
|
file = argv[optind+1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (delete)
|
||||||
|
res = del_loop(device);
|
||||||
|
else if (file == NULL)
|
||||||
|
res = show_loop(device);
|
||||||
|
else {
|
||||||
if (offset && sscanf(offset, "%llu", &off) != 1)
|
if (offset && sscanf(offset, "%llu", &off) != 1)
|
||||||
usage();
|
usage();
|
||||||
if (passfd && sscanf(passfd, "%d", &pfd) != 1)
|
if (passfd && sscanf(passfd, "%d", &pfd) != 1)
|
||||||
usage();
|
usage();
|
||||||
res = set_loop(argv[optind], argv[optind+1], off,
|
res = set_loop(device, file, off, encryption, pfd, &ro);
|
||||||
encryption, pfd, &ro);
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,24 +3,40 @@
|
||||||
losetup \- set up and control loop devices
|
losetup \- set up and control loop devices
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.ad l
|
.ad l
|
||||||
|
Get info:
|
||||||
|
.sp
|
||||||
|
.in +5
|
||||||
.B losetup
|
.B losetup
|
||||||
[
|
|
||||||
.RB [ \-e | \-E ]
|
|
||||||
.I encryption
|
|
||||||
] [
|
|
||||||
.B \-o
|
|
||||||
.I offset
|
|
||||||
] [
|
|
||||||
.B \-p
|
|
||||||
.I pfd
|
|
||||||
]
|
|
||||||
.I loop_device file
|
|
||||||
.br
|
|
||||||
.B losetup
|
|
||||||
[
|
|
||||||
.B \-d
|
|
||||||
]
|
|
||||||
.I loop_device
|
.I loop_device
|
||||||
|
.sp
|
||||||
|
.in -5
|
||||||
|
Delete loop:
|
||||||
|
.sp
|
||||||
|
.in +5
|
||||||
|
.B "losetup \-d"
|
||||||
|
.I loop_device
|
||||||
|
.sp
|
||||||
|
.in -5
|
||||||
|
Print name of first unused loop device:
|
||||||
|
.sp
|
||||||
|
.in +5
|
||||||
|
.B "losetup \-f"
|
||||||
|
.sp
|
||||||
|
.in -5
|
||||||
|
Setup loop device:
|
||||||
|
.sp
|
||||||
|
.in +5
|
||||||
|
.B losetup
|
||||||
|
.RB [{\-e | \-E}
|
||||||
|
.IR encryption ]
|
||||||
|
.RB [ \-o
|
||||||
|
.IR offset ]
|
||||||
|
.RB [ \-p
|
||||||
|
.IR pfd ]
|
||||||
|
.in +8
|
||||||
|
.RB { \-f | \fIloop_device\fP }
|
||||||
|
.I file
|
||||||
|
.in -13
|
||||||
.ad b
|
.ad b
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
.B losetup
|
.B losetup
|
||||||
|
@ -56,6 +72,10 @@ Detach the file or device associated with the specified loop device.
|
||||||
Enable data encryption with specified number.
|
Enable data encryption with specified number.
|
||||||
.IP "\fB\-e \fIencryption_name\fP"
|
.IP "\fB\-e \fIencryption_name\fP"
|
||||||
Enable data encryption with specified name.
|
Enable data encryption with specified name.
|
||||||
|
.IP "\fB\-f\fP"
|
||||||
|
Find the first unused loop device. If a
|
||||||
|
.I file
|
||||||
|
argument is present, use this device. Otherwise, print its name.
|
||||||
.IP "\fB\-o \fIoffset\fP"
|
.IP "\fB\-o \fIoffset\fP"
|
||||||
The data start is moved \fIoffset\fP bytes into the specified file or
|
The data start is moved \fIoffset\fP bytes into the specified file or
|
||||||
device.
|
device.
|
||||||
|
|
|
@ -216,6 +216,10 @@ option, with the restriction that the user must be the owner
|
||||||
of the special file. This may be useful e.g. for
|
of the special file. This may be useful e.g. for
|
||||||
.I /dev/fd
|
.I /dev/fd
|
||||||
if a login script makes the console user owner of this device.
|
if a login script makes the console user owner of this device.
|
||||||
|
The
|
||||||
|
.B group
|
||||||
|
option is similar, with the restriction that the user must be
|
||||||
|
member of the group of the special file.
|
||||||
|
|
||||||
The programs
|
The programs
|
||||||
.B mount
|
.B mount
|
||||||
|
@ -551,6 +555,14 @@ Interpret character or block special devices on the file system.
|
||||||
.B exec
|
.B exec
|
||||||
Permit execution of binaries.
|
Permit execution of binaries.
|
||||||
.TP
|
.TP
|
||||||
|
.B group
|
||||||
|
Allow an ordinary (i.e., non-root) user to mount the file system if one
|
||||||
|
of his groups matches the group of the device.
|
||||||
|
This option implies the options
|
||||||
|
.BR nosuid " and " nodev
|
||||||
|
(unless overridden by subsequent options, as in the option line
|
||||||
|
.BR group,dev,suid ).
|
||||||
|
.TP
|
||||||
.B _netdev
|
.B _netdev
|
||||||
The filesystem resides on a device that requires network access
|
The filesystem resides on a device that requires network access
|
||||||
(used to prevent the system from attempting to mount these filesystems
|
(used to prevent the system from attempting to mount these filesystems
|
||||||
|
@ -583,6 +595,14 @@ suidperl(1) installed.)
|
||||||
Forbid an ordinary (i.e., non-root) user to mount the file system.
|
Forbid an ordinary (i.e., non-root) user to mount the file system.
|
||||||
This is the default.
|
This is the default.
|
||||||
.TP
|
.TP
|
||||||
|
.B owner
|
||||||
|
Allow an ordinary (i.e., non-root) user to mount the file system if he
|
||||||
|
is the owner of the device.
|
||||||
|
This option implies the options
|
||||||
|
.BR nosuid " and " nodev
|
||||||
|
(unless overridden by subsequent options, as in the option line
|
||||||
|
.BR owner,dev,suid ).
|
||||||
|
.TP
|
||||||
.B remount
|
.B remount
|
||||||
Attempt to remount an already-mounted file system. This is commonly
|
Attempt to remount an already-mounted file system. This is commonly
|
||||||
used to change the mount flags for a file system, especially to make a
|
used to change the mount flags for a file system, especially to make a
|
||||||
|
|
171
mount/mount.c
171
mount/mount.c
|
@ -96,6 +96,7 @@ struct opt_map {
|
||||||
#define MS_USERS 0x40000000
|
#define MS_USERS 0x40000000
|
||||||
#define MS_USER 0x20000000
|
#define MS_USER 0x20000000
|
||||||
#define MS_OWNER 0x10000000
|
#define MS_OWNER 0x10000000
|
||||||
|
#define MS_GROUP 0x08000000
|
||||||
#define MS_COMMENT 0x00020000
|
#define MS_COMMENT 0x00020000
|
||||||
#define MS_LOOP 0x00010000
|
#define MS_LOOP 0x00010000
|
||||||
|
|
||||||
|
@ -135,6 +136,8 @@ static const struct opt_map opt_map[] = {
|
||||||
{ "nouser", 0, 1, MS_USER }, /* Forbid ordinary user to mount */
|
{ "nouser", 0, 1, MS_USER }, /* Forbid ordinary user to mount */
|
||||||
{ "owner", 0, 0, MS_OWNER }, /* Let the owner of the device mount */
|
{ "owner", 0, 0, MS_OWNER }, /* Let the owner of the device mount */
|
||||||
{ "noowner", 0, 1, MS_OWNER }, /* Device owner has no special privs */
|
{ "noowner", 0, 1, MS_OWNER }, /* Device owner has no special privs */
|
||||||
|
{ "group", 0, 0, MS_GROUP }, /* Let the group of the device mount */
|
||||||
|
{ "nogroup", 0, 1, MS_GROUP }, /* Device group has no special privs */
|
||||||
{ "_netdev", 0, 0, MS_COMMENT}, /* Device requires network */
|
{ "_netdev", 0, 0, MS_COMMENT}, /* Device requires network */
|
||||||
{ "comment", 0, 0, MS_COMMENT}, /* fstab comment only (kudzu,_netdev)*/
|
{ "comment", 0, 0, MS_COMMENT}, /* fstab comment only (kudzu,_netdev)*/
|
||||||
|
|
||||||
|
@ -263,7 +266,8 @@ parse_opt (const char *opt, int *mask, char *extra_opts) {
|
||||||
if ((om->mask == MS_USER || om->mask == MS_USERS)
|
if ((om->mask == MS_USER || om->mask == MS_USERS)
|
||||||
&& !om->inv)
|
&& !om->inv)
|
||||||
*mask |= MS_SECURE;
|
*mask |= MS_SECURE;
|
||||||
if ((om->mask == MS_OWNER) && !om->inv)
|
if ((om->mask == MS_OWNER || om->mask == MS_GROUP)
|
||||||
|
&& !om->inv)
|
||||||
*mask |= MS_OWNERSECURE;
|
*mask |= MS_OWNERSECURE;
|
||||||
#ifdef MS_SILENT
|
#ifdef MS_SILENT
|
||||||
if (om->mask == MS_SILENT && om->inv) {
|
if (om->mask == MS_SILENT && om->inv) {
|
||||||
|
@ -507,20 +511,47 @@ guess_fstype_and_mount(const char *spec, const char *node, const char **types,
|
||||||
static void
|
static void
|
||||||
suid_check(const char *spec, const char *node, int *flags, char **user) {
|
suid_check(const char *spec, const char *node, int *flags, char **user) {
|
||||||
if (suid) {
|
if (suid) {
|
||||||
/* RedHat patch: allow owners to mount when fstab contains
|
/*
|
||||||
the owner option. Note that this should never be used
|
* MS_OWNER: Allow owners to mount when fstab contains
|
||||||
in a high security environment, but may be useful to give
|
* the owner option. Note that this should never be used
|
||||||
people at the console the possibility of mounting a floppy. */
|
* in a high security environment, but may be useful to give
|
||||||
if (*flags & MS_OWNER) {
|
* people at the console the possibility of mounting a floppy.
|
||||||
if (!strncmp(spec, "/dev/", 5)) {
|
* MS_GROUP: Allow members of device group to mount. (Martin Dickopp)
|
||||||
struct stat sb;
|
*/
|
||||||
|
if (*flags & (MS_OWNER | MS_GROUP)) {
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
if (!stat(spec, &sb)) {
|
if (!strncmp(spec, "/dev/", 5) && stat(spec, &sb) == 0) {
|
||||||
|
|
||||||
|
if (*flags & MS_OWNER) {
|
||||||
if (getuid() == sb.st_uid)
|
if (getuid() == sb.st_uid)
|
||||||
*flags |= MS_USER;
|
*flags |= MS_USER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (*flags & MS_GROUP) {
|
||||||
|
if (getgid() == sb.st_gid)
|
||||||
|
*flags |= MS_USER;
|
||||||
|
else {
|
||||||
|
int n = getgroups(0, NULL);
|
||||||
|
|
||||||
|
if (n > 0) {
|
||||||
|
gid_t *groups = xmalloc(n * sizeof(*groups));
|
||||||
|
if (getgroups(n, groups) == n) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
if (groups[i] == sb.st_gid) {
|
||||||
|
*flags |= MS_USER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(groups);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* James Kehl <mkehl@gil.com.au> came with a similar patch:
|
/* James Kehl <mkehl@gil.com.au> came with a similar patch:
|
||||||
allow an arbitrary user to mount when he is the owner of
|
allow an arbitrary user to mount when he is the owner of
|
||||||
the mount-point and has write-access to the device.
|
the mount-point and has write-access to the device.
|
||||||
|
@ -537,8 +568,7 @@ suid_check(const char *spec, const char *node, int *flags, char **user) {
|
||||||
*user = getusername();
|
*user = getusername();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*flags & MS_OWNER)
|
*flags &= ~(MS_OWNER | MS_GROUP);
|
||||||
*flags &= ~MS_OWNER;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -927,13 +957,13 @@ retry_nfs:
|
||||||
error (_("mount: %s not mounted already, or bad option"), node);
|
error (_("mount: %s not mounted already, or bad option"), node);
|
||||||
} else {
|
} else {
|
||||||
error (_("mount: wrong fs type, bad option, bad superblock on %s,\n"
|
error (_("mount: wrong fs type, bad option, bad superblock on %s,\n"
|
||||||
" or too many mounted file systems"),
|
" missing codepage, or too many mounted file systems"),
|
||||||
spec);
|
spec);
|
||||||
|
|
||||||
if (stat(spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
|
if (stat(spec, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)
|
||||||
&& (fd = open(spec, O_RDONLY | O_NONBLOCK)) >= 0) {
|
&& (fd = open(spec, O_RDONLY | O_NONBLOCK)) >= 0) {
|
||||||
if (ioctl(fd, BLKGETSIZE, &size) == 0) {
|
if (ioctl(fd, BLKGETSIZE, &size) == 0) {
|
||||||
if (size == 0) {
|
if (size == 0 && !loop) {
|
||||||
warned++;
|
warned++;
|
||||||
error (" (could this be the IDE device where you in fact use\n"
|
error (" (could this be the IDE device where you in fact use\n"
|
||||||
" ide-scsi so that sr0 or sda or so is needed?)");
|
" ide-scsi so that sr0 or sda or so is needed?)");
|
||||||
|
@ -1111,61 +1141,63 @@ is_existing_file (const char *s) {
|
||||||
static int
|
static int
|
||||||
mount_one (const char *spec, const char *node, const char *types,
|
mount_one (const char *spec, const char *node, const char *types,
|
||||||
const char *opts, char *cmdlineopts, int freq, int pass) {
|
const char *opts, char *cmdlineopts, int freq, int pass) {
|
||||||
int status, status2;
|
int status, status2;
|
||||||
const char *nspec;
|
const char *nspec;
|
||||||
|
|
||||||
/* Substitute values in opts, if required */
|
/* Substitute values in opts, if required */
|
||||||
opts = usersubst(opts);
|
opts = usersubst(opts);
|
||||||
|
|
||||||
/* Merge the fstab and command line options. */
|
/* Merge the fstab and command line options. */
|
||||||
if (opts == NULL)
|
if (opts == NULL)
|
||||||
opts = cmdlineopts;
|
opts = cmdlineopts;
|
||||||
else if (cmdlineopts != NULL)
|
else if (cmdlineopts != NULL)
|
||||||
opts = xstrconcat3(opts, ",", cmdlineopts);
|
opts = xstrconcat3(opts, ",", cmdlineopts);
|
||||||
|
|
||||||
/* Handle possible LABEL= and UUID= forms of spec */
|
/* Handle possible LABEL= and UUID= forms of spec */
|
||||||
nspec = mount_get_devname_for_mounting(spec);
|
nspec = mount_get_devname_for_mounting(spec);
|
||||||
if (nspec)
|
if (nspec)
|
||||||
spec = nspec;
|
spec = nspec;
|
||||||
|
|
||||||
if (types == NULL && !mounttype && !is_existing_file(spec)) {
|
if (types == NULL && !mounttype && !is_existing_file(spec)) {
|
||||||
if (strchr (spec, ':') != NULL) {
|
if (strchr (spec, ':') != NULL) {
|
||||||
types = "nfs";
|
types = "nfs";
|
||||||
if (verbose)
|
if (verbose)
|
||||||
printf(_("mount: no type was given - "
|
printf(_("mount: no type was given - "
|
||||||
"I'll assume nfs because of the colon\n"));
|
"I'll assume nfs because of "
|
||||||
} else if(!strncmp(spec, "//", 2)) {
|
"the colon\n"));
|
||||||
types = "smbfs";
|
} else if(!strncmp(spec, "//", 2)) {
|
||||||
if (verbose)
|
types = "smbfs";
|
||||||
printf(_("mount: no type was given - "
|
if (verbose)
|
||||||
"I'll assume smbfs because of the // prefix\n"));
|
printf(_("mount: no type was given - "
|
||||||
}
|
"I'll assume smbfs because of "
|
||||||
}
|
"the // prefix\n"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to mount the file system. When the exit status is EX_BG,
|
* Try to mount the file system. When the exit status is EX_BG,
|
||||||
* we will retry in the background. Otherwise, we're done.
|
* we will retry in the background. Otherwise, we're done.
|
||||||
*/
|
*/
|
||||||
status = try_mount_one (spec, node, types, opts, freq, pass, 0, 0);
|
status = try_mount_one (spec, node, types, opts, freq, pass, 0, 0);
|
||||||
if (status != EX_BG)
|
if (status != EX_BG)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retry in the background.
|
* Retry in the background.
|
||||||
*/
|
*/
|
||||||
printf (_("mount: backgrounding \"%s\"\n"), spec);
|
printf (_("mount: backgrounding \"%s\"\n"), spec);
|
||||||
fflush( stdout ); /* prevent duplicate output */
|
fflush( stdout ); /* prevent duplicate output */
|
||||||
if (fork() > 0)
|
if (fork() > 0)
|
||||||
return 0; /* parent returns "success" */
|
return 0; /* parent returns "success" */
|
||||||
spec = xstrdup(spec); /* arguments will be destroyed */
|
spec = xstrdup(spec); /* arguments will be destroyed */
|
||||||
node = xstrdup(node); /* by set_proc_name() */
|
node = xstrdup(node); /* by set_proc_name() */
|
||||||
types = xstrdup(types);
|
types = xstrdup(types);
|
||||||
opts = xstrdup(opts);
|
opts = xstrdup(opts);
|
||||||
set_proc_name (spec); /* make a nice "ps" listing */
|
set_proc_name (spec); /* make a nice "ps" listing */
|
||||||
status2 = try_mount_one (spec, node, types, opts, freq, pass, 1, 0);
|
status2 = try_mount_one (spec, node, types, opts, freq, pass, 1, 0);
|
||||||
if (verbose && status2)
|
if (verbose && status2)
|
||||||
printf (_("mount: giving up \"%s\"\n"), spec);
|
printf (_("mount: giving up \"%s\"\n"), spec);
|
||||||
exit (0); /* child stops here */
|
exit (0); /* child stops here */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if an fsname/dir pair was already in the old mtab. */
|
/* Check if an fsname/dir pair was already in the old mtab. */
|
||||||
|
@ -1177,6 +1209,8 @@ mounted (const char *spec0, const char *node0) {
|
||||||
|
|
||||||
/* Handle possible UUID= and LABEL= in spec */
|
/* Handle possible UUID= and LABEL= in spec */
|
||||||
spec0 = mount_get_devname(spec0);
|
spec0 = mount_get_devname(spec0);
|
||||||
|
if (!spec0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
spec = canonicalize(spec0);
|
spec = canonicalize(spec0);
|
||||||
node = canonicalize(node0);
|
node = canonicalize(node0);
|
||||||
|
@ -1189,8 +1223,8 @@ mounted (const char *spec0, const char *node0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
free(spec);
|
my_free(spec);
|
||||||
free(node);
|
my_free(node);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1407,14 +1441,17 @@ usage (FILE *fp, int n) {
|
||||||
exit (n);
|
exit (n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *progname;
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[]) {
|
main(int argc, char *argv[]) {
|
||||||
int c, result = 0, specseen;
|
int c, result = 0, specseen;
|
||||||
char *options = NULL, *test_opts = NULL, *node;
|
char *options = NULL, *test_opts = NULL, *node;
|
||||||
const char *spec;
|
const char *spec;
|
||||||
char *volumelabel = NULL;
|
char *volumelabel = NULL;
|
||||||
char *uuid = NULL;
|
char *uuid = NULL;
|
||||||
char *types = NULL;
|
char *types = NULL;
|
||||||
|
char *p;
|
||||||
struct mntentchn *mc;
|
struct mntentchn *mc;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
|
@ -1423,6 +1460,10 @@ main (int argc, char *argv[]) {
|
||||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
textdomain(PACKAGE);
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
if ((p = strrchr(progname, '/')) != NULL)
|
||||||
|
progname = p+1;
|
||||||
|
|
||||||
umask(033);
|
umask(033);
|
||||||
|
|
||||||
/* People report that a mount called from init without console
|
/* People report that a mount called from init without console
|
||||||
|
|
|
@ -57,7 +57,7 @@ mount_blkid_put_cache(void) {
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
mount_get_volume_label_by_spec(const char *spec) {
|
mount_get_volume_label_by_spec(const char *spec) {
|
||||||
return strdup(get_volume_label_by_spec(spec));
|
return xstrdup(get_volume_label_by_spec(spec));
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
|
|
|
@ -94,7 +94,7 @@ uuidcache_init_lvm(void) {
|
||||||
sprintf(lvm_device, "%s/%s/%s", DEVLABELDIR,
|
sprintf(lvm_device, "%s/%s/%s", DEVLABELDIR,
|
||||||
vg_iter->d_name, lv_iter->d_name);
|
vg_iter->d_name, lv_iter->d_name);
|
||||||
if (!get_label_uuid(lvm_device, &label, uuid))
|
if (!get_label_uuid(lvm_device, &label, uuid))
|
||||||
uuidcache_addentry(strdup(lvm_device),
|
uuidcache_addentry(xstrdup(lvm_device),
|
||||||
label, uuid);
|
label, uuid);
|
||||||
}
|
}
|
||||||
closedir(lv_list);
|
closedir(lv_list);
|
||||||
|
@ -117,7 +117,7 @@ uuidcache_init_evms(void) {
|
||||||
while (fgets(line, sizeof(line), procvol)) {
|
while (fgets(line, sizeof(line), procvol)) {
|
||||||
if (sscanf(line, "%*d %*d %*d %*s %*s %[^\n]", volname) == 1) {
|
if (sscanf(line, "%*d %*d %*d %*s %*s %[^\n]", volname) == 1) {
|
||||||
if (!get_label_uuid(volname, &label, uuid))
|
if (!get_label_uuid(volname, &label, uuid))
|
||||||
uuidcache_addentry(strdup(volname), label, uuid);
|
uuidcache_addentry(xstrdup(volname), label, uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ uuidcache_init(void) {
|
||||||
*/
|
*/
|
||||||
sprintf(device, "%s/%s", DEVLABELDIR, ptname);
|
sprintf(device, "%s/%s", DEVLABELDIR, ptname);
|
||||||
if (!get_label_uuid(device, &label, uuid))
|
if (!get_label_uuid(device, &label, uuid))
|
||||||
uuidcache_addentry(strdup(device), label, uuid);
|
uuidcache_addentry(xstrdup(device), label, uuid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -559,7 +559,7 @@ procfsnext(FILE *procfs) {
|
||||||
while (fgets(line, sizeof(line), procfs)) {
|
while (fgets(line, sizeof(line), procfs)) {
|
||||||
if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
|
if (sscanf (line, "nodev %[^\n]\n", fsname) == 1) continue;
|
||||||
if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
|
if (sscanf (line, " %[^ \n]\n", fsname) != 1) continue;
|
||||||
return strdup(fsname);
|
return xstrdup(fsname);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ rootdev(char *p) {
|
||||||
sprintf(devname, "/dev/%s%c", type, let);
|
sprintf(devname, "/dev/%s%c", type, let);
|
||||||
else
|
else
|
||||||
sprintf(devname, "/dev/%s%c%d", type, let, mi);
|
sprintf(devname, "/dev/%s%c%d", type, let, mi);
|
||||||
return strdup(devname);
|
return xstrdup(devname);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,8 +80,8 @@ Not available before Linux 2.1.25.
|
||||||
.B \-a
|
.B \-a
|
||||||
All devices marked as ``swap'' swap devices in
|
All devices marked as ``swap'' swap devices in
|
||||||
.I /etc/fstab
|
.I /etc/fstab
|
||||||
are made available. Devices that are already running as swap are silently
|
are made available, except for those with the ``noauto'' option.
|
||||||
skipped.
|
Devices that are already running as swap are silently skipped.
|
||||||
.TP
|
.TP
|
||||||
.B \-e
|
.B \-e
|
||||||
When
|
When
|
||||||
|
|
|
@ -315,6 +315,7 @@ main_swapon(int argc, char *argv[]) {
|
||||||
}
|
}
|
||||||
while ((fstab = getmntent(fp)) != NULL) {
|
while ((fstab = getmntent(fp)) != NULL) {
|
||||||
char *special = fstab->mnt_fsname;
|
char *special = fstab->mnt_fsname;
|
||||||
|
int skip = 0;
|
||||||
|
|
||||||
if (streq(fstab->mnt_type, MNTTYPE_SWAP) &&
|
if (streq(fstab->mnt_type, MNTTYPE_SWAP) &&
|
||||||
!is_in_proc_swaps(special)
|
!is_in_proc_swaps(special)
|
||||||
|
@ -323,10 +324,14 @@ main_swapon(int argc, char *argv[]) {
|
||||||
char *opt, *opts = strdup(fstab->mnt_opts);
|
char *opt, *opts = strdup(fstab->mnt_opts);
|
||||||
|
|
||||||
for (opt = strtok(opts, ","); opt != NULL;
|
for (opt = strtok(opts, ","); opt != NULL;
|
||||||
opt = strtok(NULL, ","))
|
opt = strtok(NULL, ",")) {
|
||||||
if (strncmp(opt, "pri=", 4) == 0)
|
if (strncmp(opt, "pri=", 4) == 0)
|
||||||
priority = atoi(opt+4);
|
priority = atoi(opt+4);
|
||||||
status |= do_swapon(special, priority);
|
if (strcmp(opt, "noauto") == 0)
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
if (!skip)
|
||||||
|
status |= do_swapon(special, priority);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
|
@ -74,6 +74,9 @@ In case unmounting fails, try to remount read-only.
|
||||||
In case the unmounted device was a loop device, also
|
In case the unmounted device was a loop device, also
|
||||||
free this loop device.
|
free this loop device.
|
||||||
.TP
|
.TP
|
||||||
|
.B \-i
|
||||||
|
Don't call the /sbin/umount.<filesystem> helper even if it exists. By default /sbin/umount.<filesystem> helper is called if one exists.
|
||||||
|
.TP
|
||||||
.B \-a
|
.B \-a
|
||||||
All of the file systems described in
|
All of the file systems described in
|
||||||
.I /etc/mtab
|
.I /etc/mtab
|
||||||
|
|
145
mount/umount.c
145
mount/umount.c
|
@ -1,32 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* A umount(8) for Linux 0.99.
|
* umount(8) for Linux 0.99 - jrs, 1993
|
||||||
* umount.c,v 1.1.1.1 1993/11/18 08:40:51 jrs Exp
|
|
||||||
*
|
|
||||||
* Wed Sep 14 22:43:54 1994: Sebastian Lederer
|
|
||||||
* (lederer@next-pc.informatik.uni-bonn.de) added support for sending an
|
|
||||||
* unmount RPC call to the server when an NFS-filesystem is unmounted.
|
|
||||||
*
|
|
||||||
* Tue Sep 26 16:33:09 1995: Added patches from Greg Page (greg@caldera.com)
|
|
||||||
* so that NetWare filesystems can be unmounted.
|
|
||||||
*
|
|
||||||
* 951213: Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>:
|
|
||||||
* Ignore any RPC errors, so that you can umount an nfs mounted filesystem
|
|
||||||
* if the server is down.
|
|
||||||
*
|
|
||||||
* 960223: aeb - several minor changes
|
|
||||||
* 960324: aeb - added some changes from Rob Leslie <rob@mars.org>
|
|
||||||
* 960823: aeb - also try umount(spec) when umount(node) fails
|
|
||||||
* 970307: aeb - canonicalise names from fstab
|
|
||||||
* 970726: aeb - remount read-only in cases where umount fails
|
|
||||||
* 980810: aeb - umount2 support
|
|
||||||
* 981222: aeb - If mount point or special file occurs several times
|
|
||||||
* in mtab, try them all, with last one tried first
|
|
||||||
* - Differentiate "user" and "users" key words in fstab
|
|
||||||
* 001202: aeb - remove at most one line from /etc/mtab
|
|
||||||
* 010716: Michael K. Johnson <johnsonm@redhat.com: -a -O
|
|
||||||
* 010914: Jamie Strandboge - use tcp if that was used for mount
|
|
||||||
* 011005: hch - add lazy umount support
|
|
||||||
* 020105: aeb - permission test owner umount
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -36,6 +9,7 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <sys/mount.h>
|
#include <sys/mount.h>
|
||||||
#include "mount_constants.h"
|
#include "mount_constants.h"
|
||||||
#include "sundries.h"
|
#include "sundries.h"
|
||||||
|
@ -91,6 +65,10 @@ umount2(const char *path, int flags) {
|
||||||
#define MNT_DETACH 2
|
#define MNT_DETACH 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* True if we are allowed to call /sbin/umount.${FSTYPE} */
|
||||||
|
int external_allowed = 1;
|
||||||
|
|
||||||
/* Nonzero for force umount (-f). There is kernel support since 2.1.116. */
|
/* Nonzero for force umount (-f). There is kernel support since 2.1.116. */
|
||||||
int force = 0;
|
int force = 0;
|
||||||
|
|
||||||
|
@ -112,15 +90,61 @@ int verbose = 0;
|
||||||
/* True if ruid != euid. */
|
/* True if ruid != euid. */
|
||||||
int suid = 0;
|
int suid = 0;
|
||||||
|
|
||||||
#ifdef USE_SPECIAL_UMOUNTPROG
|
/*
|
||||||
/* unimplemented so far */
|
* check_special_umountprog()
|
||||||
|
* If there is a special umount program for this type, exec it.
|
||||||
|
* returns: 0: no exec was done, 1: exec was done, status has result
|
||||||
|
*/
|
||||||
static int
|
static int
|
||||||
check_special_umountprog() {
|
check_special_umountprog(const char *spec, const char *node,
|
||||||
/* find type from command line or /etc/mtab;
|
const char *type, int *status) {
|
||||||
stat /sbin/umount.%s
|
char umountprog[120];
|
||||||
if it exists, use it */
|
struct stat statbuf;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (!external_allowed)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (type && strlen(type) < 100) {
|
||||||
|
sprintf(umountprog, "/sbin/umount.%s", type);
|
||||||
|
if (stat(umountprog, &statbuf) == 0) {
|
||||||
|
res = fork();
|
||||||
|
if (res == 0) {
|
||||||
|
char *umountargs[8];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
setuid(getuid());
|
||||||
|
setgid(getgid());
|
||||||
|
umountargs[i++] = umountprog;
|
||||||
|
umountargs[i++] = xstrdup(node);
|
||||||
|
if (nomtab)
|
||||||
|
umountargs[i++] = "-n";
|
||||||
|
if (lazy)
|
||||||
|
umountargs[i++] = "-l";
|
||||||
|
if (force)
|
||||||
|
umountargs[i++] = "-f";
|
||||||
|
if (verbose)
|
||||||
|
umountargs[i++] = "-v";
|
||||||
|
if (remount)
|
||||||
|
umountargs[i++] = "-r";
|
||||||
|
umountargs[i] = NULL;
|
||||||
|
execv(umountprog, umountargs);
|
||||||
|
exit(1); /* exec failed */
|
||||||
|
} else if (res != -1) {
|
||||||
|
int st;
|
||||||
|
wait(&st);
|
||||||
|
*status = (WIFEXITED(st) ? WEXITSTATUS(st)
|
||||||
|
: EX_SYSERR);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
int errsv = errno;
|
||||||
|
error(_("umount: cannot fork: %s"),
|
||||||
|
strerror(errsv));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_NFS
|
#ifdef HAVE_NFS
|
||||||
static int xdr_dir(XDR *xdrsp, char *dirp)
|
static int xdr_dir(XDR *xdrsp, char *dirp)
|
||||||
|
@ -248,6 +272,7 @@ umount_one (const char *spec, const char *node, const char *type,
|
||||||
int umnt_err, umnt_err2;
|
int umnt_err, umnt_err2;
|
||||||
int isroot;
|
int isroot;
|
||||||
int res;
|
int res;
|
||||||
|
int status;
|
||||||
const char *loopdev;
|
const char *loopdev;
|
||||||
|
|
||||||
/* Special case for root. As of 0.99pl10 we can (almost) unmount root;
|
/* Special case for root. As of 0.99pl10 we can (almost) unmount root;
|
||||||
|
@ -260,6 +285,13 @@ umount_one (const char *spec, const char *node, const char *type,
|
||||||
|| streq (node, "rootfs"));
|
|| streq (node, "rootfs"));
|
||||||
if (isroot)
|
if (isroot)
|
||||||
nomtab++;
|
nomtab++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Call umount.TYPE for types that require a separate umount program.
|
||||||
|
* All such special things must occur isolated in the types string.
|
||||||
|
*/
|
||||||
|
if (check_special_umountprog(spec, node, type, &status))
|
||||||
|
return status;
|
||||||
|
|
||||||
#ifdef HAVE_NFS
|
#ifdef HAVE_NFS
|
||||||
/* Ignore any RPC errors, so that you can umount the filesystem
|
/* Ignore any RPC errors, so that you can umount the filesystem
|
||||||
|
@ -322,7 +354,7 @@ umount_one (const char *spec, const char *node, const char *type,
|
||||||
spec);
|
spec);
|
||||||
remnt.mnt_type = remnt.mnt_fsname = NULL;
|
remnt.mnt_type = remnt.mnt_fsname = NULL;
|
||||||
remnt.mnt_dir = xstrdup(node);
|
remnt.mnt_dir = xstrdup(node);
|
||||||
remnt.mnt_opts = "ro";
|
remnt.mnt_opts = xstrdup("ro");
|
||||||
update_mtab(node, &remnt);
|
update_mtab(node, &remnt);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (errno != EBUSY) { /* hmm ... */
|
} else if (errno != EBUSY) { /* hmm ... */
|
||||||
|
@ -514,7 +546,8 @@ static int
|
||||||
umount_file (char *arg) {
|
umount_file (char *arg) {
|
||||||
struct mntentchn *mc, *fs;
|
struct mntentchn *mc, *fs;
|
||||||
const char *file, *options;
|
const char *file, *options;
|
||||||
int fstab_has_user, fstab_has_users, fstab_has_owner, ok;
|
int fstab_has_user, fstab_has_users, fstab_has_owner, fstab_has_group;
|
||||||
|
int ok;
|
||||||
|
|
||||||
file = canonicalize(arg); /* mtab paths are canonicalized */
|
file = canonicalize(arg); /* mtab paths are canonicalized */
|
||||||
if (verbose > 1)
|
if (verbose > 1)
|
||||||
|
@ -556,16 +589,17 @@ umount_file (char *arg) {
|
||||||
"the fstab"), file);
|
"the fstab"), file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User mounting and unmounting is allowed only
|
/*
|
||||||
if fstab contains one of the options `user',
|
* User mounting and unmounting is allowed only
|
||||||
`users' or `owner'. */
|
* if fstab contains one of the options `user',
|
||||||
/* The option `users' allows arbitrary users to mount
|
* `users' or `owner' or `group'.
|
||||||
and unmount - this may be a security risk. */
|
*
|
||||||
/* The option `user' only allows unmounting by the user
|
* The option `users' allows arbitrary users to mount
|
||||||
that mounted. */
|
* and unmount - this may be a security risk.
|
||||||
/* The option `owner' only allows (un)mounting by the owner. */
|
*
|
||||||
/* A convenient side effect is that the user who mounted
|
* The options `user', `owner' and `group' only allow
|
||||||
is visible in mtab. */
|
* unmounting by the user that mounted (visible in mtab).
|
||||||
|
*/
|
||||||
|
|
||||||
options = fs->m.mnt_opts;
|
options = fs->m.mnt_opts;
|
||||||
if (!options)
|
if (!options)
|
||||||
|
@ -573,12 +607,14 @@ umount_file (char *arg) {
|
||||||
fstab_has_user = contains(options, "user");
|
fstab_has_user = contains(options, "user");
|
||||||
fstab_has_users = contains(options, "users");
|
fstab_has_users = contains(options, "users");
|
||||||
fstab_has_owner = contains(options, "owner");
|
fstab_has_owner = contains(options, "owner");
|
||||||
|
fstab_has_group = contains(options, "group");
|
||||||
ok = 0;
|
ok = 0;
|
||||||
|
|
||||||
if (fstab_has_users)
|
if (fstab_has_users)
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
if (!ok && (fstab_has_user || fstab_has_owner)) {
|
if (!ok && (fstab_has_user || fstab_has_owner ||
|
||||||
|
fstab_has_group)) {
|
||||||
char *user = getusername();
|
char *user = getusername();
|
||||||
|
|
||||||
options = mc->m.mnt_opts;
|
options = mc->m.mnt_opts;
|
||||||
|
@ -601,11 +637,13 @@ umount_file (char *arg) {
|
||||||
return umount_one (arg, arg, arg, arg, NULL);
|
return umount_one (arg, arg, arg, arg, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *progname;
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc, char *argv[]) {
|
main (int argc, char *argv[]) {
|
||||||
int c;
|
int c;
|
||||||
int all = 0;
|
int all = 0;
|
||||||
char *types = NULL, *test_opts = NULL;
|
char *types = NULL, *test_opts = NULL, *p;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
sanitize_env();
|
sanitize_env();
|
||||||
|
@ -613,9 +651,13 @@ main (int argc, char *argv[]) {
|
||||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
textdomain(PACKAGE);
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
if ((p = strrchr(progname, '/')) != NULL)
|
||||||
|
progname = p+1;
|
||||||
|
|
||||||
umask(033);
|
umask(033);
|
||||||
|
|
||||||
while ((c = getopt_long (argc, argv, "adfhlnrt:O:vV",
|
while ((c = getopt_long (argc, argv, "adfhlnrit:O:vV",
|
||||||
longopts, NULL)) != -1)
|
longopts, NULL)) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'a': /* umount everything */
|
case 'a': /* umount everything */
|
||||||
|
@ -652,6 +694,9 @@ main (int argc, char *argv[]) {
|
||||||
case 't': /* specify file system type */
|
case 't': /* specify file system type */
|
||||||
types = optarg;
|
types = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'i':
|
||||||
|
external_allowed = 0;
|
||||||
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
|
|
2766
po/cat-id-tbl.c
2766
po/cat-id-tbl.c
File diff suppressed because it is too large
Load Diff
1351
po/pt_BR.po
1351
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
|
@ -8,7 +8,7 @@ include ../MCONFIG
|
||||||
|
|
||||||
# Where to put man pages?
|
# Where to put man pages?
|
||||||
|
|
||||||
MAN1= arch.1 readprofile.1
|
MAN1= arch.1 flock.1 readprofile.1
|
||||||
|
|
||||||
MAN8= ctrlaltdel.8 cytune.8 dmesg.8 \
|
MAN8= ctrlaltdel.8 cytune.8 dmesg.8 \
|
||||||
ipcrm.8 ipcs.8 renice.8 \
|
ipcrm.8 ipcs.8 renice.8 \
|
||||||
|
@ -19,7 +19,7 @@ MAN8= ctrlaltdel.8 cytune.8 dmesg.8 \
|
||||||
|
|
||||||
BIN= arch dmesg
|
BIN= arch dmesg
|
||||||
|
|
||||||
USRBIN= cytune ipcrm ipcs renice setsid
|
USRBIN= cytune flock ipcrm ipcs renice setsid
|
||||||
|
|
||||||
USRSBIN= readprofile tunelp
|
USRSBIN= readprofile tunelp
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
.TH FLOCK "1" "November 2004" "flock (util-linux)" "User Commands"
|
||||||
|
.SH NAME
|
||||||
|
flock \- acquire a file lock and then execute a command with the lock held
|
||||||
|
.SH SYNOPSIS
|
||||||
|
.BR flock
|
||||||
|
[ \fB\-\-shared\fR | \fB\-\-timeout=\fR\fIseconds\fR ] lockfile command ..
|
||||||
|
.SH DESCRIPTION
|
||||||
|
.\" Add any additional description here
|
||||||
|
.PP
|
||||||
|
Acquire a file lock using the flock(2) system call and then execute
|
||||||
|
the given command with the lock held. Depending on the options given,
|
||||||
|
the lock can be either exclusive or shared, and the behavior in the
|
||||||
|
event of lock contention can be specified as either waiting
|
||||||
|
indefinitely for the lock to become available (the default), or
|
||||||
|
failing if the lock does not become available after a specific time,
|
||||||
|
which can be specified as zero to make the command not wait at all.
|
||||||
|
.PP
|
||||||
|
.TP
|
||||||
|
\fB\-\-shared\fR
|
||||||
|
Acquire a shared lock. Acquiring a shared lock does
|
||||||
|
not stop others from acquiring a shared lock, but it will stop others
|
||||||
|
from acquiring an exclusive lock. Conversely, acquiring an exclusive
|
||||||
|
lock (the default) stops both exclusive and shared attempts to acquire
|
||||||
|
the lock. Typically, a shared lock is used if a command is just going
|
||||||
|
to read the locked data, and an exclusive lock is used if the command
|
||||||
|
might write to it.
|
||||||
|
.TP
|
||||||
|
\fB\-\-timeout=n\fR
|
||||||
|
Abort if the lock cannot be acquired before \fIn\fR seconds.
|
||||||
|
For a completely non-blocking attempt to acquire a lock, specify
|
||||||
|
\fB\-\-timeout=0\fR.
|
||||||
|
The timer applies only to the attempt to acquire the lock. As soon
|
||||||
|
as the lock is acquired, the timeout is cancelled. The command to
|
||||||
|
be run is not subject to the timeout.
|
||||||
|
.PP
|
||||||
|
.SH "EXAMPLES (invoking some imaginary programs)"
|
||||||
|
.hl
|
||||||
|
.PP
|
||||||
|
flock /etc/passwd read-and-write-to-passwd
|
||||||
|
.PP
|
||||||
|
flock \-\-shared /etc/passwd just-read-something-from-passwd
|
||||||
|
.PP
|
||||||
|
flock \-\-timeout=0 /sys /usr/local/bin/update-hotplug /sys
|
||||||
|
.SH AUTHOR
|
||||||
|
Written by Adam J. Richter
|
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
flock - acquires a file lock and executes a command with the lock held.
|
||||||
|
Usage: flock [--shared | --timeout=seconds] lockfile program [args...]
|
||||||
|
|
||||||
|
Written by Adam J. Richter
|
||||||
|
Copyright (C) 2004 Yggdrasil Computing, Inc.
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program 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 General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h> /* exit */
|
||||||
|
#include <signal.h> /* kill */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "nls.h"
|
||||||
|
|
||||||
|
static int non_blocking = 0;
|
||||||
|
static int shared = LOCK_EX;
|
||||||
|
|
||||||
|
static const struct option options[] = {
|
||||||
|
{"shared", no_argument, &shared, LOCK_SH },
|
||||||
|
{"timeout", required_argument, NULL, 't' },
|
||||||
|
{NULL, 0, NULL, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
int opt;
|
||||||
|
int pid;
|
||||||
|
int child_status;
|
||||||
|
int option_index;
|
||||||
|
int timeout = 0;
|
||||||
|
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
|
textdomain(PACKAGE);
|
||||||
|
|
||||||
|
do {
|
||||||
|
opt = getopt_long(argc, argv, "+", options, &option_index);
|
||||||
|
switch(opt) {
|
||||||
|
case '?':
|
||||||
|
fprintf (stderr,
|
||||||
|
_("flock: unknown option, aborting.\n"));
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
timeout = atoi(optarg);
|
||||||
|
if (timeout == 0)
|
||||||
|
non_blocking |= LOCK_NB;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (opt != -1);
|
||||||
|
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr,
|
||||||
|
_("Usage flock [--shared | --timeout=seconds] "
|
||||||
|
"filename command {arg arg...}\n"));
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open(argv[0], O_RDONLY);
|
||||||
|
if (fd < 0) {
|
||||||
|
perror(argv[0]);
|
||||||
|
exit(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
alarm(timeout);
|
||||||
|
if (flock(fd, shared | non_blocking) != 0) {
|
||||||
|
perror("flock");
|
||||||
|
exit(4);
|
||||||
|
}
|
||||||
|
alarm(0);
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
|
perror("fork");
|
||||||
|
exit(5);
|
||||||
|
}
|
||||||
|
if (pid == 0) {
|
||||||
|
execvp(argv[1], argv+1);
|
||||||
|
perror(argv[1]);
|
||||||
|
exit(6);
|
||||||
|
}
|
||||||
|
waitpid(pid, &child_status, 0);
|
||||||
|
|
||||||
|
/* flock(fd, LOCK_UN); */
|
||||||
|
/* No need to explicitly release the flock, since we are just
|
||||||
|
going to exit now anyhow. */
|
||||||
|
|
||||||
|
/* Lame attempt to simulate child's mode of death. */
|
||||||
|
if (WIFSIGNALED(child_status))
|
||||||
|
kill(0, WTERMSIG(child_status));
|
||||||
|
|
||||||
|
return WEXITSTATUS(child_status);
|
||||||
|
}
|
|
@ -388,6 +388,10 @@ main(int argc, char **argv) {
|
||||||
|
|
||||||
maplineno++;
|
maplineno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clock ticks, out of kernel text - probably modules */
|
||||||
|
printf("%6i %s\n", buf[len/sizeof(*buf)-1], "*unknown*");
|
||||||
|
|
||||||
/* trailer */
|
/* trailer */
|
||||||
if (optVerbose)
|
if (optVerbose)
|
||||||
printf("%016x %-40s %6i %8.4f\n",
|
printf("%016x %-40s %6i %8.4f\n",
|
||||||
|
|
|
@ -70,6 +70,9 @@
|
||||||
#define Fseek(f,off) (file_pos=off,fseek(f,off,0))
|
#define Fseek(f,off) (file_pos=off,fseek(f,off,0))
|
||||||
#define Getc(f) (++file_pos, getc(f))
|
#define Getc(f) (++file_pos, getc(f))
|
||||||
#define Ungetc(c,f) (--file_pos, ungetc(c,f))
|
#define Ungetc(c,f) (--file_pos, ungetc(c,f))
|
||||||
|
#define putcerr(c) fputc(c, stderr)
|
||||||
|
#define putserr(s) fputs(s, stderr)
|
||||||
|
#define putsout(s) fputs(s, stdout)
|
||||||
|
|
||||||
#define stty(fd,argp) tcsetattr(fd,TCSANOW,argp)
|
#define stty(fd,argp) tcsetattr(fd,TCSANOW,argp)
|
||||||
|
|
||||||
|
@ -94,8 +97,6 @@ void screen (register FILE *f, register int num_lines);
|
||||||
int command (char *filename, register FILE *f);
|
int command (char *filename, register FILE *f);
|
||||||
void erasep (register int col);
|
void erasep (register int col);
|
||||||
void show (register char ch);
|
void show (register char ch);
|
||||||
int pr(char *s1);
|
|
||||||
int printd (int n);
|
|
||||||
void set_tty(void);
|
void set_tty(void);
|
||||||
void reset_tty(void);
|
void reset_tty(void);
|
||||||
void ttyin (unsigned char buf[], register int nmax, char pchar);
|
void ttyin (unsigned char buf[], register int nmax, char pchar);
|
||||||
|
@ -103,10 +104,7 @@ int number(char *cmd);
|
||||||
int readch (void);
|
int readch (void);
|
||||||
int get_line(register FILE *f, int *length);
|
int get_line(register FILE *f, int *length);
|
||||||
void prbuf (register char *s, register int n);
|
void prbuf (register char *s, register int n);
|
||||||
int xprintf (char *fmt, ...);
|
|
||||||
void execute (char *filename, char *cmd, ...);
|
void execute (char *filename, char *cmd, ...);
|
||||||
void errwrite (char *txt);
|
|
||||||
void errwrite1 (char *sym);
|
|
||||||
FILE *checkf (char *, int *);
|
FILE *checkf (char *, int *);
|
||||||
|
|
||||||
#define TBUFSIZ 1024
|
#define TBUFSIZ 1024
|
||||||
|
@ -182,7 +180,7 @@ extern char PC; /* pad character */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
my_putstring(char *s) {
|
my_putstring(char *s) {
|
||||||
putp(s);
|
tputs (s, 1, putchar); /* putp(s); */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -412,14 +410,14 @@ int main(int argc, char **argv) {
|
||||||
erasep (0);
|
erasep (0);
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
pr("::::::::::::::");
|
putsout("::::::::::::::");
|
||||||
if (promptlen > 14)
|
if (promptlen > 14)
|
||||||
erasep (14);
|
erasep (14);
|
||||||
xprintf ("\n");
|
putchar('\n');
|
||||||
if(clreol) cleareol();
|
if(clreol) cleareol();
|
||||||
xprintf("%s\n", fnames[fnum]);
|
puts(fnames[fnum]);
|
||||||
if(clreol) cleareol();
|
if(clreol) cleareol();
|
||||||
xprintf("::::::::::::::\n");
|
puts("::::::::::::::");
|
||||||
if (left > Lpp - 4)
|
if (left > Lpp - 4)
|
||||||
left = Lpp - 4;
|
left = Lpp - 4;
|
||||||
}
|
}
|
||||||
|
@ -483,10 +481,8 @@ void argscan(char *s, char *argv0) {
|
||||||
case '-': case ' ': case '\t':
|
case '-': case ' ': case '\t':
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fputs(argv0,stderr);
|
fprintf(stderr,
|
||||||
fputs(": unknown option \"-",stderr);
|
_("%s: unknown option \"-%c\"\n"), argv0, *s);
|
||||||
putc(*s,stderr);
|
|
||||||
fputs("\"\n",stderr);
|
|
||||||
usage(argv0);
|
usage(argv0);
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
|
@ -518,7 +514,7 @@ checkf (fs, clearfirst)
|
||||||
return((FILE *)NULL);
|
return((FILE *)NULL);
|
||||||
}
|
}
|
||||||
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
|
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) {
|
||||||
xprintf(_("\n*** %s: directory ***\n\n"), fs);
|
printf(_("\n*** %s: directory ***\n\n"), fs);
|
||||||
return((FILE *)NULL);
|
return((FILE *)NULL);
|
||||||
}
|
}
|
||||||
if ((f = Fopen(fs, "r")) == NULL) {
|
if ((f = Fopen(fs, "r")) == NULL) {
|
||||||
|
@ -561,7 +557,7 @@ magic(f, fs)
|
||||||
case 0411:
|
case 0411:
|
||||||
case 0177545:
|
case 0177545:
|
||||||
case 0x457f: /* simple ELF detection */
|
case 0x457f: /* simple ELF detection */
|
||||||
xprintf(_("\n******** %s: Not a text file ********\n\n"), fs);
|
printf(_("\n******** %s: Not a text file ********\n\n"), fs);
|
||||||
(void)fclose(f);
|
(void)fclose(f);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
@ -664,9 +660,7 @@ void onquit(int dummy) {
|
||||||
Pause++;
|
Pause++;
|
||||||
}
|
}
|
||||||
else if (!dum_opt && notell) {
|
else if (!dum_opt && notell) {
|
||||||
char *s = _("[Use q or Q to quit]");
|
promptlen += fprintf(stderr, _("[Use q or Q to quit]"));
|
||||||
errwrite(s);
|
|
||||||
promptlen += strlen(s);
|
|
||||||
notell = 0;
|
notell = 0;
|
||||||
}
|
}
|
||||||
signal(SIGQUIT, onquit);
|
signal(SIGQUIT, onquit);
|
||||||
|
@ -712,7 +706,7 @@ void end_it (int dummy) {
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
errwrite("\n");
|
putcerr('\n');
|
||||||
_exit(0);
|
_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -723,93 +717,7 @@ void copy_file(register FILE *f) {
|
||||||
putchar(c);
|
putchar(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Simplified printf function */
|
#define ringbell() putcerr('\007')
|
||||||
|
|
||||||
int xprintf (char *fmt, ...) {
|
|
||||||
va_list ap;
|
|
||||||
char ch;
|
|
||||||
int ccount;
|
|
||||||
|
|
||||||
ccount = 0;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
while (*fmt) {
|
|
||||||
while ((ch = *fmt++) != '%') {
|
|
||||||
if (ch == '\0')
|
|
||||||
return (ccount);
|
|
||||||
ccount++;
|
|
||||||
putchar (ch);
|
|
||||||
}
|
|
||||||
switch (*fmt++) {
|
|
||||||
case 'd':
|
|
||||||
ccount += printd (va_arg(ap, int));
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
ccount += pr (va_arg(ap, char *));
|
|
||||||
break;
|
|
||||||
case '%':
|
|
||||||
ccount++;
|
|
||||||
putchar ('%');
|
|
||||||
break;
|
|
||||||
case '0':
|
|
||||||
return (ccount);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
va_end(ap);
|
|
||||||
return (ccount);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** Print an integer as a string of decimal digits,
|
|
||||||
** returning the length of the print representation.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int printd (int n)
|
|
||||||
{
|
|
||||||
int a, nchars;
|
|
||||||
|
|
||||||
if ((a = n/10) != 0)
|
|
||||||
nchars = 1 + printd(a);
|
|
||||||
else
|
|
||||||
nchars = 1;
|
|
||||||
putchar (n % 10 + '0');
|
|
||||||
return (nchars);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put the print representation of an integer into a string */
|
|
||||||
static char *sptr;
|
|
||||||
|
|
||||||
static void Sprintf (int n) {
|
|
||||||
int a;
|
|
||||||
|
|
||||||
if ((a = n/10) != 0)
|
|
||||||
Sprintf (a);
|
|
||||||
*sptr++ = n % 10 + '0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static void scanstr (int n, char *str)
|
|
||||||
{
|
|
||||||
sptr = str;
|
|
||||||
Sprintf (n);
|
|
||||||
*sptr = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
#define ringbell() errwrite("\007");
|
|
||||||
|
|
||||||
#ifdef undef
|
|
||||||
strlen (s)
|
|
||||||
char *s;
|
|
||||||
{
|
|
||||||
register char *p;
|
|
||||||
|
|
||||||
p = s;
|
|
||||||
while (*p++)
|
|
||||||
;
|
|
||||||
return (p - s - 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* See whether the last component of the path name "path" is equal to the
|
/* See whether the last component of the path name "path" is equal to the
|
||||||
** string "string"
|
** string "string"
|
||||||
|
@ -844,15 +752,14 @@ static void prompt (char *filename)
|
||||||
}
|
}
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
promptlen += pr(_("--More--"));
|
promptlen += printf(_("--More--"));
|
||||||
if (filename != NULL) {
|
if (filename != NULL) {
|
||||||
promptlen += xprintf (_("(Next file: %s)"), filename);
|
promptlen += printf(_("(Next file: %s)"), filename);
|
||||||
} else if (!no_intty) {
|
} else if (!no_intty) {
|
||||||
promptlen += xprintf ("(%d%%)",
|
promptlen += printf("(%d%%)", (int) ((file_pos * 100) / file_size));
|
||||||
(int)((file_pos * 100) / file_size));
|
|
||||||
}
|
}
|
||||||
if (dum_opt) {
|
if (dum_opt) {
|
||||||
promptlen += pr(_("[Press space to continue, 'q' to quit.]"));
|
promptlen += printf(_("[Press space to continue, 'q' to quit.]"));
|
||||||
}
|
}
|
||||||
if (Senter && Sexit)
|
if (Senter && Sexit)
|
||||||
my_putstring (Sexit);
|
my_putstring (Sexit);
|
||||||
|
@ -1119,21 +1026,6 @@ void clreos()
|
||||||
my_putstring(EodClr);
|
my_putstring(EodClr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
** Print string and return number of characters
|
|
||||||
*/
|
|
||||||
|
|
||||||
int pr(char *s1)
|
|
||||||
{
|
|
||||||
register char *s;
|
|
||||||
register char c;
|
|
||||||
|
|
||||||
for (s = s1; (c = *s++) != 0; )
|
|
||||||
putchar(c);
|
|
||||||
return (int) (s - s1 - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Print a buffer of n characters */
|
/* Print a buffer of n characters */
|
||||||
|
|
||||||
void prbuf (register char *s, register int n)
|
void prbuf (register char *s, register int n)
|
||||||
|
@ -1165,7 +1057,7 @@ void prbuf (register char *s, register int n)
|
||||||
if (c != ' ' || pstate == 0 || state != 0 || ulglitch == 0)
|
if (c != ' ' || pstate == 0 || state != 0 || ulglitch == 0)
|
||||||
putchar(c);
|
putchar(c);
|
||||||
if (state && *chUL) {
|
if (state && *chUL) {
|
||||||
pr(chBS);
|
putsout(chBS);
|
||||||
my_putstring(chUL);
|
my_putstring(chUL);
|
||||||
}
|
}
|
||||||
pstate = state;
|
pstate = state;
|
||||||
|
@ -1262,16 +1154,16 @@ int command (char *filename, register FILE *f)
|
||||||
|
|
||||||
putchar ('\r');
|
putchar ('\r');
|
||||||
erasep (0);
|
erasep (0);
|
||||||
xprintf ("\n");
|
putchar('\n');
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
if (nlines != 1)
|
if (nlines != 1)
|
||||||
xprintf (_("...back %d pages"), nlines);
|
printf(_("...back %d pages"), nlines);
|
||||||
else
|
else
|
||||||
xprintf (_("...back 1 page"));
|
putsout(_("...back 1 page"));
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
pr ("\n");
|
putchar('\n');
|
||||||
|
|
||||||
initline = Currline - dlines * (nlines + 1);
|
initline = Currline - dlines * (nlines + 1);
|
||||||
if (! noscroll)
|
if (! noscroll)
|
||||||
|
@ -1307,17 +1199,17 @@ int command (char *filename, register FILE *f)
|
||||||
nlines *= dlines;
|
nlines *= dlines;
|
||||||
putchar ('\r');
|
putchar ('\r');
|
||||||
erasep (0);
|
erasep (0);
|
||||||
xprintf ("\n");
|
putchar('\n');
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
if (nlines == 1)
|
if (nlines == 1)
|
||||||
xprintf (_("...skipping one line"));
|
putsout(_("...skipping one line"));
|
||||||
else
|
else
|
||||||
xprintf (_("...skipping %d lines"), nlines);
|
printf(_("...skipping %d lines"), nlines);
|
||||||
|
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
pr ("\n");
|
putchar('\n');
|
||||||
|
|
||||||
while (nlines > 0) {
|
while (nlines > 0) {
|
||||||
while ((c = Getc (f)) != '\n')
|
while ((c = Getc (f)) != '\n')
|
||||||
|
@ -1350,7 +1242,7 @@ int command (char *filename, register FILE *f)
|
||||||
case '\'':
|
case '\'':
|
||||||
if (!no_intty) {
|
if (!no_intty) {
|
||||||
kill_line ();
|
kill_line ();
|
||||||
pr (_("\n***Back***\n\n"));
|
putsout(_("\n***Back***\n\n"));
|
||||||
Fseek (f, context.chrctr);
|
Fseek (f, context.chrctr);
|
||||||
Currline = context.line;
|
Currline = context.line;
|
||||||
ret (dlines);
|
ret (dlines);
|
||||||
|
@ -1361,7 +1253,7 @@ int command (char *filename, register FILE *f)
|
||||||
}
|
}
|
||||||
case '=':
|
case '=':
|
||||||
kill_line ();
|
kill_line ();
|
||||||
promptlen = printd (Currline);
|
promptlen = printf("%d", Currline);
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
|
@ -1369,16 +1261,16 @@ int command (char *filename, register FILE *f)
|
||||||
case '/':
|
case '/':
|
||||||
if (nlines == 0) nlines++;
|
if (nlines == 0) nlines++;
|
||||||
kill_line ();
|
kill_line ();
|
||||||
pr ("/");
|
putchar('/');
|
||||||
promptlen = 1;
|
promptlen = 1;
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
if (lastp) {
|
if (lastp) {
|
||||||
errwrite ("\r");
|
putcerr('\r');
|
||||||
search (NULL, f, nlines); /* Use previous r.e. */
|
search (NULL, f, nlines); /* Use previous r.e. */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ttyin (cmdbuf, sizeof(cmdbuf)-2, '/');
|
ttyin (cmdbuf, sizeof(cmdbuf)-2, '/');
|
||||||
errwrite("\r");
|
putcerr('\r');
|
||||||
search (cmdbuf, f, nlines);
|
search (cmdbuf, f, nlines);
|
||||||
}
|
}
|
||||||
ret (dlines-1);
|
ret (dlines-1);
|
||||||
|
@ -1388,13 +1280,13 @@ int command (char *filename, register FILE *f)
|
||||||
case '?':
|
case '?':
|
||||||
case 'h':
|
case 'h':
|
||||||
if (noscroll) doclear();
|
if (noscroll) doclear();
|
||||||
xprintf(_("\n"
|
putsout(_("\n"
|
||||||
"Most commands optionally preceded by integer argument k. "
|
"Most commands optionally preceded by integer argument k. "
|
||||||
"Defaults in brackets.\n"
|
"Defaults in brackets.\n"
|
||||||
"Star (*) indicates argument becomes new default.\n"));
|
"Star (*) indicates argument becomes new default.\n"));
|
||||||
xprintf("---------------------------------------"
|
puts("---------------------------------------"
|
||||||
"----------------------------------------\n");
|
"----------------------------------------");
|
||||||
xprintf(_(
|
putsout(_(
|
||||||
"<space> Display next k lines of text [current screen size]\n"
|
"<space> Display next k lines of text [current screen size]\n"
|
||||||
"z Display next k lines of text [current screen size]*\n"
|
"z Display next k lines of text [current screen size]*\n"
|
||||||
"<return> Display next k lines of text [1]*\n"
|
"<return> Display next k lines of text [1]*\n"
|
||||||
|
@ -1414,8 +1306,8 @@ int command (char *filename, register FILE *f)
|
||||||
":p Go to kth previous file [1]\n"
|
":p Go to kth previous file [1]\n"
|
||||||
":f Display current file name and line number\n"
|
":f Display current file name and line number\n"
|
||||||
". Repeat previous command\n"));
|
". Repeat previous command\n"));
|
||||||
xprintf("---------------------------------------"
|
puts("---------------------------------------"
|
||||||
"----------------------------------------\n");
|
"----------------------------------------");
|
||||||
prompt(filename);
|
prompt(filename);
|
||||||
break;
|
break;
|
||||||
case 'v': /* This case should go right before default */
|
case 'v': /* This case should go right before default */
|
||||||
|
@ -1441,17 +1333,14 @@ int command (char *filename, register FILE *f)
|
||||||
else
|
else
|
||||||
p = editor;
|
p = editor;
|
||||||
if (!strcmp(p, "vi") || !strcmp(p, "ex")) {
|
if (!strcmp(p, "vi") || !strcmp(p, "ex")) {
|
||||||
strcpy(cmdbuf, "-c ");
|
sprintf(cmdbuf, "-c %d", n);
|
||||||
scanstr(n, &cmdbuf[3]);
|
|
||||||
split = 1;
|
split = 1;
|
||||||
} else {
|
} else {
|
||||||
cmdbuf[0] = '+';
|
sprintf(cmdbuf, "+%d", n);
|
||||||
scanstr(n, &cmdbuf[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kill_line();
|
kill_line();
|
||||||
pr(editor); putchar(' ');
|
printf("%s %s %s", editor, cmdbuf, fnames[fnum]);
|
||||||
pr(cmdbuf); putchar(' '); pr(fnames[fnum]);
|
|
||||||
if (split) {
|
if (split) {
|
||||||
cmdbuf[2] = 0;
|
cmdbuf[2] = 0;
|
||||||
execute(filename, editor, editor, cmdbuf,
|
execute(filename, editor, editor, cmdbuf,
|
||||||
|
@ -1467,12 +1356,12 @@ int command (char *filename, register FILE *f)
|
||||||
kill_line ();
|
kill_line ();
|
||||||
if (Senter && Sexit) {
|
if (Senter && Sexit) {
|
||||||
my_putstring (Senter);
|
my_putstring (Senter);
|
||||||
promptlen = pr (_("[Press 'h' for instructions.]"))
|
promptlen = printf(_("[Press 'h' for instructions.]"))
|
||||||
+ 2 * soglitch;
|
+ 2 * soglitch;
|
||||||
my_putstring (Sexit);
|
my_putstring (Sexit);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
promptlen = pr (_("[Press 'h' for instructions.]"));
|
promptlen = printf(_("[Press 'h' for instructions.]"));
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1506,9 +1395,9 @@ int colon (char *filename, int cmd, int nlines) {
|
||||||
case 'f':
|
case 'f':
|
||||||
kill_line ();
|
kill_line ();
|
||||||
if (!no_intty)
|
if (!no_intty)
|
||||||
promptlen = xprintf (_("\"%s\" line %d"), fnames[fnum], Currline);
|
promptlen = printf(_("\"%s\" line %d"), fnames[fnum], Currline);
|
||||||
else
|
else
|
||||||
promptlen = xprintf (_("[Not a file] line %d"), Currline);
|
promptlen = printf(_("[Not a file] line %d"), Currline);
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
return (-1);
|
return (-1);
|
||||||
case 'n':
|
case 'n':
|
||||||
|
@ -1575,11 +1464,11 @@ void do_shell (char *filename)
|
||||||
char *expanded;
|
char *expanded;
|
||||||
|
|
||||||
kill_line ();
|
kill_line ();
|
||||||
pr ("!");
|
putchar('!');
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
promptlen = 1;
|
promptlen = 1;
|
||||||
if (lastp)
|
if (lastp)
|
||||||
pr (shell_line);
|
putsout(shell_line);
|
||||||
else {
|
else {
|
||||||
ttyin (cmdbuf, sizeof(cmdbuf)-2, '!');
|
ttyin (cmdbuf, sizeof(cmdbuf)-2, '!');
|
||||||
expanded = 0;
|
expanded = 0;
|
||||||
|
@ -1592,16 +1481,16 @@ void do_shell (char *filename)
|
||||||
free(expanded);
|
free(expanded);
|
||||||
}
|
}
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
errwrite(_(" Overflow\n"));
|
putserr(_(" Overflow\n"));
|
||||||
prompt (filename);
|
prompt (filename);
|
||||||
return;
|
return;
|
||||||
} else if (rc > 0) {
|
} else if (rc > 0) {
|
||||||
kill_line ();
|
kill_line ();
|
||||||
promptlen = xprintf ("!%s", shell_line);
|
promptlen = printf("!%s", shell_line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
errwrite("\n");
|
putcerr('\n');
|
||||||
promptlen = 0;
|
promptlen = 0;
|
||||||
shellp = 1;
|
shellp = 1;
|
||||||
execute (filename, shell, shell, "-c", shell_line, 0);
|
execute (filename, shell, shell, "-c", shell_line, 0);
|
||||||
|
@ -1636,10 +1525,10 @@ void search(char buf[], FILE *file, register int n)
|
||||||
if (--n == 0) {
|
if (--n == 0) {
|
||||||
if (lncount > 3 || (lncount > 1 && no_intty))
|
if (lncount > 3 || (lncount > 1 && no_intty))
|
||||||
{
|
{
|
||||||
pr ("\n");
|
putchar('\n');
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
pr(_("...skipping\n"));
|
putsout(_("...skipping\n"));
|
||||||
}
|
}
|
||||||
if (!no_intty) {
|
if (!no_intty) {
|
||||||
Currline -= (lncount >= 3 ? 3 : lncount);
|
Currline -= (lncount >= 3 ? 3 : lncount);
|
||||||
|
@ -1663,8 +1552,7 @@ void search(char buf[], FILE *file, register int n)
|
||||||
else
|
else
|
||||||
doclear ();
|
doclear ();
|
||||||
}
|
}
|
||||||
pr (Line);
|
puts(Line);
|
||||||
putchar ('\n');
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1681,7 +1569,7 @@ void search(char buf[], FILE *file, register int n)
|
||||||
Fseek (file, startline);
|
Fseek (file, startline);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
pr (_("\nPattern not found\n"));
|
putsout(_("\nPattern not found\n"));
|
||||||
end_it (0);
|
end_it (0);
|
||||||
}
|
}
|
||||||
error (_("Pattern not found"));
|
error (_("Pattern not found"));
|
||||||
|
@ -1731,7 +1619,7 @@ void execute (char *filename, char *cmd, ...)
|
||||||
va_end(argp);
|
va_end(argp);
|
||||||
|
|
||||||
execvp (cmd, args);
|
execvp (cmd, args);
|
||||||
errwrite(_("exec failed\n"));
|
putserr(_("exec failed\n"));
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
if (id > 0) {
|
if (id > 0) {
|
||||||
|
@ -1745,9 +1633,9 @@ void execute (char *filename, char *cmd, ...)
|
||||||
if (catch_susp)
|
if (catch_susp)
|
||||||
signal(SIGTSTP, onsusp);
|
signal(SIGTSTP, onsusp);
|
||||||
} else
|
} else
|
||||||
errwrite(_("can't fork\n"));
|
putserr(_("can't fork\n"));
|
||||||
set_tty ();
|
set_tty ();
|
||||||
pr ("------------------------\n");
|
puts("------------------------");
|
||||||
prompt (filename);
|
prompt (filename);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1784,19 +1672,17 @@ void skipf (register int nskip)
|
||||||
fnum += nskip;
|
fnum += nskip;
|
||||||
if (fnum < 0)
|
if (fnum < 0)
|
||||||
fnum = 0;
|
fnum = 0;
|
||||||
pr (_("\n...Skipping "));
|
puts(_("\n...Skipping "));
|
||||||
pr ("\n");
|
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
if (nskip > 0)
|
if (nskip > 0)
|
||||||
pr (_("...Skipping to file "));
|
putsout(_("...Skipping to file "));
|
||||||
else
|
else
|
||||||
pr (_("...Skipping back to file "));
|
putsout(_("...Skipping back to file "));
|
||||||
pr (fnames[fnum]);
|
puts(fnames[fnum]);
|
||||||
pr ("\n");
|
|
||||||
if (clreol)
|
if (clreol)
|
||||||
cleareol ();
|
cleareol ();
|
||||||
pr ("\n");
|
putchar('\n');
|
||||||
--fnum;
|
--fnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1946,9 +1832,9 @@ static char *BSB = "\b \b";
|
||||||
static char *CARAT = "^";
|
static char *CARAT = "^";
|
||||||
#define ERASEONECOLUMN \
|
#define ERASEONECOLUMN \
|
||||||
if (docrterase) \
|
if (docrterase) \
|
||||||
errwrite(BSB); \
|
putserr(BSB); \
|
||||||
else \
|
else \
|
||||||
errwrite(BS);
|
putserr(BS);
|
||||||
|
|
||||||
void ttyin (unsigned char buf[], register int nmax, char pchar) {
|
void ttyin (unsigned char buf[], register int nmax, char pchar) {
|
||||||
unsigned char *sp;
|
unsigned char *sp;
|
||||||
|
@ -2040,7 +1926,7 @@ void ttyin (unsigned char buf[], register int nmax, char pchar) {
|
||||||
erasep (1);
|
erasep (1);
|
||||||
else if (docrtkill)
|
else if (docrtkill)
|
||||||
while (promptlen-- > 1)
|
while (promptlen-- > 1)
|
||||||
errwrite(BSB);
|
putserr(BSB);
|
||||||
promptlen = 1;
|
promptlen = 1;
|
||||||
}
|
}
|
||||||
sp = buf;
|
sp = buf;
|
||||||
|
@ -2057,12 +1943,11 @@ void ttyin (unsigned char buf[], register int nmax, char pchar) {
|
||||||
*sp++ = c;
|
*sp++ = c;
|
||||||
if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) {
|
if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) {
|
||||||
c += (c == RUBOUT) ? -0100 : 0100;
|
c += (c == RUBOUT) ? -0100 : 0100;
|
||||||
errwrite(CARAT);
|
putserr(CARAT);
|
||||||
promptlen++;
|
promptlen++;
|
||||||
}
|
}
|
||||||
if (c != '\n' && c != ESC) {
|
if (c != '\n' && c != ESC) {
|
||||||
char cbuf = c;
|
putcerr(c);
|
||||||
errwrite1(&cbuf);
|
|
||||||
promptlen++;
|
promptlen++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -2134,28 +2019,15 @@ int expand (char **outbuf, char *inbuf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void show (char c) {
|
void show (char c) {
|
||||||
char cbuf;
|
|
||||||
|
|
||||||
if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) {
|
if ((c < ' ' && c != '\n' && c != ESC) || c == RUBOUT) {
|
||||||
c += (c == RUBOUT) ? -0100 : 0100;
|
c += (c == RUBOUT) ? -0100 : 0100;
|
||||||
errwrite(CARAT);
|
putserr(CARAT);
|
||||||
promptlen++;
|
promptlen++;
|
||||||
}
|
}
|
||||||
cbuf = c;
|
putcerr(c);
|
||||||
errwrite1(&cbuf);
|
|
||||||
promptlen++;
|
promptlen++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void errwrite (char *txt)
|
|
||||||
{
|
|
||||||
write (fileno(stderr), txt, strlen(txt));
|
|
||||||
}
|
|
||||||
|
|
||||||
void errwrite1 (char *sym)
|
|
||||||
{
|
|
||||||
write (fileno(stderr), sym, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void error (char *mess)
|
void error (char *mess)
|
||||||
{
|
{
|
||||||
if (clreol)
|
if (clreol)
|
||||||
|
@ -2165,11 +2037,11 @@ void error (char *mess)
|
||||||
promptlen += strlen (mess);
|
promptlen += strlen (mess);
|
||||||
if (Senter && Sexit) {
|
if (Senter && Sexit) {
|
||||||
my_putstring (Senter);
|
my_putstring (Senter);
|
||||||
pr(mess);
|
putsout(mess);
|
||||||
my_putstring (Sexit);
|
my_putstring (Sexit);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pr (mess);
|
putsout(mess);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
errors++;
|
errors++;
|
||||||
siglongjmp (restore, 1);
|
siglongjmp (restore, 1);
|
||||||
|
@ -2185,7 +2057,7 @@ void set_tty () {
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ourputch(int c) {
|
ourputch(int c) {
|
||||||
return putc(c, stdout);
|
return putc(c, stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -2193,7 +2065,7 @@ reset_tty () {
|
||||||
if (no_tty)
|
if (no_tty)
|
||||||
return;
|
return;
|
||||||
if (pstate) {
|
if (pstate) {
|
||||||
tputs(ULexit, 1, ourputch);
|
tputs(ULexit, 1, ourputch); /* putchar - if that isnt a macro */
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
pstate = 0;
|
pstate = 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue