aboutsummaryrefslogtreecommitdiff
path: root/coreutils/stty.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-01-12 21:02:04 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-01-12 21:02:04 +0000
commitf8abc100cc84c370f7c595846c74ab46456faccb (patch)
treef49034e2a17d8fe1dd040b0a178811b82557927b /coreutils/stty.c
parent4df8135cf6f4c4055a6eeb56eab6fd794c348a72 (diff)
downloadbusybox-w32-f8abc100cc84c370f7c595846c74ab46456faccb.tar.gz
busybox-w32-f8abc100cc84c370f7c595846c74ab46456faccb.tar.bz2
busybox-w32-f8abc100cc84c370f7c595846c74ab46456faccb.zip
stty: rearrange functions, avoiding the need in forward declarations.
No other code chages.
Diffstat (limited to 'coreutils/stty.c')
-rw-r--r--coreutils/stty.c760
1 files changed, 374 insertions, 386 deletions
diff --git a/coreutils/stty.c b/coreutils/stty.c
index b48941429..93919b33a 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -637,17 +637,382 @@ static int find_param(const char *name)
637 return 0; 637 return 0;
638} 638}
639 639
640static int recover_mode(const char *arg, struct termios *mode)
641{
642 int i, n;
643 unsigned int chr;
644 unsigned long iflag, oflag, cflag, lflag;
645
646 /* Scan into temporaries since it is too much trouble to figure out
647 the right format for 'tcflag_t' */
648 if (sscanf(arg, "%lx:%lx:%lx:%lx%n",
649 &iflag, &oflag, &cflag, &lflag, &n) != 4)
650 return 0;
651 mode->c_iflag = iflag;
652 mode->c_oflag = oflag;
653 mode->c_cflag = cflag;
654 mode->c_lflag = lflag;
655 arg += n;
656 for (i = 0; i < NCCS; ++i) {
657 if (sscanf(arg, ":%x%n", &chr, &n) != 1)
658 return 0;
659 mode->c_cc[i] = chr;
660 arg += n;
661 }
662
663 /* Fail if there are too many fields */
664 if (*arg != '\0')
665 return 0;
666
667 return 1;
668}
669
670static void display_recoverable(const struct termios *mode)
671{
672 int i;
673 printf("%lx:%lx:%lx:%lx",
674 (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag,
675 (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag);
676 for (i = 0; i < NCCS; ++i)
677 printf(":%x", (unsigned int) mode->c_cc[i]);
678 putchar('\n');
679}
680
681static void display_speed(const struct termios *mode, int fancy)
682{
683 //01234567 8 9
684 const char *fmt_str = "%lu %lu\n\0ispeed %lu baud; ospeed %lu baud;";
685 unsigned long ispeed, ospeed;
686
687 ospeed = ispeed = cfgetispeed(mode);
688 if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) {
689 ispeed = ospeed; /* in case ispeed was 0 */
690 //0123 4 5 6 7 8 9
691 fmt_str = "%lu\n\0\0\0\0\0speed %lu baud;";
692 }
693 if (fancy) fmt_str += 9;
694 wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed));
695}
696
697static void display_all(const struct termios *mode)
698{
699 int i;
700 tcflag_t *bitsp;
701 unsigned long mask;
702 int prev_type = control;
703
704 display_speed(mode, 1);
705 display_window_size(1);
706#ifdef HAVE_C_LINE
707 wrapf("line = %d;\n", mode->c_line);
708#else
709 wrapf("\n");
710#endif
711
712 for (i = 0; control_info[i].name != stty_min; ++i) {
713 /* If swtch is the same as susp, don't print both */
714#if VSWTCH == VSUSP
715 if (control_info[i].name == stty_swtch)
716 continue;
717#endif
718 /* If eof uses the same slot as min, only print whichever applies */
719#if VEOF == VMIN
720 if ((mode->c_lflag & ICANON) == 0
721 && (control_info[i].name == stty_eof
722 || control_info[i].name == stty_eol)) continue;
723#endif
724 wrapf("%s = %s;", control_info[i].name,
725 visible(mode->c_cc[control_info[i].offset]));
726 }
727#if VEOF == VMIN
728 if ((mode->c_lflag & ICANON) == 0)
729#endif
730 wrapf("min = %d; time = %d;", mode->c_cc[VMIN], mode->c_cc[VTIME]);
731 if (current_col) wrapf("\n");
732
733 for (i = 0; i < NUM_mode_info; ++i) {
734 if (mode_info[i].flags & OMIT)
735 continue;
736 if (mode_info[i].type != prev_type) {
737 wrapf("\n");
738 prev_type = mode_info[i].type;
739 }
740
741 bitsp = mode_type_flag(mode_info[i].type, mode);
742 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
743 if ((*bitsp & mask) == mode_info[i].bits)
744 wrapf("%s", mode_info[i].name);
745 else if (mode_info[i].flags & REV)
746 wrapf("-%s", mode_info[i].name);
747 }
748 if (current_col) wrapf("\n");
749}
750
751static void sane_mode(struct termios *mode)
752{
753 int i;
754 tcflag_t *bitsp;
755
756 for (i = 0; i < NUM_control_info; ++i) {
757#if VMIN == VEOF
758 if (control_info[i].name == stty_min)
759 break;
760#endif
761 mode->c_cc[control_info[i].offset] = control_info[i].saneval;
762 }
763
764 for (i = 0; i < NUM_mode_info; ++i) {
765 if (mode_info[i].flags & SANE_SET) {
766 bitsp = mode_type_flag(mode_info[i].type, mode);
767 *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask))
768 | mode_info[i].bits;
769 } else if (mode_info[i].flags & SANE_UNSET) {
770 bitsp = mode_type_flag(mode_info[i].type, mode);
771 *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask)
772 & ~mode_info[i].bits;
773 }
774 }
775}
776
777/* Save set_mode from #ifdef forest plague */
778#ifndef ONLCR
779#define ONLCR 0
780#endif
781#ifndef OCRNL
782#define OCRNL 0
783#endif
784#ifndef ONLRET
785#define ONLRET 0
786#endif
787#ifndef XCASE
788#define XCASE 0
789#endif
790#ifndef IXANY
791#define IXANY 0
792#endif
793#ifndef TABDLY
794#define TABDLY 0
795#endif
796#ifndef OXTABS
797#define OXTABS 0
798#endif
799#ifndef IUCLC
800#define IUCLC 0
801#endif
802#ifndef OLCUC
803#define OLCUC 0
804#endif
805#ifndef ECHOCTL
806#define ECHOCTL 0
807#endif
808#ifndef ECHOKE
809#define ECHOKE 0
810#endif
811
812static void set_mode(const struct mode_info *info, int reversed,
813 struct termios *mode)
814{
815 tcflag_t *bitsp;
816
817 bitsp = mode_type_flag(info->type, mode);
818
819 if (bitsp) {
820 if (reversed)
821 *bitsp = *bitsp & ~info->mask & ~info->bits;
822 else
823 *bitsp = (*bitsp & ~info->mask) | info->bits;
824 return;
825 }
826
827 /* Combination mode */
828 if (info->name == evenp || info->name == parity) {
829 if (reversed)
830 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
831 else
832 mode->c_cflag = (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7;
833 } else if (info->name == stty_oddp) {
834 if (reversed)
835 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
836 else
837 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB;
838 } else if (info->name == stty_nl) {
839 if (reversed) {
840 mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR;
841 mode->c_oflag = (mode->c_oflag | ONLCR) & ~OCRNL & ~ONLRET;
842 } else {
843 mode->c_iflag = mode->c_iflag & ~ICRNL;
844 if (ONLCR) mode->c_oflag = mode->c_oflag & ~ONLCR;
845 }
846 } else if (info->name == stty_ek) {
847 mode->c_cc[VERASE] = CERASE;
848 mode->c_cc[VKILL] = CKILL;
849 } else if (info->name == stty_sane) {
850 sane_mode(mode);
851 }
852 else if (info->name == cbreak) {
853 if (reversed)
854 mode->c_lflag |= ICANON;
855 else
856 mode->c_lflag &= ~ICANON;
857 } else if (info->name == stty_pass8) {
858 if (reversed) {
859 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB;
860 mode->c_iflag |= ISTRIP;
861 } else {
862 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
863 mode->c_iflag &= ~ISTRIP;
864 }
865 } else if (info->name == litout) {
866 if (reversed) {
867 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB;
868 mode->c_iflag |= ISTRIP;
869 mode->c_oflag |= OPOST;
870 } else {
871 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
872 mode->c_iflag &= ~ISTRIP;
873 mode->c_oflag &= ~OPOST;
874 }
875 } else if (info->name == raw || info->name == cooked) {
876 if ((info->name[0] == 'r' && reversed)
877 || (info->name[0] == 'c' && !reversed)) {
878 /* Cooked mode */
879 mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON;
880 mode->c_oflag |= OPOST;
881 mode->c_lflag |= ISIG | ICANON;
882#if VMIN == VEOF
883 mode->c_cc[VEOF] = CEOF;
884#endif
885#if VTIME == VEOL
886 mode->c_cc[VEOL] = CEOL;
887#endif
888 } else {
889 /* Raw mode */
890 mode->c_iflag = 0;
891 mode->c_oflag &= ~OPOST;
892 mode->c_lflag &= ~(ISIG | ICANON | XCASE);
893 mode->c_cc[VMIN] = 1;
894 mode->c_cc[VTIME] = 0;
895 }
896 }
897 else if (IXANY && info->name == decctlq) {
898 if (reversed)
899 mode->c_iflag |= IXANY;
900 else
901 mode->c_iflag &= ~IXANY;
902 }
903 else if (TABDLY && info->name == stty_tabs) {
904 if (reversed)
905 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3;
906 else
907 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0;
908 }
909 else if (OXTABS && info->name == stty_tabs) {
910 if (reversed)
911 mode->c_oflag |= OXTABS;
912 else
913 mode->c_oflag &= ~OXTABS;
914 }
915 else if (XCASE && IUCLC && OLCUC
916 && (info->name == stty_lcase || info->name == stty_LCASE)) {
917 if (reversed) {
918 mode->c_lflag &= ~XCASE;
919 mode->c_iflag &= ~IUCLC;
920 mode->c_oflag &= ~OLCUC;
921 } else {
922 mode->c_lflag |= XCASE;
923 mode->c_iflag |= IUCLC;
924 mode->c_oflag |= OLCUC;
925 }
926 }
927 else if (info->name == stty_crt) {
928 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE;
929 }
930 else if (info->name == stty_dec) {
931 mode->c_cc[VINTR] = 3; /* ^C */
932 mode->c_cc[VERASE] = 127; /* DEL */
933 mode->c_cc[VKILL] = 21; /* ^U */
934 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE;
935 if (IXANY) mode->c_iflag &= ~IXANY;
936 }
937}
938
939static void display_changed(const struct termios *mode)
940{
941 int i;
942 tcflag_t *bitsp;
943 unsigned long mask;
944 int prev_type = control;
945
946 display_speed(mode, 1);
947#ifdef HAVE_C_LINE
948 wrapf("line = %d;\n", mode->c_line);
949#else
950 wrapf("\n");
951#endif
952
953 for (i = 0; control_info[i].name != stty_min; ++i) {
954 if (mode->c_cc[control_info[i].offset] == control_info[i].saneval)
955 continue;
956 /* If swtch is the same as susp, don't print both */
957#if VSWTCH == VSUSP
958 if (control_info[i].name == stty_swtch)
959 continue;
960#endif
961 /* If eof uses the same slot as min, only print whichever applies */
962#if VEOF == VMIN
963 if ((mode->c_lflag & ICANON) == 0
964 && (control_info[i].name == stty_eof
965 || control_info[i].name == stty_eol)) continue;
966#endif
967 wrapf("%s = %s;", control_info[i].name,
968 visible(mode->c_cc[control_info[i].offset]));
969 }
970 if ((mode->c_lflag & ICANON) == 0) {
971 wrapf("min = %d; time = %d;", (int) mode->c_cc[VMIN],
972 (int) mode->c_cc[VTIME]);
973 }
974 if (current_col) wrapf("\n");
975
976 for (i = 0; i < NUM_mode_info; ++i) {
977 if (mode_info[i].flags & OMIT)
978 continue;
979 if (mode_info[i].type != prev_type) {
980 if (current_col) wrapf("\n");
981 prev_type = mode_info[i].type;
982 }
983
984 bitsp = mode_type_flag(mode_info[i].type, mode);
985 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
986 if ((*bitsp & mask) == mode_info[i].bits) {
987 if (mode_info[i].flags & SANE_UNSET) {
988 wrapf("%s", mode_info[i].name);
989 }
990 } else if ((mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV)) {
991 wrapf("-%s", mode_info[i].name);
992 }
993 }
994 if (current_col) wrapf("\n");
995}
640 996
641static int recover_mode(const char *arg, struct termios *mode);
642static void set_mode(const struct mode_info *info,
643 int reversed, struct termios *mode);
644static void display_all(const struct termios *mode);
645static void display_changed(const struct termios *mode);
646static void display_recoverable(const struct termios *mode);
647static void display_speed(const struct termios *mode, int fancy);
648static void sane_mode(struct termios *mode);
649static void set_control_char_or_die(const struct control_info *info, 997static void set_control_char_or_die(const struct control_info *info,
650 const char *arg, struct termios *mode); 998 const char *arg, struct termios *mode)
999{
1000 unsigned char value;
1001
1002 if (info->name == stty_min || info->name == stty_time)
1003 value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes);
1004 else if (arg[0] == '\0' || arg[1] == '\0')
1005 value = arg[0];
1006 else if (streq(arg, "^-") || streq(arg, "undef"))
1007 value = _POSIX_VDISABLE;
1008 else if (arg[0] == '^') { /* Ignore any trailing junk (^Cjunk) */
1009 value = arg[1] & 0x1f; /* Non-letters get weird results */
1010 if (arg[1] == '?')
1011 value = 127;
1012 } else
1013 value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes);
1014 mode->c_cc[info->offset] = value;
1015}
651 1016
652int stty_main(int argc, char **argv) 1017int stty_main(int argc, char **argv)
653{ 1018{
@@ -928,380 +1293,3 @@ end_option:
928 1293
929 return EXIT_SUCCESS; 1294 return EXIT_SUCCESS;
930} 1295}
931
932/* Save set_mode from #ifdef forest plague */
933#ifndef ONLCR
934#define ONLCR 0
935#endif
936#ifndef OCRNL
937#define OCRNL 0
938#endif
939#ifndef ONLRET
940#define ONLRET 0
941#endif
942#ifndef XCASE
943#define XCASE 0
944#endif
945#ifndef IXANY
946#define IXANY 0
947#endif
948#ifndef TABDLY
949#define TABDLY 0
950#endif
951#ifndef OXTABS
952#define OXTABS 0
953#endif
954#ifndef IUCLC
955#define IUCLC 0
956#endif
957#ifndef OLCUC
958#define OLCUC 0
959#endif
960#ifndef ECHOCTL
961#define ECHOCTL 0
962#endif
963#ifndef ECHOKE
964#define ECHOKE 0
965#endif
966
967static void set_mode(const struct mode_info *info, int reversed,
968 struct termios *mode)
969{
970 tcflag_t *bitsp;
971
972 bitsp = mode_type_flag(info->type, mode);
973
974 if (bitsp) {
975 if (reversed)
976 *bitsp = *bitsp & ~info->mask & ~info->bits;
977 else
978 *bitsp = (*bitsp & ~info->mask) | info->bits;
979 return;
980 }
981
982 /* Combination mode */
983 if (info->name == evenp || info->name == parity) {
984 if (reversed)
985 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
986 else
987 mode->c_cflag = (mode->c_cflag & ~PARODD & ~CSIZE) | PARENB | CS7;
988 } else if (info->name == stty_oddp) {
989 if (reversed)
990 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
991 else
992 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARODD | PARENB;
993 } else if (info->name == stty_nl) {
994 if (reversed) {
995 mode->c_iflag = (mode->c_iflag | ICRNL) & ~INLCR & ~IGNCR;
996 mode->c_oflag = (mode->c_oflag | ONLCR) & ~OCRNL & ~ONLRET;
997 } else {
998 mode->c_iflag = mode->c_iflag & ~ICRNL;
999 if (ONLCR) mode->c_oflag = mode->c_oflag & ~ONLCR;
1000 }
1001 } else if (info->name == stty_ek) {
1002 mode->c_cc[VERASE] = CERASE;
1003 mode->c_cc[VKILL] = CKILL;
1004 } else if (info->name == stty_sane) {
1005 sane_mode(mode);
1006 }
1007 else if (info->name == cbreak) {
1008 if (reversed)
1009 mode->c_lflag |= ICANON;
1010 else
1011 mode->c_lflag &= ~ICANON;
1012 } else if (info->name == stty_pass8) {
1013 if (reversed) {
1014 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB;
1015 mode->c_iflag |= ISTRIP;
1016 } else {
1017 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
1018 mode->c_iflag &= ~ISTRIP;
1019 }
1020 } else if (info->name == litout) {
1021 if (reversed) {
1022 mode->c_cflag = (mode->c_cflag & ~CSIZE) | CS7 | PARENB;
1023 mode->c_iflag |= ISTRIP;
1024 mode->c_oflag |= OPOST;
1025 } else {
1026 mode->c_cflag = (mode->c_cflag & ~PARENB & ~CSIZE) | CS8;
1027 mode->c_iflag &= ~ISTRIP;
1028 mode->c_oflag &= ~OPOST;
1029 }
1030 } else if (info->name == raw || info->name == cooked) {
1031 if ((info->name[0] == 'r' && reversed)
1032 || (info->name[0] == 'c' && !reversed)) {
1033 /* Cooked mode */
1034 mode->c_iflag |= BRKINT | IGNPAR | ISTRIP | ICRNL | IXON;
1035 mode->c_oflag |= OPOST;
1036 mode->c_lflag |= ISIG | ICANON;
1037#if VMIN == VEOF
1038 mode->c_cc[VEOF] = CEOF;
1039#endif
1040#if VTIME == VEOL
1041 mode->c_cc[VEOL] = CEOL;
1042#endif
1043 } else {
1044 /* Raw mode */
1045 mode->c_iflag = 0;
1046 mode->c_oflag &= ~OPOST;
1047 mode->c_lflag &= ~(ISIG | ICANON | XCASE);
1048 mode->c_cc[VMIN] = 1;
1049 mode->c_cc[VTIME] = 0;
1050 }
1051 }
1052 else if (IXANY && info->name == decctlq) {
1053 if (reversed)
1054 mode->c_iflag |= IXANY;
1055 else
1056 mode->c_iflag &= ~IXANY;
1057 }
1058 else if (TABDLY && info->name == stty_tabs) {
1059 if (reversed)
1060 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3;
1061 else
1062 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0;
1063 }
1064 else if (OXTABS && info->name == stty_tabs) {
1065 if (reversed)
1066 mode->c_oflag |= OXTABS;
1067 else
1068 mode->c_oflag &= ~OXTABS;
1069 }
1070 else if (XCASE && IUCLC && OLCUC
1071 && (info->name == stty_lcase || info->name == stty_LCASE)) {
1072 if (reversed) {
1073 mode->c_lflag &= ~XCASE;
1074 mode->c_iflag &= ~IUCLC;
1075 mode->c_oflag &= ~OLCUC;
1076 } else {
1077 mode->c_lflag |= XCASE;
1078 mode->c_iflag |= IUCLC;
1079 mode->c_oflag |= OLCUC;
1080 }
1081 }
1082 else if (info->name == stty_crt) {
1083 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE;
1084 }
1085 else if (info->name == stty_dec) {
1086 mode->c_cc[VINTR] = 3; /* ^C */
1087 mode->c_cc[VERASE] = 127; /* DEL */
1088 mode->c_cc[VKILL] = 21; /* ^U */
1089 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE;
1090 if (IXANY) mode->c_iflag &= ~IXANY;
1091 }
1092}
1093
1094static void set_control_char_or_die(const struct control_info *info,
1095 const char *arg, struct termios *mode)
1096{
1097 unsigned char value;
1098
1099 if (info->name == stty_min || info->name == stty_time)
1100 value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes);
1101 else if (arg[0] == '\0' || arg[1] == '\0')
1102 value = arg[0];
1103 else if (streq(arg, "^-") || streq(arg, "undef"))
1104 value = _POSIX_VDISABLE;
1105 else if (arg[0] == '^') { /* Ignore any trailing junk (^Cjunk) */
1106 value = arg[1] & 0x1f; /* Non-letters get weird results */
1107 if (arg[1] == '?')
1108 value = 127;
1109 } else
1110 value = xatoul_range_sfx(arg, 0, 0xff, stty_suffixes);
1111 mode->c_cc[info->offset] = value;
1112}
1113
1114static void display_changed(const struct termios *mode)
1115{
1116 int i;
1117 tcflag_t *bitsp;
1118 unsigned long mask;
1119 int prev_type = control;
1120
1121 display_speed(mode, 1);
1122#ifdef HAVE_C_LINE
1123 wrapf("line = %d;\n", mode->c_line);
1124#else
1125 wrapf("\n");
1126#endif
1127
1128 for (i = 0; control_info[i].name != stty_min; ++i) {
1129 if (mode->c_cc[control_info[i].offset] == control_info[i].saneval)
1130 continue;
1131 /* If swtch is the same as susp, don't print both */
1132#if VSWTCH == VSUSP
1133 if (control_info[i].name == stty_swtch)
1134 continue;
1135#endif
1136 /* If eof uses the same slot as min, only print whichever applies */
1137#if VEOF == VMIN
1138 if ((mode->c_lflag & ICANON) == 0
1139 && (control_info[i].name == stty_eof
1140 || control_info[i].name == stty_eol)) continue;
1141#endif
1142 wrapf("%s = %s;", control_info[i].name,
1143 visible(mode->c_cc[control_info[i].offset]));
1144 }
1145 if ((mode->c_lflag & ICANON) == 0) {
1146 wrapf("min = %d; time = %d;", (int) mode->c_cc[VMIN],
1147 (int) mode->c_cc[VTIME]);
1148 }
1149 if (current_col) wrapf("\n");
1150
1151 for (i = 0; i < NUM_mode_info; ++i) {
1152 if (mode_info[i].flags & OMIT)
1153 continue;
1154 if (mode_info[i].type != prev_type) {
1155 if (current_col) wrapf("\n");
1156 prev_type = mode_info[i].type;
1157 }
1158
1159 bitsp = mode_type_flag(mode_info[i].type, mode);
1160 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
1161 if ((*bitsp & mask) == mode_info[i].bits) {
1162 if (mode_info[i].flags & SANE_UNSET) {
1163 wrapf("%s", mode_info[i].name);
1164 }
1165 } else if ((mode_info[i].flags & (SANE_SET | REV)) == (SANE_SET | REV)) {
1166 wrapf("-%s", mode_info[i].name);
1167 }
1168 }
1169 if (current_col) wrapf("\n");
1170}
1171
1172static void display_all(const struct termios *mode)
1173{
1174 int i;
1175 tcflag_t *bitsp;
1176 unsigned long mask;
1177 int prev_type = control;
1178
1179 display_speed(mode, 1);
1180 display_window_size(1);
1181#ifdef HAVE_C_LINE
1182 wrapf("line = %d;\n", mode->c_line);
1183#else
1184 wrapf("\n");
1185#endif
1186
1187 for (i = 0; control_info[i].name != stty_min; ++i) {
1188 /* If swtch is the same as susp, don't print both */
1189#if VSWTCH == VSUSP
1190 if (control_info[i].name == stty_swtch)
1191 continue;
1192#endif
1193 /* If eof uses the same slot as min, only print whichever applies */
1194#if VEOF == VMIN
1195 if ((mode->c_lflag & ICANON) == 0
1196 && (control_info[i].name == stty_eof
1197 || control_info[i].name == stty_eol)) continue;
1198#endif
1199 wrapf("%s = %s;", control_info[i].name,
1200 visible(mode->c_cc[control_info[i].offset]));
1201 }
1202#if VEOF == VMIN
1203 if ((mode->c_lflag & ICANON) == 0)
1204#endif
1205 wrapf("min = %d; time = %d;", mode->c_cc[VMIN], mode->c_cc[VTIME]);
1206 if (current_col) wrapf("\n");
1207
1208 for (i = 0; i < NUM_mode_info; ++i) {
1209 if (mode_info[i].flags & OMIT)
1210 continue;
1211 if (mode_info[i].type != prev_type) {
1212 wrapf("\n");
1213 prev_type = mode_info[i].type;
1214 }
1215
1216 bitsp = mode_type_flag(mode_info[i].type, mode);
1217 mask = mode_info[i].mask ? mode_info[i].mask : mode_info[i].bits;
1218 if ((*bitsp & mask) == mode_info[i].bits)
1219 wrapf("%s", mode_info[i].name);
1220 else if (mode_info[i].flags & REV)
1221 wrapf("-%s", mode_info[i].name);
1222 }
1223 if (current_col) wrapf("\n");
1224}
1225
1226static void display_speed(const struct termios *mode, int fancy)
1227{
1228 //01234567 8 9
1229 const char *fmt_str = "%lu %lu\n\0ispeed %lu baud; ospeed %lu baud;";
1230 unsigned long ispeed, ospeed;
1231
1232 ospeed = ispeed = cfgetispeed(mode);
1233 if (ispeed == 0 || ispeed == (ospeed = cfgetospeed(mode))) {
1234 ispeed = ospeed; /* in case ispeed was 0 */
1235 //0123 4 5 6 7 8 9
1236 fmt_str = "%lu\n\0\0\0\0\0speed %lu baud;";
1237 }
1238 if (fancy) fmt_str += 9;
1239 wrapf(fmt_str, tty_baud_to_value(ispeed), tty_baud_to_value(ospeed));
1240}
1241
1242static void display_recoverable(const struct termios *mode)
1243{
1244 int i;
1245 printf("%lx:%lx:%lx:%lx",
1246 (unsigned long) mode->c_iflag, (unsigned long) mode->c_oflag,
1247 (unsigned long) mode->c_cflag, (unsigned long) mode->c_lflag);
1248 for (i = 0; i < NCCS; ++i)
1249 printf(":%x", (unsigned int) mode->c_cc[i]);
1250 putchar('\n');
1251}
1252
1253static int recover_mode(const char *arg, struct termios *mode)
1254{
1255 int i, n;
1256 unsigned int chr;
1257 unsigned long iflag, oflag, cflag, lflag;
1258
1259 /* Scan into temporaries since it is too much trouble to figure out
1260 the right format for 'tcflag_t' */
1261 if (sscanf(arg, "%lx:%lx:%lx:%lx%n",
1262 &iflag, &oflag, &cflag, &lflag, &n) != 4)
1263 return 0;
1264 mode->c_iflag = iflag;
1265 mode->c_oflag = oflag;
1266 mode->c_cflag = cflag;
1267 mode->c_lflag = lflag;
1268 arg += n;
1269 for (i = 0; i < NCCS; ++i) {
1270 if (sscanf(arg, ":%x%n", &chr, &n) != 1)
1271 return 0;
1272 mode->c_cc[i] = chr;
1273 arg += n;
1274 }
1275
1276 /* Fail if there are too many fields */
1277 if (*arg != '\0')
1278 return 0;
1279
1280 return 1;
1281}
1282
1283static void sane_mode(struct termios *mode)
1284{
1285 int i;
1286 tcflag_t *bitsp;
1287
1288 for (i = 0; i < NUM_control_info; ++i) {
1289#if VMIN == VEOF
1290 if (control_info[i].name == stty_min)
1291 break;
1292#endif
1293 mode->c_cc[control_info[i].offset] = control_info[i].saneval;
1294 }
1295
1296 for (i = 0; i < NUM_mode_info; ++i) {
1297 if (mode_info[i].flags & SANE_SET) {
1298 bitsp = mode_type_flag(mode_info[i].type, mode);
1299 *bitsp = (*bitsp & ~((unsigned long)mode_info[i].mask))
1300 | mode_info[i].bits;
1301 } else if (mode_info[i].flags & SANE_UNSET) {
1302 bitsp = mode_type_flag(mode_info[i].type, mode);
1303 *bitsp = *bitsp & ~((unsigned long)mode_info[i].mask)
1304 & ~mode_info[i].bits;
1305 }
1306 }
1307}