diff --git a/configure.ac b/configure.ac index ed3a65d06..974ac0bc5 100644 --- a/configure.ac +++ b/configure.ac @@ -310,6 +310,7 @@ AC_CHECK_FUNCS([ \ getexecname \ getmntinfo \ getrlimit \ + getsgnam \ inotify_init \ inotify_init1 \ jrand48 \ diff --git a/disk-utils/mkfs.minix.c b/disk-utils/mkfs.minix.c index 9fdfc6379..2dafc869f 100644 --- a/disk-utils/mkfs.minix.c +++ b/disk-utils/mkfs.minix.c @@ -362,9 +362,11 @@ static void make_bad_inode_v2_v3 (void) static void make_bad_inode(void) { - if (fs_version < 2) - return make_bad_inode_v1(); - return make_bad_inode_v2_v3(); + if (fs_version < 2) { + make_bad_inode_v1(); + return; + } + make_bad_inode_v2_v3(); } static void make_root_inode_v1(void) { @@ -412,9 +414,11 @@ static void make_root_inode_v2_v3 (void) { static void make_root_inode(void) { - if (fs_version < 2) - return make_root_inode_v1(); - return make_root_inode_v2_v3(); + if (fs_version < 2) { + make_root_inode_v1(); + return; + } + make_root_inode_v2_v3(); } static void super_set_nzones(void) diff --git a/include/Makemodule.am b/include/Makemodule.am index bb8aac58b..d162d24b4 100644 --- a/include/Makemodule.am +++ b/include/Makemodule.am @@ -49,7 +49,6 @@ dist_noinst_HEADERS += \ include/ttyutils.h \ include/widechar.h \ include/xalloc.h \ - include/xgetpass.h \ include/pt-sgi.h \ include/pt-bsd.h \ include/pt-mbr.h \ diff --git a/include/carefulputc.h b/include/carefulputc.h index f29dc699f..c116d0a98 100644 --- a/include/carefulputc.h +++ b/include/carefulputc.h @@ -10,26 +10,22 @@ #include #include -#define iso8859x_iscntrl(c) \ - (((c) & 0x7f) < 0x20 || (c) == 0x7f) - -static inline int fputc_careful(int c, FILE *fp, const char fail) { +static inline int fputc_careful(int c, FILE *fp, const char fail) +{ int ret; - if (c == '\007' || c == '\t' || c == '\r' || c == '\n' || - (!iso8859x_iscntrl(c) && (isprint(c) || isspace(c)))) + if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n') ret = putc(c, fp); - else if ((c & 0x80) || !isprint(c^0x40)) - ret = fprintf(fp, "\\%3o", (unsigned char) c); + else if (!isascii(c)) + ret = fprintf(fp, "\\%3o", (unsigned char)c); else { ret = putc(fail, fp); if (ret != EOF) - ret = putc(c^0x40, fp); + ret = putc(c ^ 0x40, fp); } return (ret < 0) ? EOF : 0; } - static inline void fputs_quoted(const char *data, FILE *out) { const char *p; diff --git a/include/xgetpass.h b/include/xgetpass.h deleted file mode 100644 index b5a3c87de..000000000 --- a/include/xgetpass.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef UTIL_LINUX_XGETPASS_H -#define UTIL_LINUX_XGETPASS_H - -extern char *xgetpass(int pfd, const char *prompt); - -#endif /* UTIL_LINUX_XGETPASS_H */ diff --git a/lib/Makemodule.am b/lib/Makemodule.am index 78298691b..645090215 100644 --- a/lib/Makemodule.am +++ b/lib/Makemodule.am @@ -24,7 +24,6 @@ libcommon_la_SOURCES = \ lib/sysfs.c \ lib/timeutils.c \ lib/ttyutils.c \ - lib/xgetpass.c \ lib/exec_shell.c \ lib/readutmp.c diff --git a/lib/xgetpass.c b/lib/xgetpass.c deleted file mode 100644 index ba2089470..000000000 --- a/lib/xgetpass.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * A function to read the passphrase either from the terminal or from - * an open file descriptor. - * - * Public domain. - */ - -#include -#include -#include -#include -#include -#include - -#include "c.h" -#include "xgetpass.h" - -char *xgetpass(int pfd, const char *prompt) -{ - char *pass = NULL; - int len = 0, i; - - if (pfd < 0) /* terminal */ - return getpass(prompt); - - for (i=0; ; i++) { - if (i >= len-1) { - char *tmppass = pass; - len += 128; - - pass = realloc(tmppass, len); - if (!pass) { - pass = tmppass; /* the old buffer hasn't changed */ - break; - } - } - if (pass && (read(pfd, pass + i, 1) != 1 || - pass[i] == '\n' || pass[i] == 0)) - break; - } - - if (pass) - pass[i] = '\0'; - return pass; -} - diff --git a/libuuid/src/uuid.h b/libuuid/src/uuid.h index 874d65a19..30bd4c0e0 100644 --- a/libuuid/src/uuid.h +++ b/libuuid/src/uuid.h @@ -67,35 +67,35 @@ extern "C" { #endif /* clear.c */ -void uuid_clear(uuid_t uu); +extern void uuid_clear(uuid_t uu); /* compare.c */ -int uuid_compare(const uuid_t uu1, const uuid_t uu2); +extern int uuid_compare(const uuid_t uu1, const uuid_t uu2); /* copy.c */ -void uuid_copy(uuid_t dst, const uuid_t src); +extern void uuid_copy(uuid_t dst, const uuid_t src); /* gen_uuid.c */ -void uuid_generate(uuid_t out); -void uuid_generate_random(uuid_t out); -void uuid_generate_time(uuid_t out); -int uuid_generate_time_safe(uuid_t out); +extern void uuid_generate(uuid_t out); +extern void uuid_generate_random(uuid_t out); +extern void uuid_generate_time(uuid_t out); +extern int uuid_generate_time_safe(uuid_t out); /* isnull.c */ -int uuid_is_null(const uuid_t uu); +extern int uuid_is_null(const uuid_t uu); /* parse.c */ -int uuid_parse(const char *in, uuid_t uu); +extern int uuid_parse(const char *in, uuid_t uu); /* unparse.c */ -void uuid_unparse(const uuid_t uu, char *out); -void uuid_unparse_lower(const uuid_t uu, char *out); -void uuid_unparse_upper(const uuid_t uu, char *out); +extern void uuid_unparse(const uuid_t uu, char *out); +extern void uuid_unparse_lower(const uuid_t uu, char *out); +extern void uuid_unparse_upper(const uuid_t uu, char *out); /* uuid_time.c */ -time_t uuid_time(const uuid_t uu, struct timeval *ret_tv); -int uuid_type(const uuid_t uu); -int uuid_variant(const uuid_t uu); +extern time_t uuid_time(const uuid_t uu, struct timeval *ret_tv); +extern int uuid_type(const uuid_t uu); +extern int uuid_variant(const uuid_t uu); #ifdef __cplusplus } diff --git a/login-utils/last.c b/login-utils/last.c index f7a2576f4..54d9e1f8e 100644 --- a/login-utils/last.c +++ b/login-utils/last.c @@ -376,9 +376,9 @@ static void trim_trailing_spaces(char *s) /* * Show one line of information on screen */ -static int list(const struct last_control *ctl, struct utmp *p, time_t t, int what) +static int list(const struct last_control *ctl, struct utmp *p, time_t logout_time, int what) { - time_t secs, tmp, epoch; + time_t secs, utmp_time, now; char logintime[LAST_TIMESTAMP_LEN]; char logouttime[LAST_TIMESTAMP_LEN]; char length[LAST_TIMESTAMP_LEN]; @@ -417,22 +417,25 @@ static int list(const struct last_control *ctl, struct utmp *p, time_t t, int wh /* * Calculate times */ - tmp = p->UL_UT_TIME; + utmp_time = p->UL_UT_TIME; - if (ctl->present && (ctl->present < tmp || (0 < t && t < ctl->present))) - return 0; - - if (time_formatter(ctl, &logintime[0], sizeof(logintime), &tmp, 0) < 0 || - time_formatter(ctl, &logouttime[0], sizeof(logouttime), &t, 1) < 0) + if (ctl->present) { + if (ctl->present < utmp_time) + return 0; + if (0 < logout_time && logout_time < ctl->present) + return 0; + } + if (time_formatter(ctl, &logintime[0], sizeof(logintime), &utmp_time, 0) < 0 || + time_formatter(ctl, &logouttime[0], sizeof(logouttime), &logout_time, 1) < 0) errx(EXIT_FAILURE, _("preallocation size exceeded")); - secs = t - p->UL_UT_TIME; + secs = logout_time - utmp_time; mins = (secs / 60) % 60; hours = (secs / 3600) % 24; days = secs / 86400; - epoch = time(NULL); - if (t == epoch) { + now = time(NULL); + if (logout_time == now) { if (ctl->time_fmt > LAST_TIMEFTM_SHORT_CTIME) { sprintf(logouttime, " still running"); length[0] = 0; @@ -582,8 +585,6 @@ static int is_phantom(const struct last_control *ctl, struct utmp *ut) { struct passwd *pw; char path[32]; - FILE *f = NULL; - unsigned int loginuid; int ret = 0; if (ut->UL_UT_TIME < ctl->boot_time.tv_sec) @@ -592,14 +593,26 @@ static int is_phantom(const struct last_control *ctl, struct utmp *ut) if (!pw) return 1; sprintf(path, "/proc/%u/loginuid", ut->ut_pid); - if (access(path, R_OK) != 0 || !(f = fopen(path, "r"))) - return 1; + if (access(path, R_OK) == 0) { + unsigned int loginuid; + FILE *f = NULL; - if (fscanf(f, "%u", &loginuid) != 1) - ret = 1; - fclose(f); - if (!ret && pw->pw_uid != loginuid) - return 1; + if (!(f = fopen(path, "r"))) + return 1; + if (fscanf(f, "%u", &loginuid) != 1) + ret = 1; + fclose(f); + if (!ret && pw->pw_uid != loginuid) + return 1; + } else { + struct stat st; + + sprintf(path, "/dev/%s", ut->ut_line); + if (stat(path, &st)) + return 1; + if (pw->pw_uid != st.st_uid) + return 1; + } return ret; } diff --git a/login-utils/newgrp.c b/login-utils/newgrp.c index 55dad1bb4..9c0f8f581 100644 --- a/login-utils/newgrp.c +++ b/login-utils/newgrp.c @@ -22,21 +22,75 @@ #include #include #include +#include #include #ifdef HAVE_CRYPT_H # include #endif +#ifdef HAVE_GETSGNAM +# include +#endif + #include "c.h" #include "closestream.h" #include "nls.h" #include "pathnames.h" #include "xalloc.h" +static char *xgetpass(FILE *input, const char *prompt) +{ + char *pass = NULL; + struct termios saved, no_echo; + const int fd = fileno(input); + size_t dummy = 0; + ssize_t len; + + fputs(prompt, stdout); + if (isatty(fd)) { + /* disable echo */ + tcgetattr(fd, &saved); + no_echo = saved; + no_echo.c_lflag &= ~ECHO; + no_echo.c_lflag |= ECHONL; + if (tcsetattr(fd, TCSANOW, &no_echo)) + err(EXIT_FAILURE, _("could not set terminal attributes")); + } + len = getline(&pass, &dummy, input); + if (isatty(fd)) + /* restore terminal */ + if (tcsetattr(fd, TCSANOW, &saved)) + err(EXIT_FAILURE, _("could not set terminal attributes")); + if (len < 0) + err(EXIT_FAILURE, _("could not getline")); + if (0 < len && *(pass + len - 1) == '\n') + *(pass + len - 1) = '\0'; + return pass; +} + +/* Ensure memory is set to value c without compiler optimization getting + * into way that could happen with memset(3). */ +static int memset_s(void *v, size_t sz, const int c) +{ + volatile unsigned char *p = v; + + if (v == NULL) + return EINVAL; + while (sz--) + *p++ = c; + return 0; +} + /* try to read password from gshadow */ static char *get_gshadow_pwd(char *groupname) { +#ifdef HAVE_GETSGNAM + struct sgrp *sgrp; + + sgrp = getsgnam(groupname); + return sgrp ? xstrdup(sgrp->sg_passwd) : NULL; +#else char buf[BUFSIZ]; char *pwd = NULL; FILE *f; @@ -69,6 +123,7 @@ static char *get_gshadow_pwd(char *groupname) } fclose(f); return pwd ? xstrdup(pwd) : NULL; +#endif /* HAVE_GETSGNAM */ } static int allow_setgid(struct passwd *pe, struct group *ge) @@ -99,11 +154,13 @@ static int allow_setgid(struct passwd *pe, struct group *ge) if (!(pwd = get_gshadow_pwd(ge->gr_name))) pwd = ge->gr_passwd; - if (pwd && *pwd && (xpwd = getpass(_("Password: ")))) { + if (pwd && *pwd && (xpwd = xgetpass(stdin, _("Password: ")))) { char *cbuf = crypt(xpwd, pwd); + memset_s(xpwd, strlen(xpwd), 0); + free(xpwd); if (!cbuf) - warn(_("crypt() failed")); + warn(_("crypt failed")); else if (strcmp(pwd, cbuf) == 0) return TRUE; } diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am index b75d5e005..c7cd95f82 100644 --- a/sys-utils/Makemodule.am +++ b/sys-utils/Makemodule.am @@ -359,8 +359,7 @@ PATHFILES += sys-utils/hwclock.8 hwclock_SOURCES = \ sys-utils/hwclock.c \ sys-utils/hwclock.h \ - sys-utils/hwclock-cmos.c \ - sys-utils/hwclock-kd.c + sys-utils/hwclock-cmos.c if LINUX hwclock_SOURCES += sys-utils/hwclock-rtc.c endif diff --git a/sys-utils/eject.c b/sys-utils/eject.c index 03744c7e7..91f1102ab 100644 --- a/sys-utils/eject.c +++ b/sys-utils/eject.c @@ -81,31 +81,34 @@ static const char * const hotplug_subsystems[] = { "ccw" }; -/* Global Variables */ -static int a_option; /* command flags and arguments */ -static int c_option; -static int d_option; -static int f_option; -static int F_option; -static int n_option; -static int q_option; -static int r_option; -static int s_option; -static int t_option; -static int T_option; -static int X_option; -static int v_option; -static int x_option; -static int p_option; -static int m_option; -static int M_option; -static int i_option; -static int a_arg; -static int i_arg; -static long int c_arg; -static long int x_arg; - -struct libmnt_table *mtab; +struct eject_control { + struct libmnt_table *mtab; + char *device; /* device or mount point to be ejected */ + int fd; /* file descriptor for device */ + unsigned int /* command flags and arguments */ + a_option:1, + c_option:1, + d_option:1, + F_option:1, + f_option:1, + i_option:1, + M_option:1, + m_option:1, + n_option:1, + p_option:1, + q_option:1, + r_option:1, + s_option:1, + T_option:1, + t_option:1, + v_option:1, + X_option:1, + x_option:1, + a_arg:1, + i_arg:1; + long int c_arg; /* changer slot number */ + long int x_arg; /* cd speed */ +}; static void vinfo(const char *fmt, va_list va) { @@ -114,11 +117,11 @@ static void vinfo(const char *fmt, va_list va) fputc('\n', stdout); } -static inline void verbose(const char *fmt, ...) +static inline void verbose(const struct eject_control *ctl, const char *fmt, ...) { va_list va; - if (!v_option) + if (!ctl->v_option) return; va_start(va, fmt); @@ -174,7 +177,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out) /* Handle command line options. */ -static void parse_args(int argc, char **argv, char **device) +static void parse_args(struct eject_control *ctl, int argc, char **argv) { static const struct option long_opts[] = { @@ -206,75 +209,75 @@ static void parse_args(int argc, char **argv, char **device) "a:c:i:x:dfFhnqrstTXvVpmM", long_opts, NULL)) != -1) { switch (c) { case 'a': - a_option = 1; + ctl->a_option = 1; if (!strcmp(optarg, "0") || !strcmp(optarg, "off")) - a_arg = 0; + ctl->a_arg = 0; else if (!strcmp(optarg, "1") || !strcmp(optarg, "on")) - a_arg = 1; + ctl->a_arg = 1; else errx(EXIT_FAILURE, _("invalid argument to --auto/-a option")); break; case 'c': - c_option = 1; - c_arg = strtoul_or_err(optarg, _("invalid argument to --changerslot/-c option")); + ctl->c_option = 1; + ctl->c_arg = strtoul_or_err(optarg, _("invalid argument to --changerslot/-c option")); break; case 'x': - x_option = 1; - x_arg = strtoul_or_err(optarg, _("invalid argument to --cdspeed/-x option")); + ctl->x_option = 1; + ctl->x_arg = strtoul_or_err(optarg, _("invalid argument to --cdspeed/-x option")); break; case 'd': - d_option = 1; + ctl->d_option = 1; break; case 'f': - f_option = 1; + ctl->f_option = 1; break; case 'F': - F_option = 1; + ctl->F_option = 1; break; case 'h': usage(stdout); break; case 'i': - i_option = 1; + ctl->i_option = 1; if (!strcmp(optarg, "0") || !strcmp(optarg, "off")) - i_arg = 0; + ctl->i_arg = 0; else if (!strcmp(optarg, "1") || !strcmp(optarg, "on")) - i_arg = 1; + ctl->i_arg = 1; else errx(EXIT_FAILURE, _("invalid argument to --manualeject/-i option")); break; case 'm': - m_option = 1; + ctl->m_option = 1; break; case 'M': - M_option = 1; + ctl->M_option = 1; break; case 'n': - n_option = 1; + ctl->n_option = 1; break; case 'p': - p_option = 1; + ctl->p_option = 1; break; case 'q': - q_option = 1; + ctl->q_option = 1; break; case 'r': - r_option = 1; + ctl->r_option = 1; break; case 's': - s_option = 1; + ctl->s_option = 1; break; case 't': - t_option = 1; + ctl->t_option = 1; break; case 'T': - T_option = 1; + ctl->T_option = 1; break; case 'X': - X_option = 1; + ctl->X_option = 1; break; case 'v': - v_option = 1; + ctl->v_option = 1; break; case 'V': printf(UTIL_LINUX_VERSION); @@ -292,7 +295,7 @@ static void parse_args(int argc, char **argv, char **device) errx(EXIT_FAILURE, _("too many arguments")); if ((argc - optind) == 1) - *device = xstrdup(argv[optind]); + ctl->device = xstrdup(argv[optind]); } /* @@ -323,15 +326,15 @@ static char *find_device(const char *name) } /* Set or clear auto-eject mode. */ -static void auto_eject(int fd, int on) +static void auto_eject(const struct eject_control *ctl) { int status = -1; #if defined(CDROM_SET_OPTIONS) && defined(CDROM_CLEAR_OPTIONS) - if (on) - status = ioctl(fd, CDROM_SET_OPTIONS, CDO_AUTO_EJECT); + if (ctl->a_arg) + status = ioctl(ctl->fd, CDROM_SET_OPTIONS, CDO_AUTO_EJECT); else - status = ioctl(fd, CDROM_CLEAR_OPTIONS, CDO_AUTO_EJECT); + status = ioctl(ctl->fd, CDROM_CLEAR_OPTIONS, CDO_AUTO_EJECT); #else errno = ENOSYS; #endif @@ -350,12 +353,12 @@ static void auto_eject(int fd, int on) * EBUSY Attempt to unlock when multiple users * have the drive open and not CAP_SYS_ADMIN */ -static void manual_eject(int fd, int on) +static void manual_eject(const struct eject_control *ctl) { - if (ioctl(fd, CDROM_LOCKDOOR, on) < 0) + if (ioctl(ctl->fd, CDROM_LOCKDOOR, ctl->i_arg) < 0) err(EXIT_FAILURE, _("CD-ROM lock door command failed")); - if (on) + if (ctl->i_arg) info(_("CD-Drive may NOT be ejected with device button")); else info(_("CD-Drive may be ejected with device button")); @@ -365,14 +368,14 @@ static void manual_eject(int fd, int on) * Changer select. CDROM_SELECT_DISC is preferred, older kernels used * CDROMLOADFROMSLOT. */ -static void changer_select(int fd, int slot) +static void changer_select(const struct eject_control *ctl) { #ifdef CDROM_SELECT_DISC - if (ioctl(fd, CDROM_SELECT_DISC, slot) < 0) + if (ioctl(ctl->fd, CDROM_SELECT_DISC, ctl->c_arg) < 0) err(EXIT_FAILURE, _("CD-ROM select disc command failed")); #elif defined CDROMLOADFROMSLOT - if (ioctl(fd, CDROMLOADFROMSLOT, slot) != 0) + if (ioctl(ctl->fd, CDROMLOADFROMSLOT, ctl->c_arg) != 0) err(EXIT_FAILURE, _("CD-ROM load from slot command failed")); #else warnx(_("IDE/ATAPI CD-ROM changer not supported by this kernel\n") ); @@ -485,10 +488,10 @@ static void toggle_tray(int fd) * Thanks to Roland Krivanek (krivanek@fmph.uniba.sk) * http://dmpc.dbp.fmph.uniba.sk/~krivanek/cdrom_speed/ */ -static void select_speed(int fd, int speed) +static void select_speed(const struct eject_control *ctl) { #ifdef CDROM_SELECT_SPEED - if (ioctl(fd, CDROM_SELECT_SPEED, speed) != 0) + if (ioctl(ctl->fd, CDROM_SELECT_SPEED, ctl->x_arg) != 0) err(EXIT_FAILURE, _("CD-ROM select speed command failed")); #else warnx(_("CD-ROM select speed command not supported by this kernel")); @@ -557,22 +560,22 @@ static int read_speed(const char *devname) /* * List Speed of CD-ROM drive. */ -static void list_speeds(const char *name, int fd) +static void list_speeds(struct eject_control *ctl) { #ifdef CDROM_SELECT_SPEED - int max_speed, curr_speed = 0, prev_speed; + int max_speed, curr_speed = 0; - select_speed(fd, 0); - max_speed = read_speed(name); + select_speed(ctl); + max_speed = read_speed(ctl->device); while (curr_speed < max_speed) { - prev_speed = curr_speed; - select_speed(fd, prev_speed + 1); - curr_speed = read_speed(name); - if (curr_speed > prev_speed) + ctl->x_arg = curr_speed + 1; + select_speed(ctl); + curr_speed = read_speed(ctl->device); + if (ctl->x_arg < curr_speed) printf("%d ", curr_speed); else - curr_speed = prev_speed + 1; + curr_speed = ctl->x_arg + 1; } printf("\n"); @@ -584,7 +587,7 @@ static void list_speeds(const char *name, int fd) /* * Eject using SCSI SG_IO commands. Return 1 if successful, 0 otherwise. */ -static int eject_scsi(int fd) +static int eject_scsi(const struct eject_control *ctl) { int status, k; sg_io_hdr_t io_hdr; @@ -594,8 +597,8 @@ static int eject_scsi(int fd) unsigned char inqBuff[2]; unsigned char sense_buffer[32]; - if ((ioctl(fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) { - verbose(_("not an sg device, or old sg driver")); + if ((ioctl(ctl->fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) { + verbose(ctl, _("not an sg device, or old sg driver")); return 0; } @@ -610,12 +613,12 @@ static int eject_scsi(int fd) io_hdr.timeout = 10000; io_hdr.cmdp = allowRmBlk; - status = ioctl(fd, SG_IO, (void *)&io_hdr); + status = ioctl(ctl->fd, SG_IO, (void *)&io_hdr); if (status < 0 || io_hdr.host_status || io_hdr.driver_status) return 0; io_hdr.cmdp = startStop1Blk; - status = ioctl(fd, SG_IO, (void *)&io_hdr); + status = ioctl(ctl->fd, SG_IO, (void *)&io_hdr); if (status < 0 || io_hdr.host_status) return 0; @@ -630,12 +633,12 @@ static int eject_scsi(int fd) return 0; io_hdr.cmdp = startStop2Blk; - status = ioctl(fd, SG_IO, (void *)&io_hdr); + status = ioctl(ctl->fd, SG_IO, (void *)&io_hdr); if (status < 0 || io_hdr.host_status || io_hdr.driver_status) return 0; /* force kernel to reread partition table when new disc inserted */ - ioctl(fd, BLKRRPART); + ioctl(ctl->fd, BLKRRPART); return 1; } @@ -660,14 +663,14 @@ static int eject_tape(int fd) /* umount a device. */ -static void umount_one(const char *name) +static void umount_one(const struct eject_control *ctl, const char *name) { int status; if (!name) return; - verbose(_("%s: unmounting"), name); + verbose(ctl, _("%s: unmounting"), name); switch (fork()) { case 0: /* child */ @@ -677,7 +680,7 @@ static void umount_one(const char *name) if (setuid(getuid()) < 0) err(EXIT_FAILURE, _("cannot set user id")); - if (p_option) + if (ctl->p_option) execl("/bin/umount", "/bin/umount", name, "-n", NULL); else execl("/bin/umount", "/bin/umount", name, NULL); @@ -701,51 +704,49 @@ static void umount_one(const char *name) } /* Open a device file. */ -static int open_device(const char *name) +static void open_device(struct eject_control *ctl) { - int fd = open(name, O_RDWR|O_NONBLOCK); - - if (fd < 0) - fd = open(name, O_RDONLY|O_NONBLOCK); - if (fd == -1) - err(EXIT_FAILURE, _("cannot open %s"), name); - return fd; + ctl->fd = open(ctl->device, O_RDWR | O_NONBLOCK); + if (ctl->fd < 0) + ctl->fd = open(ctl->device, O_RDONLY | O_NONBLOCK); + if (ctl->fd == -1) + err(EXIT_FAILURE, _("cannot open %s"), ctl->device); } /* * See if device has been mounted by looking in mount table. If so, set * device name and mount point name, and return 1, otherwise return 0. */ -static int device_get_mountpoint(char **devname, char **mnt) +static int device_get_mountpoint(struct eject_control *ctl, char **devname, char **mnt) { struct libmnt_fs *fs; int rc; *mnt = NULL; - if (!mtab) { + if (!ctl->mtab) { struct libmnt_cache *cache; - mtab = mnt_new_table(); - if (!mtab) + ctl->mtab = mnt_new_table(); + if (!ctl->mtab) err(EXIT_FAILURE, _("failed to initialize libmount table")); cache = mnt_new_cache(); - mnt_table_set_cache(mtab, cache); + mnt_table_set_cache(ctl->mtab, cache); mnt_unref_cache(cache); - if (p_option) - rc = mnt_table_parse_file(mtab, _PATH_PROC_MOUNTINFO); + if (ctl->p_option) + rc = mnt_table_parse_file(ctl->mtab, _PATH_PROC_MOUNTINFO); else - rc = mnt_table_parse_mtab(mtab, NULL); + rc = mnt_table_parse_mtab(ctl->mtab, NULL); if (rc) err(EXIT_FAILURE, _("failed to parse mount table")); } - fs = mnt_table_find_source(mtab, *devname, MNT_ITER_BACKWARD); + fs = mnt_table_find_source(ctl->mtab, *devname, MNT_ITER_BACKWARD); if (!fs) { /* maybe 'devname' is mountpoint rather than a real device */ - fs = mnt_table_find_target(mtab, *devname, MNT_ITER_BACKWARD); + fs = mnt_table_find_target(ctl->mtab, *devname, MNT_ITER_BACKWARD); if (fs) { free(*devname); *devname = xstrdup(mnt_fs_get_source(fs)); @@ -774,7 +775,7 @@ static char *get_disk_devname(const char *device) return st.st_rdev == diskno ? NULL : find_device(diskname); } -static int umount_partitions(const char *disk, int checkonly) +static int umount_partitions(struct eject_control *ctl) { struct sysfs_cxt cxt = UL_SYSFSCXT_EMPTY; dev_t devno; @@ -782,7 +783,7 @@ static int umount_partitions(const char *disk, int checkonly) struct dirent *d; int count = 0; - devno = sysfs_devname_to_devno(disk, NULL); + devno = sysfs_devname_to_devno(ctl->device, NULL); if (sysfs_init(&cxt, devno, NULL) != 0) return 0; @@ -795,14 +796,14 @@ static int umount_partitions(const char *disk, int checkonly) if (!strcmp(d->d_name, ".") || !strcmp(d->d_name, "..")) continue; - if (sysfs_is_partition_dirent(dir, d, disk)) { + if (sysfs_is_partition_dirent(dir, d, ctl->device)) { char *mnt = NULL; char *dev = find_device(d->d_name); - if (dev && device_get_mountpoint(&dev, &mnt) == 0) { - verbose(_("%s: mounted on %s"), dev, mnt); - if (!checkonly) - umount_one(mnt); + if (dev && device_get_mountpoint(ctl, &dev, &mnt) == 0) { + verbose(ctl, _("%s: mounted on %s"), dev, mnt); + if (!ctl->M_option) + umount_one(ctl, mnt); count++; } free(dev); @@ -881,7 +882,7 @@ static char *get_subsystem(char *chain, char *buf, size_t bufsz) return NULL; } -static int is_hotpluggable(const char* device) +static int is_hotpluggable(const struct eject_control *ctl) { struct sysfs_cxt cxt = UL_SYSFSCXT_EMPTY; char devchain[PATH_MAX]; @@ -891,13 +892,13 @@ static int is_hotpluggable(const char* device) ssize_t sz; char *sub; - devno = sysfs_devname_to_devno(device, NULL); + devno = sysfs_devname_to_devno(ctl->device, NULL); if (sysfs_init(&cxt, devno, NULL) != 0) return 0; /* check /sys/dev/block/:/removable attribute */ if (sysfs_read_int(&cxt, "removable", &rc) == 0 && rc == 1) { - verbose(_("%s: is removable device"), device); + verbose(ctl, _("%s: is removable device"), ctl->device); goto done; } @@ -916,8 +917,8 @@ static int is_hotpluggable(const char* device) while ((sub = get_subsystem(devchain, subbuf, sizeof(subbuf)))) { rc = is_hotpluggable_subsystem(sub); if (rc) { - verbose(_("%s: connected by hotplug subsystem: %s"), - device, sub); + verbose(ctl, _("%s: connected by hotplug subsystem: %s"), + ctl->device, sub); break; } } @@ -929,20 +930,18 @@ done: /* handle -x option */ -static void set_device_speed(char *name) +static void set_device_speed(struct eject_control *ctl) { - int fd; - - if (!x_option) + if (!ctl->x_option) return; - if (x_arg == 0) - verbose(_("setting CD-ROM speed to auto")); + if (ctl->x_arg == 0) + verbose(ctl, _("setting CD-ROM speed to auto")); else - verbose(_("setting CD-ROM speed to %ldX"), x_arg); + verbose(ctl, _("setting CD-ROM speed to %ldX"), ctl->x_arg); - fd = open_device(name); - select_speed(fd, x_arg); + open_device(ctl); + select_speed(ctl); exit(EXIT_SUCCESS); } @@ -950,11 +949,10 @@ static void set_device_speed(char *name) /* main program */ int main(int argc, char **argv) { - char *device = NULL; char *disk = NULL; char *mountpoint = NULL; int worked = 0; /* set to 1 when successfully ejected */ - int fd; /* file descriptor for device */ + struct eject_control ctl = { 0 }; setlocale(LC_ALL,""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -962,118 +960,118 @@ int main(int argc, char **argv) atexit(close_stdout); /* parse the command line arguments */ - parse_args(argc, argv, &device); + parse_args(&ctl, argc, argv); /* handle -d option */ - if (d_option) { + if (ctl.d_option) { info(_("default device: `%s'"), EJECT_DEFAULT_DEVICE); return EXIT_SUCCESS; } - if (!device) { - device = mnt_resolve_path(EJECT_DEFAULT_DEVICE, NULL); - verbose(_("using default device `%s'"), device); + if (!ctl.device) { + ctl.device = mnt_resolve_path(EJECT_DEFAULT_DEVICE, NULL); + verbose(&ctl, _("using default device `%s'"), ctl.device); } else { char *p; - if (device[strlen(device)-1] == '/') - device[strlen(device)-1] = '\0'; + if (ctl.device[strlen(ctl.device) - 1] == '/') + ctl.device[strlen(ctl.device) - 1] = '\0'; /* figure out full device or mount point name */ - p = find_device(device); + p = find_device(ctl.device); if (p) - free(device); + free(ctl.device); else - p = device; + p = ctl.device; - device = mnt_resolve_spec(p, NULL); + ctl.device = mnt_resolve_spec(p, NULL); free(p); } - if (!device) - errx(EXIT_FAILURE, _("%s: unable to find device"), device); + if (!ctl.device) + errx(EXIT_FAILURE, _("%s: unable to find device"), ctl.device); - verbose(_("device name is `%s'"), device); + verbose(&ctl, _("device name is `%s'"), ctl.device); - device_get_mountpoint(&device, &mountpoint); + device_get_mountpoint(&ctl, &ctl.device, &mountpoint); if (mountpoint) - verbose(_("%s: mounted on %s"), device, mountpoint); + verbose(&ctl, _("%s: mounted on %s"), ctl.device, mountpoint); else - verbose(_("%s: not mounted"), device); + verbose(&ctl, _("%s: not mounted"), ctl.device); - disk = get_disk_devname(device); + disk = get_disk_devname(ctl.device); if (disk) { - verbose(_("%s: disc device: %s (disk device will be used for eject)"), device, disk); - free(device); - device = disk; + verbose(&ctl, _("%s: disc device: %s (disk device will be used for eject)"), ctl.device, disk); + free(ctl.device); + ctl.device = disk; disk = NULL; } else { struct stat st; - if (stat(device, &st) != 0 || !S_ISBLK(st.st_mode)) + if (stat(ctl.device, &st) != 0 || !S_ISBLK(st.st_mode)) errx(EXIT_FAILURE, _("%s: not found mountpoint or device " - "with the given name"), device); + "with the given name"), ctl.device); - verbose(_("%s: is whole-disk device"), device); + verbose(&ctl, _("%s: is whole-disk device"), ctl.device); } - if (F_option == 0 && is_hotpluggable(device) == 0) - errx(EXIT_FAILURE, _("%s: is not hot-pluggable device"), device); + if (ctl.F_option == 0 && is_hotpluggable(&ctl) == 0) + errx(EXIT_FAILURE, _("%s: is not hot-pluggable device"), ctl.device); /* handle -n option */ - if (n_option) { - info(_("device is `%s'"), device); - verbose(_("exiting due to -n/--noop option")); + if (ctl.n_option) { + info(_("device is `%s'"), ctl.device); + verbose(&ctl, _("exiting due to -n/--noop option")); return EXIT_SUCCESS; } /* handle -i option */ - if (i_option) { - fd = open_device(device); - manual_eject(fd, i_arg); + if (ctl.i_option) { + open_device(&ctl); + manual_eject(&ctl); return EXIT_SUCCESS; } /* handle -a option */ - if (a_option) { - if (a_arg) - verbose(_("%s: enabling auto-eject mode"), device); + if (ctl.a_option) { + if (ctl.a_arg) + verbose(&ctl, _("%s: enabling auto-eject mode"), ctl.device); else - verbose(_("%s: disabling auto-eject mode"), device); - fd = open_device(device); - auto_eject(fd, a_arg); + verbose(&ctl, _("%s: disabling auto-eject mode"), ctl.device); + open_device(&ctl); + auto_eject(&ctl); return EXIT_SUCCESS; } /* handle -t option */ - if (t_option) { - verbose(_("%s: closing tray"), device); - fd = open_device(device); - close_tray(fd); - set_device_speed(device); + if (ctl.t_option) { + verbose(&ctl, _("%s: closing tray"), ctl.device); + open_device(&ctl); + close_tray(ctl.fd); + set_device_speed(&ctl); return EXIT_SUCCESS; } /* handle -T option */ - if (T_option) { - verbose(_("%s: toggling tray"), device); - fd = open_device(device); - toggle_tray(fd); - set_device_speed(device); + if (ctl.T_option) { + verbose(&ctl, _("%s: toggling tray"), ctl.device); + open_device(&ctl); + toggle_tray(ctl.fd); + set_device_speed(&ctl); return EXIT_SUCCESS; } /* handle -X option */ - if (X_option) { - verbose(_("%s: listing CD-ROM speed"), device); - fd = open_device(device); - list_speeds(device, fd); + if (ctl.X_option) { + verbose(&ctl, _("%s: listing CD-ROM speed"), ctl.device); + open_device(&ctl); + list_speeds(&ctl); return EXIT_SUCCESS; } /* handle -x option only */ - if (!c_option) - set_device_speed(device); + if (!ctl.c_option) + set_device_speed(&ctl); /* @@ -1081,62 +1079,62 @@ int main(int argc, char **argv) * mountpoint if -M is specified, otherwise print error of another * partition is mounted. */ - if (!m_option) { - int ct = umount_partitions(device, M_option); + if (!ctl.m_option) { + int ct = umount_partitions(&ctl); if (ct == 0 && mountpoint) - umount_one(mountpoint); /* probably whole-device */ + umount_one(&ctl, mountpoint); /* probably whole-device */ - if (M_option) { + if (ctl.M_option) { if (ct == 1 && mountpoint) - umount_one(mountpoint); + umount_one(&ctl, mountpoint); else if (ct) - errx(EXIT_FAILURE, _("error: %s: device in use"), device); + errx(EXIT_FAILURE, _("error: %s: device in use"), ctl.device); } } /* handle -c option */ - if (c_option) { - verbose(_("%s: selecting CD-ROM disc #%ld"), device, c_arg); - fd = open_device(device); - changer_select(fd, c_arg); - set_device_speed(device); + if (ctl.c_option) { + verbose(&ctl, _("%s: selecting CD-ROM disc #%ld"), ctl.device, ctl.c_arg); + open_device(&ctl); + changer_select(&ctl); + set_device_speed(&ctl); return EXIT_SUCCESS; } /* if user did not specify type of eject, try all four methods */ - if (r_option + s_option + f_option + q_option == 0) - r_option = s_option = f_option = q_option = 1; + if (ctl.r_option + ctl.s_option + ctl.f_option + ctl.q_option == 0) + ctl.r_option = ctl.s_option = ctl.f_option = ctl.q_option = 1; /* open device */ - fd = open_device(device); + open_device(&ctl); /* try various methods of ejecting until it works */ - if (r_option) { - verbose(_("%s: trying to eject using CD-ROM eject command"), device); - worked = eject_cdrom(fd); - verbose(worked ? _("CD-ROM eject command succeeded") : + if (ctl.r_option) { + verbose(&ctl, _("%s: trying to eject using CD-ROM eject command"), ctl.device); + worked = eject_cdrom(ctl.fd); + verbose(&ctl, worked ? _("CD-ROM eject command succeeded") : _("CD-ROM eject command failed")); } - if (s_option && !worked) { - verbose(_("%s: trying to eject using SCSI commands"), device); - worked = eject_scsi(fd); - verbose(worked ? _("SCSI eject succeeded") : + if (ctl.s_option && !worked) { + verbose(&ctl, _("%s: trying to eject using SCSI commands"), ctl.device); + worked = eject_scsi(&ctl); + verbose(&ctl, worked ? _("SCSI eject succeeded") : _("SCSI eject failed")); } - if (f_option && !worked) { - verbose(_("%s: trying to eject using floppy eject command"), device); - worked = eject_floppy(fd); - verbose(worked ? _("floppy eject command succeeded") : + if (ctl.f_option && !worked) { + verbose(&ctl, _("%s: trying to eject using floppy eject command"), ctl.device); + worked = eject_floppy(ctl.fd); + verbose(&ctl, worked ? _("floppy eject command succeeded") : _("floppy eject command failed")); } - if (q_option && !worked) { - verbose(_("%s: trying to eject using tape offline command"), device); - worked = eject_tape(fd); - verbose(worked ? _("tape offline command succeeded") : + if (ctl.q_option && !worked) { + verbose(&ctl, _("%s: trying to eject using tape offline command"), ctl.device); + worked = eject_tape(ctl.fd); + verbose(&ctl, worked ? _("tape offline command succeeded") : _("tape offline command failed")); } @@ -1144,11 +1142,11 @@ int main(int argc, char **argv) errx(EXIT_FAILURE, _("unable to eject")); /* cleanup */ - close(fd); - free(device); + close(ctl.fd); + free(ctl.device); free(mountpoint); - mnt_unref_table(mtab); + mnt_unref_table(ctl.mtab); return EXIT_SUCCESS; } diff --git a/sys-utils/hwclock-kd.c b/sys-utils/hwclock-kd.c deleted file mode 100644 index 3dac7072b..000000000 --- a/sys-utils/hwclock-kd.c +++ /dev/null @@ -1,180 +0,0 @@ -/* - * kd.c - KDGHWCLK stuff, possibly m68k only, likely to be deprecated - */ -#include "hwclock.h" - -#ifdef __m68k__ - -# include -# include -# include -# include - -# include "nls.h" - -/* Get defines for KDGHWCLK and KDSHWCLK (m68k) */ -# include - -/* Even on m68k, if KDGHWCLK (antique) is not defined, don't build this */ - -#endif - -#if !defined(__m68k__) || !defined(KDGHWCLK) - -#include -struct clock_ops *probe_for_kd_clock(void) -{ - return NULL; -} - -#else /* __m68k__ && KDGHWCLK */ - -/* Opened by probe_for_kd_clock(), and never closed. */ -static int con_fd = -1; -static char *con_fd_filename; /* usually "/dev/tty1" */ - -/* - * Wait for the top of a clock tick by calling KDGHWCLK in a busy loop until - * we see it. - */ -static int synchronize_to_clock_tick_kd(void) -{ - /* The time when we were called (and started waiting) */ - struct hwclk_time start_time, nowtime; - struct timeval begin, now; - - if (debug) - printf(_("Waiting in loop for time from KDGHWCLK to change\n")); - - if (ioctl(con_fd, KDGHWCLK, &start_time) == -1) { - warn(_("KDGHWCLK ioctl to read time failed")); - return 3; - } - - /* - * Wait for change. Should be within a second, but in case something - * weird happens, we have a time limit (1.5s) on this loop to reduce - * the impact of this failure. - */ - gettimeofday(&begin, NULL); - do { - /* - * Added by Roman Hodek - * - * "The culprit is the fast loop with KDGHWCLK ioctls. It - * seems the kernel gets confused by those on Amigas with - * A2000 RTCs and simply hangs after some time. Inserting a - * sleep helps." - */ - xusleep(1); - - if (ioctl(con_fd, KDGHWCLK, &nowtime) == -1) { - warn(_("KDGHWCLK ioctl to read time failed in loop")); - return 3; - } - if (start_time.tm_sec != nowtime.tm_sec) - break; - gettimeofday(&now, NULL); - if (time_diff(now, begin) > 1.5) { - warnx(_("Timed out waiting for time change.")); - return 2; - } - } while (1); - - return 0; -} - -/* - * Read the hardware clock and return the current time via argument. - * Use ioctls to /dev/tty1 on what we assume is an m68k machine. - * - * Note that we don't use /dev/console here. That might be a serial console. - */ -static int read_hardware_clock_kd(struct tm *tm) -{ - struct hwclk_time t; - - if (ioctl(con_fd, KDGHWCLK, &t) == -1) { - warn(_("ioctl() failed to read time from %s"), - con_fd_filename); - hwclock_exit(EX_IOERR); - } - - tm->tm_sec = t.sec; - tm->tm_min = t.min; - tm->tm_hour = t.hour; - tm->tm_mday = t.day; - tm->tm_mon = t.mon; - tm->tm_year = t.year; - tm->tm_wday = t.wday; - tm->tm_isdst = -1; /* Don't know if it's Daylight Savings Time */ - - return 0; -} - -/* - * Set the Hardware Clock to the time . Use ioctls to - * /dev/tty1 on what we assume is an m68k machine. - * - * Note that we don't use /dev/console here. That might be a serial console. - */ -static int set_hardware_clock_kd(const struct tm *new_broken_time) -{ - struct hwclk_time t; - - t.sec = new_broken_time->tm_sec; - t.min = new_broken_time->tm_min; - t.hour = new_broken_time->tm_hour; - t.day = new_broken_time->tm_mday; - t.mon = new_broken_time->tm_mon; - t.year = new_broken_time->tm_year; - t.wday = new_broken_time->tm_wday; - - if (ioctl(con_fd, KDSHWCLK, &t) == -1) { - warn(_("ioctl KDSHWCLK failed")); - hwclock_exit(EX_IOERR); - } - return 0; -} - -static int get_permissions_kd(void) -{ - return 0; -} - -static struct clock_ops kd = { - N_("Using the KDGHWCLK interface to m68k clock."), - get_permissions_kd, - read_hardware_clock_kd, - set_hardware_clock_kd, - synchronize_to_clock_tick_kd, -}; - -/* return &kd if KDGHWCLK works, NULL otherwise */ -struct clock_ops *probe_for_kd_clock() -{ - struct clock_ops *ret = NULL; - struct hwclk_time t; - - if (con_fd < 0) { /* first time here */ - con_fd_filename = "/dev/tty1"; - con_fd = open(con_fd_filename, O_RDONLY); - } - if (con_fd < 0) { - /* perhaps they are using devfs? */ - con_fd_filename = "/dev/vc/1"; - con_fd = open(con_fd_filename, O_RDONLY); - } - if (con_fd < 0) { - /* probably KDGHWCLK exists on m68k only */ - warn(_("Can't open /dev/tty1 or /dev/vc/1")); - } else { - if (ioctl(con_fd, KDGHWCLK, &t) == -1) { - if (errno != EINVAL) - warn(_("KDGHWCLK ioctl failed")); - } else - ret = &kd; - } - return ret; -} -#endif /* __m68k__ && KDGHWCLK */ diff --git a/sys-utils/hwclock.c b/sys-utils/hwclock.c index 474e04fdc..d0d422d2f 100644 --- a/sys-utils/hwclock.c +++ b/sys-utils/hwclock.c @@ -1256,9 +1256,6 @@ static void determine_clock_access_method(const bool user_requests_ISA) ur = probe_for_rtc_clock(); #endif - if (!ur) - ur = probe_for_kd_clock(); - if (!ur && !user_requests_ISA) ur = probe_for_cmos_clock(); diff --git a/sys-utils/hwclock.h b/sys-utils/hwclock.h index 69b0ce200..974d96a40 100644 --- a/sys-utils/hwclock.h +++ b/sys-utils/hwclock.h @@ -19,7 +19,6 @@ struct clock_ops { extern struct clock_ops *probe_for_cmos_clock(void); extern struct clock_ops *probe_for_rtc_clock(void); -extern struct clock_ops *probe_for_kd_clock(void); typedef int bool; diff --git a/sys-utils/mountpoint.c b/sys-utils/mountpoint.c index 3919ab748..0aaa290fe 100644 --- a/sys-utils/mountpoint.c +++ b/sys-utils/mountpoint.c @@ -40,9 +40,17 @@ #include "closestream.h" #include "pathnames.h" -static int quiet; +struct mountpoint_control { + char *path; + dev_t dev; + struct stat st; + unsigned int + dev_devno:1, + fs_devno:1, + quiet:1; +}; -static int dir_to_device(const char *spec, dev_t *dev) +static int dir_to_device(struct mountpoint_control *ctl) { struct libmnt_table *tb = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO); struct libmnt_fs *fs; @@ -54,16 +62,13 @@ static int dir_to_device(const char *spec, dev_t *dev) * Fallback. Traditional way to detect mountpoints. This way * is independent on /proc, but not able to detect bind mounts. */ - struct stat pst, st; + struct stat pst; char buf[PATH_MAX], *cn; int len; - if (stat(spec, &st) != 0) - return -1; + cn = mnt_resolve_path(ctl->path, NULL); /* canonicalize */ - cn = mnt_resolve_path(spec, NULL); /* canonicalize */ - - len = snprintf(buf, sizeof(buf), "%s/..", cn ? cn : spec); + len = snprintf(buf, sizeof(buf), "%s/..", cn ? cn : ctl->path); free(cn); if (len < 0 || (size_t) len + 1 > sizeof(buf)) @@ -71,9 +76,9 @@ static int dir_to_device(const char *spec, dev_t *dev) if (stat(buf, &pst) !=0) return -1; - if ((st.st_dev != pst.st_dev) || - (st.st_dev == pst.st_dev && st.st_ino == pst.st_ino)) { - *dev = st.st_dev; + if ((ctl->st.st_dev != pst.st_dev) || + (ctl->st.st_dev == pst.st_dev && ctl->st.st_ino == pst.st_ino)) { + ctl->dev = ctl->st.st_dev; return 0; } @@ -85,9 +90,9 @@ static int dir_to_device(const char *spec, dev_t *dev) mnt_table_set_cache(tb, cache); mnt_unref_cache(cache); - fs = mnt_table_find_target(tb, spec, MNT_ITER_BACKWARD); + fs = mnt_table_find_target(tb, ctl->path, MNT_ITER_BACKWARD); if (fs && mnt_fs_get_target(fs)) { - *dev = mnt_fs_get_devno(fs); + ctl->dev = mnt_fs_get_devno(fs); rc = 0; } @@ -95,20 +100,14 @@ static int dir_to_device(const char *spec, dev_t *dev) return rc; } -static int print_devno(const char *devname, struct stat *st) +static int print_devno(const struct mountpoint_control *ctl) { - struct stat stbuf; - - if (!st && stat(devname, &stbuf) == 0) - st = &stbuf; - if (!st) - return -1; - if (!S_ISBLK(st->st_mode)) { - if (!quiet) - warnx(_("%s: not a block device"), devname); + if (!S_ISBLK(ctl->st.st_mode)) { + if (!ctl->quiet) + warnx(_("%s: not a block device"), ctl->path); return -1; } - printf("%u:%u\n", major(st->st_rdev), minor(st->st_rdev)); + printf("%u:%u\n", major(ctl->st.st_rdev), minor(ctl->st.st_rdev)); return 0; } @@ -133,9 +132,8 @@ static void __attribute__((__noreturn__)) usage(FILE *out) int main(int argc, char **argv) { - int c, fs_devno = 0, dev_devno = 0, rc = 0; - char *spec; - struct stat st; + int c; + struct mountpoint_control ctl = { 0 }; static const struct option longopts[] = { { "quiet", 0, 0, 'q' }, @@ -157,13 +155,13 @@ int main(int argc, char **argv) switch(c) { case 'q': - quiet = 1; + ctl.quiet = 1; break; case 'd': - fs_devno = 1; + ctl.fs_devno = 1; break; case 'x': - dev_devno = 1; + ctl.dev_devno = 1; break; case 'h': usage(stdout); @@ -180,28 +178,23 @@ int main(int argc, char **argv) if (optind + 1 != argc) usage(stderr); - spec = argv[optind++]; + ctl.path = argv[optind]; - if (stat(spec, &st)) { - if (!quiet) - err(EXIT_FAILURE, "%s", spec); + if (stat(ctl.path, &ctl.st)) { + if (!ctl.quiet) + err(EXIT_FAILURE, "%s", ctl.path); return EXIT_FAILURE; } - if (dev_devno) - rc = print_devno(spec, &st); - else { - dev_t src; - - if ( dir_to_device(spec, &src)) { - if (!quiet) - printf(_("%s is not a mountpoint\n"), spec); - return EXIT_FAILURE; - } - if (fs_devno) - printf("%u:%u\n", major(src), minor(src)); - else if (!quiet) - printf(_("%s is a mountpoint\n"), spec); + if (ctl.dev_devno) + return print_devno(&ctl) ? EXIT_FAILURE : EXIT_SUCCESS; + if (dir_to_device(&ctl)) { + if (!ctl.quiet) + printf(_("%s is not a mountpoint\n"), ctl.path); + return EXIT_FAILURE; } - - return rc ? EXIT_FAILURE : EXIT_SUCCESS; + if (ctl.fs_devno) + printf("%u:%u\n", major(ctl.dev), minor(ctl.dev)); + else if (!ctl.quiet) + printf(_("%s is a mountpoint\n"), ctl.path); + return EXIT_SUCCESS; } diff --git a/sys-utils/setarch.c b/sys-utils/setarch.c index 4cce877be..ed2a6a64c 100644 --- a/sys-utils/setarch.c +++ b/sys-utils/setarch.c @@ -24,8 +24,7 @@ * sparc32 util by Jakub Jelinek (1998, 1999) */ -#include -#include +#include #include #include #include @@ -37,11 +36,14 @@ #include "c.h" #include "closestream.h" -#define set_pers(pers) ((long)syscall(SYS_personality, pers)) +#ifndef HAVE_PERSONALITY +# include +# define personality(pers) ((long)syscall(SYS_personality, pers)) +#endif /* Options without equivalent short options */ enum { - OPT_4GB = CHAR_MAX + 1, + OPT_4GB = CHAR_MAX + 1, OPT_UNAME26 }; @@ -52,7 +54,6 @@ enum { printf(_("Switching on %s.\n"), #_flag); \ } while(0) - #ifndef UNAME26 # define UNAME26 0x0020000 #endif @@ -87,301 +88,291 @@ enum { # define ADDR_LIMIT_3GB 0x8000000 #endif -static void __attribute__((__noreturn__)) -show_help(void) +static void __attribute__((__noreturn__)) show_help(void) { - fputs(USAGE_HEADER, stdout); - printf(_(" %s%s [options] [program [program arguments]]\n"), - program_invocation_short_name, - !strcmp(program_invocation_short_name, "setarch") ? " " : ""); + fputs(USAGE_HEADER, stdout); + printf(_(" %s%s [options] [program [program arguments]]\n"), + program_invocation_short_name, + !strcmp(program_invocation_short_name, "setarch") ? " " : ""); + fputs(USAGE_OPTIONS, stdout); + fputs(_(" -v, --verbose says what options are being switched on\n"), stdout); + fputs(_(" -R, --addr-no-randomize disables randomization of the virtual address space\n"), stdout); + fputs(_(" -F, --fdpic-funcptrs makes function pointers point to descriptors\n"), stdout); + fputs(_(" -Z, --mmap-page-zero turns on MMAP_PAGE_ZERO\n"), stdout); + fputs(_(" -L, --addr-compat-layout changes the way virtual memory is allocated\n"), stdout); + fputs(_(" -X, --read-implies-exec turns on READ_IMPLIES_EXEC\n"), stdout); + fputs(_(" -B, --32bit turns on ADDR_LIMIT_32BIT\n"), stdout); + fputs(_(" -I, --short-inode turns on SHORT_INODE\n"), stdout); + fputs(_(" -S, --whole-seconds turns on WHOLE_SECONDS\n"), stdout); + fputs(_(" -T, --sticky-timeouts turns on STICKY_TIMEOUTS\n"), stdout); + fputs(_(" -3, --3gb limits the used address space to a maximum of 3 GB\n"), stdout); + fputs(_(" --4gb ignored (for backward compatibility only)\n"), stdout); + fputs(_(" --uname-2.6 turns on UNAME26\n"), stdout); + fputs(_(" --list list settable architectures, and exit\n"), stdout); + fputs(USAGE_SEPARATOR, stdout); + fputs(USAGE_HELP, stdout); + fputs(USAGE_VERSION, stdout); + printf(USAGE_MAN_TAIL("setarch(8)")); + exit(EXIT_SUCCESS); +} - fputs(USAGE_OPTIONS, stdout); - fputs(_(" -v, --verbose says what options are being switched on\n"), stdout); - fputs(_(" -R, --addr-no-randomize disables randomization of the virtual address space\n"), stdout); - fputs(_(" -F, --fdpic-funcptrs makes function pointers point to descriptors\n"), stdout); - fputs(_(" -Z, --mmap-page-zero turns on MMAP_PAGE_ZERO\n"), stdout); - fputs(_(" -L, --addr-compat-layout changes the way virtual memory is allocated\n"), stdout); - fputs(_(" -X, --read-implies-exec turns on READ_IMPLIES_EXEC\n"), stdout); - fputs(_(" -B, --32bit turns on ADDR_LIMIT_32BIT\n"), stdout); - fputs(_(" -I, --short-inode turns on SHORT_INODE\n"), stdout); - fputs(_(" -S, --whole-seconds turns on WHOLE_SECONDS\n"), stdout); - fputs(_(" -T, --sticky-timeouts turns on STICKY_TIMEOUTS\n"), stdout); - fputs(_(" -3, --3gb limits the used address space to a maximum of 3 GB\n"), stdout); - fputs(_(" --4gb ignored (for backward compatibility only)\n"), stdout); - fputs(_(" --uname-2.6 turns on UNAME26\n"), stdout); - fputs(_(" --list list settable architectures, and exit\n"), stdout); - - fputs(USAGE_SEPARATOR, stdout); - fputs(USAGE_HELP, stdout); - fputs(USAGE_VERSION, stdout); - printf(USAGE_MAN_TAIL("setarch(8)")); - - exit(EXIT_SUCCESS); +static void __attribute__((__noreturn__)) show_usage(const char *s) +{ + if (s) + errx(EXIT_FAILURE, + _("%s\nTry `%s --help' for more information."), s, + program_invocation_short_name); + else + errx(EXIT_FAILURE, _("Try `%s --help' for more information."), + program_invocation_short_name); } static void __attribute__((__noreturn__)) -show_usage(const char *s) + show_version(void) { - if (s) - errx(EXIT_FAILURE, _("%s\nTry `%s --help' for more information."), s, program_invocation_short_name); - else - errx(EXIT_FAILURE, _("Try `%s --help' for more information."), program_invocation_short_name); + printf(UTIL_LINUX_VERSION); + exit(EXIT_SUCCESS); } -static void __attribute__((__noreturn__)) -show_version(void) +static int set_arch(const char *pers, unsigned long options, int list) { - printf(UTIL_LINUX_VERSION); - exit(EXIT_SUCCESS); -} + struct utsname un; + int i; + unsigned long pers_value; -static int -set_arch(const char *pers, unsigned long options, int list) -{ - struct utsname un; - int i; - unsigned long pers_value; - - struct { - int perval; - const char *target_arch, *result_arch; - } transitions[] = { - {UNAME26, "uname26", NULL}, - {PER_LINUX32, "linux32", NULL}, - {PER_LINUX, "linux64", NULL}, + struct { + int perval; + const char *target_arch, *result_arch; + } transitions[] = { + {UNAME26, "uname26", NULL}, + {PER_LINUX32, "linux32", NULL}, + {PER_LINUX, "linux64", NULL}, #if defined(__powerpc__) || defined(__powerpc64__) -#ifdef __BIG_ENDIAN__ - {PER_LINUX32, "ppc32", "ppc"}, - {PER_LINUX32, "ppc", "ppc"}, - {PER_LINUX, "ppc64", "ppc64"}, - {PER_LINUX, "ppc64pseries", "ppc64"}, - {PER_LINUX, "ppc64iseries", "ppc64"}, -#else - {PER_LINUX32, "ppc32le", "ppcle"}, - {PER_LINUX32, "ppcle", "ppcle"}, - {PER_LINUX, "ppc64le", "ppc64le"}, -#endif +# ifdef __BIG_ENDIAN__ + {PER_LINUX32, "ppc32", "ppc"}, + {PER_LINUX32, "ppc", "ppc"}, + {PER_LINUX, "ppc64", "ppc64"}, + {PER_LINUX, "ppc64pseries", "ppc64"}, + {PER_LINUX, "ppc64iseries", "ppc64"}, +# else + PER_LINUX32, "ppc32le", "ppcle"}, + PER_LINUX32, "ppcle", "ppcle"}, + PER_LINUX, "ppc64le", "ppc64le"}, +# endif #endif #if defined(__x86_64__) || defined(__i386__) || defined(__ia64__) - {PER_LINUX32, "i386", "i386"}, - {PER_LINUX32, "i486", "i386"}, - {PER_LINUX32, "i586", "i386"}, - {PER_LINUX32, "i686", "i386"}, - {PER_LINUX32, "athlon", "i386"}, + {PER_LINUX32, "i386", "i386"}, + {PER_LINUX32, "i486", "i386"}, + {PER_LINUX32, "i586", "i386"}, + {PER_LINUX32, "i686", "i386"}, + {PER_LINUX32, "athlon", "i386"}, #endif #if defined(__x86_64__) || defined(__i386__) - {PER_LINUX, "x86_64", "x86_64"}, + {PER_LINUX, "x86_64", "x86_64"}, #endif #if defined(__ia64__) || defined(__i386__) - {PER_LINUX, "ia64", "ia64"}, + {PER_LINUX, "ia64", "ia64"}, #endif #if defined(__hppa__) - {PER_LINUX32, "parisc32", "parisc"}, - {PER_LINUX32, "parisc", "parisc"}, - {PER_LINUX, "parisc64", "parisc64"}, + {PER_LINUX32, "parisc32", "parisc"}, + {PER_LINUX32, "parisc", "parisc"}, + {PER_LINUX, "parisc64", "parisc64"}, #endif #if defined(__s390x__) || defined(__s390__) - {PER_LINUX32, "s390", "s390"}, - {PER_LINUX, "s390x", "s390x"}, + {PER_LINUX32, "s390", "s390"}, + {PER_LINUX, "s390x", "s390x"}, #endif #if defined(__sparc64__) || defined(__sparc__) - {PER_LINUX32, "sparc", "sparc"}, - {PER_LINUX32, "sparc32bash", "sparc"}, - {PER_LINUX32, "sparc32", "sparc"}, - {PER_LINUX, "sparc64", "sparc64"}, + {PER_LINUX32, "sparc", "sparc"}, + {PER_LINUX32, "sparc32bash", "sparc"}, + {PER_LINUX32, "sparc32", "sparc"}, + {PER_LINUX, "sparc64", "sparc64"}, #endif #if defined(__mips64__) || defined(__mips__) - {PER_LINUX32, "mips32", "mips"}, - {PER_LINUX32, "mips", "mips"}, - {PER_LINUX, "mips64", "mips64"}, + {PER_LINUX32, "mips32", "mips"}, + {PER_LINUX32, "mips", "mips"}, + {PER_LINUX, "mips64", "mips64"}, #endif #if defined(__alpha__) - {PER_LINUX, "alpha", "alpha"}, - {PER_LINUX, "alphaev5", "alpha"}, - {PER_LINUX, "alphaev56", "alpha"}, - {PER_LINUX, "alphaev6", "alpha"}, - {PER_LINUX, "alphaev67", "alpha"}, + {PER_LINUX, "alpha", "alpha"}, + {PER_LINUX, "alphaev5", "alpha"}, + {PER_LINUX, "alphaev56", "alpha"}, + {PER_LINUX, "alphaev6", "alpha"}, + {PER_LINUX, "alphaev67", "alpha"}, #endif - {-1, NULL, NULL}, /* place holder, eventually filled up at runtime */ - {-1, NULL, NULL} - }; + /* place holder, will be filled up at runtime */ + {-1, NULL, NULL}, + {-1, NULL, NULL} + }; - /* Add the trivial transition {PER_LINUX, machine, machine} if no such - target_arch is hardcoded yet. */ - uname(&un); - for (i = 0; transitions[i].perval >= 0; i++) - if(!strcmp(un.machine, transitions[i].target_arch)) - break; - if (transitions[i].perval < 0) { - unsigned long wrdsz = CHAR_BIT * sizeof(void*); - if (wrdsz == 32 || wrdsz == 64) { - transitions[i].perval = wrdsz == 32 ? PER_LINUX32 : PER_LINUX; - transitions[i].target_arch = un.machine; - transitions[i].result_arch = un.machine; + /* Add the trivial transition {PER_LINUX, machine, machine} if no + * such target_arch is hardcoded yet. */ + uname(&un); + for (i = 0; transitions[i].perval >= 0; i++) + if (!strcmp(un.machine, transitions[i].target_arch)) + break; + if (transitions[i].perval < 0) { + unsigned long wrdsz = CHAR_BIT * sizeof(void *); + if (wrdsz == 32 || wrdsz == 64) { + /* fill up the place holder */ + transitions[i].perval = wrdsz == 32 ? PER_LINUX32 : PER_LINUX; + transitions[i].target_arch = un.machine; + transitions[i].result_arch = un.machine; + } } - } - - if (list) { - for(i = 0; transitions[i].target_arch != NULL; i++) - printf("%s\n", transitions[i].target_arch); - return 0; - } - - for(i = 0; transitions[i].perval >= 0; i++) - if(!strcmp(pers, transitions[i].target_arch)) - break; - - if(transitions[i].perval < 0) - errx(EXIT_FAILURE, _("%s: Unrecognized architecture"), pers); - - pers_value = transitions[i].perval | options; - if (set_pers(pers_value) == -EINVAL) - return 1; - - uname(&un); - if(transitions[i].result_arch && - strcmp(un.machine, transitions[i].result_arch)) - { - if(strcmp(transitions[i].result_arch, "i386") - || (strcmp(un.machine, "i486") - && strcmp(un.machine, "i586") - && strcmp(un.machine, "i686") - && strcmp(un.machine, "athlon"))) - errx(EXIT_FAILURE, _("%s: Unrecognized architecture"), pers); - } - - return 0; + if (list) { + for (i = 0; transitions[i].target_arch != NULL; i++) + printf("%s\n", transitions[i].target_arch); + return 0; + } + for (i = 0; transitions[i].perval >= 0; i++) + if (!strcmp(pers, transitions[i].target_arch)) + break; + if (transitions[i].perval < 0) + errx(EXIT_FAILURE, _("%s: Unrecognized architecture"), pers); + pers_value = transitions[i].perval | options; + if (personality(pers_value) == -EINVAL) + return 1; + uname(&un); + if (transitions[i].result_arch && strcmp(un.machine, transitions[i].result_arch)) { + if (strcmp(transitions[i].result_arch, "i386") + || (strcmp(un.machine, "i486") + && strcmp(un.machine, "i586") + && strcmp(un.machine, "i686") + && strcmp(un.machine, "athlon"))) + errx(EXIT_FAILURE, _("%s: Unrecognized architecture"), pers); + } + return 0; } int main(int argc, char *argv[]) { - const char *p; - unsigned long options = 0; - int verbose = 0; - int c; + const char *p; + unsigned long options = 0; + int verbose = 0; + int c; - /* Options --3gb and --4gb are for compatibitity with an old Debian setarch - implementation. */ - static const struct option longopts[] = - { - { "help", 0, 0, 'h' }, - { "version", 0, 0, 'V' }, - { "verbose", 0, 0, 'v' }, - { "addr-no-randomize", 0, 0, 'R' }, - { "fdpic-funcptrs", 0, 0, 'F' }, - { "mmap-page-zero", 0, 0, 'Z' }, - { "addr-compat-layout", 0, 0, 'L' }, - { "read-implies-exec", 0, 0, 'X' }, - { "32bit", 0, 0, 'B' }, - { "short-inode", 0, 0, 'I' }, - { "whole-seconds", 0, 0, 'S' }, - { "sticky-timeouts", 0, 0, 'T' }, - { "3gb", 0, 0, '3' }, - { "4gb", 0, 0, OPT_4GB }, - { "uname-2.6", 0, 0, OPT_UNAME26 }, - { NULL, 0, 0, 0 } - }; + /* Options --3gb and --4gb are for compatibitity with an old + * Debian setarch implementation. */ + static const struct option longopts[] = { + {"help", no_argument, NULL, 'h'}, + {"version", no_argument, NULL, 'V'}, + {"verbose", no_argument, NULL, 'v'}, + {"addr-no-randomize", no_argument, NULL, 'R'}, + {"fdpic-funcptrs", no_argument, NULL, 'F'}, + {"mmap-page-zero", no_argument, NULL, 'Z'}, + {"addr-compat-layout", no_argument, NULL, 'L'}, + {"read-implies-exec", no_argument, NULL, 'X'}, + {"32bit", no_argument, NULL, 'B'}, + {"short-inode", no_argument, NULL, 'I'}, + {"whole-seconds", no_argument, NULL, 'S'}, + {"sticky-timeouts", no_argument, NULL, 'T'}, + {"3gb", no_argument, NULL, '3'}, + {"4gb", no_argument, NULL, OPT_4GB}, + {"uname-2.6", no_argument, NULL, OPT_UNAME26}, + {NULL, 0, NULL, 0} + }; - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - atexit(close_stdout); + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + atexit(close_stdout); - if (argc < 1) - show_usage(_("Not enough arguments")); + if (argc < 1) + show_usage(_("Not enough arguments")); - p = program_invocation_short_name; - if (!strcmp(p, "setarch")) { - argc--; - if (argc < 1) - show_usage(_("Not enough arguments")); - p = argv[1]; - argv[1] = argv[0]; /* for getopt_long() to get the program name */ - argv++; - if (!strcmp(p, "-h") || !strcmp(p, "--help")) - show_help(); - else if (!strcmp(p, "-V") || !strcmp(p, "--version")) - show_version(); - else if (!strcmp(p, "--list")) { - set_arch(argv[0], 0L, 1); - return EXIT_SUCCESS; - } - } - #if defined(__sparc64__) || defined(__sparc__) - if (!strcmp(p, "sparc32bash")) { - if (set_arch(p, 0L, 0)) - err(EXIT_FAILURE, _("Failed to set personality to %s"), p); - execl("/bin/bash", NULL); - err(EXIT_FAILURE, _("failed to execute %s"), "/bin/bash"); - } - #endif + p = program_invocation_short_name; + if (!strcmp(p, "setarch")) { + argc--; + if (argc < 1) + show_usage(_("Not enough arguments")); + p = argv[1]; + argv[1] = argv[0]; /* for getopt_long() to get the program name */ + argv++; + if (!strcmp(p, "-h") || !strcmp(p, "--help")) + show_help(); + else if (!strcmp(p, "-V") || !strcmp(p, "--version")) + show_version(); + else if (!strcmp(p, "--list")) { + set_arch(argv[0], 0L, 1); + return EXIT_SUCCESS; + } + } +#if defined(__sparc64__) || defined(__sparc__) + if (!strcmp(p, "sparc32bash")) { + if (set_arch(p, 0L, 0)) + err(EXIT_FAILURE, _("Failed to set personality to %s"), p); + execl("/bin/bash", NULL); + err(EXIT_FAILURE, _("failed to execute %s"), "/bin/bash"); + } +#endif - while ((c = getopt_long(argc, argv, "+hVv3BFILRSTXZ", longopts, NULL)) != -1) { - switch (c) { - case 'h': - show_help(); - break; - case 'V': - show_version(); - break; - case 'v': - verbose = 1; - break; - case 'R': - turn_on(ADDR_NO_RANDOMIZE, options); - break; - case 'F': - turn_on(FDPIC_FUNCPTRS, options); - break; - case 'Z': - turn_on(MMAP_PAGE_ZERO, options); - break; - case 'L': - turn_on(ADDR_COMPAT_LAYOUT, options); - break; - case 'X': - turn_on(READ_IMPLIES_EXEC, options); - break; - case 'B': - turn_on(ADDR_LIMIT_32BIT, options); - break; - case 'I': - turn_on(SHORT_INODE, options); - break; - case 'S': - turn_on(WHOLE_SECONDS, options); - break; - case 'T': - turn_on(STICKY_TIMEOUTS, options); - break; - case '3': - turn_on(ADDR_LIMIT_3GB, options); - break; - case OPT_4GB: /* just ignore this one */ - break; - case OPT_UNAME26: - turn_on(UNAME26, options); - break; - default: - show_usage(NULL); - } - } + while ((c = getopt_long(argc, argv, "+hVv3BFILRSTXZ", longopts, NULL)) != -1) { + switch (c) { + case 'h': + show_help(); + break; + case 'V': + show_version(); + break; + case 'v': + verbose = 1; + break; + case 'R': + turn_on(ADDR_NO_RANDOMIZE, options); + break; + case 'F': + turn_on(FDPIC_FUNCPTRS, options); + break; + case 'Z': + turn_on(MMAP_PAGE_ZERO, options); + break; + case 'L': + turn_on(ADDR_COMPAT_LAYOUT, options); + break; + case 'X': + turn_on(READ_IMPLIES_EXEC, options); + break; + case 'B': + turn_on(ADDR_LIMIT_32BIT, options); + break; + case 'I': + turn_on(SHORT_INODE, options); + break; + case 'S': + turn_on(WHOLE_SECONDS, options); + break; + case 'T': + turn_on(STICKY_TIMEOUTS, options); + break; + case '3': + turn_on(ADDR_LIMIT_3GB, options); + break; + case OPT_4GB: /* just ignore this one */ + break; + case OPT_UNAME26: + turn_on(UNAME26, options); + break; + default: + show_usage(NULL); + } + } - argc -= optind; - argv += optind; + argc -= optind; + argv += optind; - if (set_arch(p, options, 0)) - err(EXIT_FAILURE, _("Failed to set personality to %s"), p); + if (set_arch(p, options, 0)) + err(EXIT_FAILURE, _("Failed to set personality to %s"), p); - /* flush all output streams before exec */ - fflush(NULL); + /* flush all output streams before exec */ + fflush(NULL); - if (!argc) { - execl("/bin/sh", "-sh", NULL); - err(EXIT_FAILURE, _("failed to execute %s"), "/bin/sh"); - } + if (!argc) { + execl("/bin/sh", "-sh", NULL); + err(EXIT_FAILURE, _("failed to execute %s"), "/bin/sh"); + } - execvp(argv[0], argv); - err(EXIT_FAILURE, "%s", argv[0]); - return EXIT_FAILURE; + execvp(argv[0], argv); + err(EXIT_FAILURE, "%s", argv[0]); + return EXIT_FAILURE; }