diff options
author | Manuel Novoa III <mjn3@codepoet.org> | 2001-08-10 19:36:07 +0000 |
---|---|---|
committer | Manuel Novoa III <mjn3@codepoet.org> | 2001-08-10 19:36:07 +0000 |
commit | 16815d4b45f6678bfed3fd6e75ef1313e7f4817b (patch) | |
tree | aef7939e25cfef90cc88648a4ceb71e1595a5c77 | |
parent | 80dd0863e2e7b2988dd1e30e83197f241be55e70 (diff) | |
download | busybox-w32-16815d4b45f6678bfed3fd6e75ef1313e7f4817b.tar.gz busybox-w32-16815d4b45f6678bfed3fd6e75ef1313e7f4817b.tar.bz2 busybox-w32-16815d4b45f6678bfed3fd6e75ef1313e7f4817b.zip |
A few bug fixes and significant size savings. Combined effort of
Vladimir N. Oleynik dzo@simtreas.ru, Aaron Lehmann aaronl@vitelus.com,
and myself.
-rw-r--r-- | ash.c | 2241 | ||||
-rw-r--r-- | shell/ash.c | 2241 |
2 files changed, 2126 insertions, 2356 deletions
@@ -58,7 +58,7 @@ | |||
58 | /* Getopts is used by shell procedures to parse positional parameters. | 58 | /* Getopts is used by shell procedures to parse positional parameters. |
59 | * You probably want to leave this disabled, and use the busybox getopt | 59 | * You probably want to leave this disabled, and use the busybox getopt |
60 | * applet if you want to do this sort of thing. There are some scripts | 60 | * applet if you want to do this sort of thing. There are some scripts |
61 | * out there that use it, so if you need it, enable it. Most people will | 61 | * out there that use it, so it you need it, enable. Most people will |
62 | * leave this disabled. This adds 1k on an x86 system. */ | 62 | * leave this disabled. This adds 1k on an x86 system. */ |
63 | #undef ASH_GETOPTS | 63 | #undef ASH_GETOPTS |
64 | 64 | ||
@@ -81,6 +81,7 @@ | |||
81 | #undef GLOB_BROKEN | 81 | #undef GLOB_BROKEN |
82 | 82 | ||
83 | #include <assert.h> | 83 | #include <assert.h> |
84 | #include <stddef.h> | ||
84 | #include <ctype.h> | 85 | #include <ctype.h> |
85 | #include <dirent.h> | 86 | #include <dirent.h> |
86 | #include <errno.h> | 87 | #include <errno.h> |
@@ -142,13 +143,6 @@ | |||
142 | #define CSPCL 13 /* these terminate a word */ | 143 | #define CSPCL 13 /* these terminate a word */ |
143 | #define CIGN 14 /* character should be ignored */ | 144 | #define CIGN 14 /* character should be ignored */ |
144 | 145 | ||
145 | /* Syntax classes for is_ functions */ | ||
146 | #define ISDIGIT 01 /* a digit */ | ||
147 | #define ISUPPER 02 /* an upper case letter */ | ||
148 | #define ISLOWER 04 /* a lower case letter */ | ||
149 | #define ISUNDER 010 /* an underscore */ | ||
150 | #define ISSPECL 020 /* the name of a special parameter */ | ||
151 | |||
152 | #define SYNBASE 130 | 146 | #define SYNBASE 130 |
153 | #define PEOF -130 | 147 | #define PEOF -130 |
154 | 148 | ||
@@ -156,18 +150,18 @@ | |||
156 | 150 | ||
157 | #define TEOF 0 | 151 | #define TEOF 0 |
158 | #define TNL 1 | 152 | #define TNL 1 |
159 | #define TSEMI 2 | 153 | #define TREDIR 2 |
160 | #define TBACKGND 3 | 154 | #define TWORD 3 |
161 | #define TAND 4 | 155 | #define TASSIGN 4 |
162 | #define TOR 5 | 156 | #define TSEMI 5 |
163 | #define TPIPE 6 | 157 | #define TBACKGND 6 |
164 | #define TLP 7 | 158 | #define TAND 7 |
165 | #define TRP 8 | 159 | #define TOR 8 |
166 | #define TENDCASE 9 | 160 | #define TPIPE 9 |
167 | #define TENDBQUOTE 10 | 161 | #define TLP 10 |
168 | #define TREDIR 11 | 162 | #define TRP 11 |
169 | #define TWORD 12 | 163 | #define TENDCASE 12 |
170 | #define TASSIGN 13 | 164 | #define TENDBQUOTE 13 |
171 | #define TNOT 14 | 165 | #define TNOT 14 |
172 | #define TCASE 15 | 166 | #define TCASE 15 |
173 | #define TDO 16 | 167 | #define TDO 16 |
@@ -186,10 +180,6 @@ | |||
186 | #define TEND 29 | 180 | #define TEND 29 |
187 | 181 | ||
188 | 182 | ||
189 | #define BASESYNTAX (basesyntax + SYNBASE) | ||
190 | #define DQSYNTAX (dqsyntax + SYNBASE) | ||
191 | #define SQSYNTAX (sqsyntax + SYNBASE) | ||
192 | #define ARISYNTAX (arisyntax + SYNBASE) | ||
193 | 183 | ||
194 | /* control characters in argument strings */ | 184 | /* control characters in argument strings */ |
195 | #define CTLESC '\201' | 185 | #define CTLESC '\201' |
@@ -202,11 +192,19 @@ | |||
202 | #define CTLENDARI '\207' | 192 | #define CTLENDARI '\207' |
203 | #define CTLQUOTEMARK '\210' | 193 | #define CTLQUOTEMARK '\210' |
204 | 194 | ||
195 | |||
205 | #define is_digit(c) ((c)>='0' && (c)<='9') | 196 | #define is_digit(c) ((c)>='0' && (c)<='9') |
206 | #define is_alpha(c) (((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c))) | ||
207 | #define is_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c)))) | 197 | #define is_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c)))) |
208 | #define is_in_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c)))) | 198 | #define is_in_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c)))) |
209 | #define is_special(c) ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT)) | 199 | |
200 | /* | ||
201 | * is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise | ||
202 | * (assuming ascii char codes, as the original implementation did) | ||
203 | */ | ||
204 | #define is_special(c) \ | ||
205 | ( (((unsigned int)c) - 33 < 32) \ | ||
206 | && ((0xc1ff920dUL >> (((unsigned int)c) - 33)) & 1)) | ||
207 | |||
210 | #define digit_val(c) ((c) - '0') | 208 | #define digit_val(c) ((c) - '0') |
211 | 209 | ||
212 | 210 | ||
@@ -688,6 +686,7 @@ static void out2fmt (const char *, ...) | |||
688 | static int xwrite (int, const char *, int); | 686 | static int xwrite (int, const char *, int); |
689 | 687 | ||
690 | #define outstr(p,file) fputs(p, file) | 688 | #define outstr(p,file) fputs(p, file) |
689 | static void outstr (const char *p, FILE *file) { fputs(p, file); } | ||
691 | static void out1str(const char *p) { outstr(p, stdout); } | 690 | static void out1str(const char *p) { outstr(p, stdout); } |
692 | static void out2str(const char *p) { outstr(p, stderr); } | 691 | static void out2str(const char *p) { outstr(p, stderr); } |
693 | 692 | ||
@@ -697,439 +696,398 @@ static void out2str(const char *p) { outstr(p, stderr); } | |||
697 | static void out2c(int c) { putc(c, stderr); } | 696 | static void out2c(int c) { putc(c, stderr); } |
698 | #endif | 697 | #endif |
699 | 698 | ||
700 | /* syntax table used when not in quotes */ | ||
701 | static const char basesyntax[257] = { | ||
702 | CENDFILE, CSPCL, CWORD, CCTL, | ||
703 | CCTL, CCTL, CCTL, CCTL, | ||
704 | CCTL, CCTL, CCTL, CWORD, | ||
705 | CWORD, CWORD, CWORD, CWORD, | ||
706 | CWORD, CWORD, CWORD, CWORD, | ||
707 | CWORD, CWORD, CWORD, CWORD, | ||
708 | CWORD, CWORD, CWORD, CWORD, | ||
709 | CWORD, CWORD, CWORD, CWORD, | ||
710 | CWORD, CWORD, CWORD, CWORD, | ||
711 | CWORD, CWORD, CWORD, CWORD, | ||
712 | CWORD, CWORD, CWORD, CWORD, | ||
713 | CWORD, CWORD, CWORD, CWORD, | ||
714 | CWORD, CWORD, CWORD, CWORD, | ||
715 | CWORD, CWORD, CWORD, CWORD, | ||
716 | CWORD, CWORD, CWORD, CWORD, | ||
717 | CWORD, CWORD, CWORD, CWORD, | ||
718 | CWORD, CWORD, CWORD, CWORD, | ||
719 | CWORD, CWORD, CWORD, CWORD, | ||
720 | CWORD, CWORD, CWORD, CWORD, | ||
721 | CWORD, CWORD, CWORD, CWORD, | ||
722 | CWORD, CWORD, CWORD, CWORD, | ||
723 | CWORD, CWORD, CWORD, CWORD, | ||
724 | CWORD, CWORD, CWORD, CWORD, | ||
725 | CWORD, CWORD, CWORD, CWORD, | ||
726 | CWORD, CWORD, CWORD, CWORD, | ||
727 | CWORD, CWORD, CWORD, CWORD, | ||
728 | CWORD, CWORD, CWORD, CWORD, | ||
729 | CWORD, CWORD, CWORD, CWORD, | ||
730 | CWORD, CWORD, CWORD, CWORD, | ||
731 | CWORD, CWORD, CWORD, CWORD, | ||
732 | CWORD, CWORD, CWORD, CWORD, | ||
733 | CWORD, CWORD, CWORD, CWORD, | ||
734 | CWORD, CWORD, CWORD, CWORD, | ||
735 | CWORD, CWORD, CWORD, CWORD, | ||
736 | CWORD, CWORD, CWORD, CSPCL, | ||
737 | CNL, CWORD, CWORD, CWORD, | ||
738 | CWORD, CWORD, CWORD, CWORD, | ||
739 | CWORD, CWORD, CWORD, CWORD, | ||
740 | CWORD, CWORD, CWORD, CWORD, | ||
741 | CWORD, CWORD, CWORD, CWORD, | ||
742 | CWORD, CWORD, CSPCL, CWORD, | ||
743 | CDQUOTE, CWORD, CVAR, CWORD, | ||
744 | CSPCL, CSQUOTE, CSPCL, CSPCL, | ||
745 | CWORD, CWORD, CWORD, CWORD, | ||
746 | CWORD, CWORD, CWORD, CWORD, | ||
747 | CWORD, CWORD, CWORD, CWORD, | ||
748 | CWORD, CWORD, CWORD, CWORD, | ||
749 | CWORD, CSPCL, CSPCL, CWORD, | ||
750 | CSPCL, CWORD, CWORD, CWORD, | ||
751 | CWORD, CWORD, CWORD, CWORD, | ||
752 | CWORD, CWORD, CWORD, CWORD, | ||
753 | CWORD, CWORD, CWORD, CWORD, | ||
754 | CWORD, CWORD, CWORD, CWORD, | ||
755 | CWORD, CWORD, CWORD, CWORD, | ||
756 | CWORD, CWORD, CWORD, CWORD, | ||
757 | CWORD, CWORD, CBACK, CWORD, | ||
758 | CWORD, CWORD, CBQUOTE, CWORD, | ||
759 | CWORD, CWORD, CWORD, CWORD, | ||
760 | CWORD, CWORD, CWORD, CWORD, | ||
761 | CWORD, CWORD, CWORD, CWORD, | ||
762 | CWORD, CWORD, CWORD, CWORD, | ||
763 | CWORD, CWORD, CWORD, CWORD, | ||
764 | CWORD, CWORD, CWORD, CWORD, | ||
765 | CWORD, CWORD, CSPCL, CENDVAR, | ||
766 | CWORD | ||
767 | }; | ||
768 | |||
769 | /* syntax table used when in double quotes */ | ||
770 | static const char dqsyntax[257] = { | ||
771 | CENDFILE, CIGN, CWORD, CCTL, | ||
772 | CCTL, CCTL, CCTL, CCTL, | ||
773 | CCTL, CCTL, CCTL, CWORD, | ||
774 | CWORD, CWORD, CWORD, CWORD, | ||
775 | CWORD, CWORD, CWORD, CWORD, | ||
776 | CWORD, CWORD, CWORD, CWORD, | ||
777 | CWORD, CWORD, CWORD, CWORD, | ||
778 | CWORD, CWORD, CWORD, CWORD, | ||
779 | CWORD, CWORD, CWORD, CWORD, | ||
780 | CWORD, CWORD, CWORD, CWORD, | ||
781 | CWORD, CWORD, CWORD, CWORD, | ||
782 | CWORD, CWORD, CWORD, CWORD, | ||
783 | CWORD, CWORD, CWORD, CWORD, | ||
784 | CWORD, CWORD, CWORD, CWORD, | ||
785 | CWORD, CWORD, CWORD, CWORD, | ||
786 | CWORD, CWORD, CWORD, CWORD, | ||
787 | CWORD, CWORD, CWORD, CWORD, | ||
788 | CWORD, CWORD, CWORD, CWORD, | ||
789 | CWORD, CWORD, CWORD, CWORD, | ||
790 | CWORD, CWORD, CWORD, CWORD, | ||
791 | CWORD, CWORD, CWORD, CWORD, | ||
792 | CWORD, CWORD, CWORD, CWORD, | ||
793 | CWORD, CWORD, CWORD, CWORD, | ||
794 | CWORD, CWORD, CWORD, CWORD, | ||
795 | CWORD, CWORD, CWORD, CWORD, | ||
796 | CWORD, CWORD, CWORD, CWORD, | ||
797 | CWORD, CWORD, CWORD, CWORD, | ||
798 | CWORD, CWORD, CWORD, CWORD, | ||
799 | CWORD, CWORD, CWORD, CWORD, | ||
800 | CWORD, CWORD, CWORD, CWORD, | ||
801 | CWORD, CWORD, CWORD, CWORD, | ||
802 | CWORD, CWORD, CWORD, CWORD, | ||
803 | CWORD, CWORD, CWORD, CWORD, | ||
804 | CWORD, CWORD, CWORD, CWORD, | ||
805 | CWORD, CWORD, CWORD, CWORD, | ||
806 | CNL, CWORD, CWORD, CWORD, | ||
807 | CWORD, CWORD, CWORD, CWORD, | ||
808 | CWORD, CWORD, CWORD, CWORD, | ||
809 | CWORD, CWORD, CWORD, CWORD, | ||
810 | CWORD, CWORD, CWORD, CWORD, | ||
811 | CWORD, CWORD, CWORD, CCTL, | ||
812 | CENDQUOTE,CWORD, CVAR, CWORD, | ||
813 | CWORD, CWORD, CWORD, CWORD, | ||
814 | CCTL, CWORD, CWORD, CCTL, | ||
815 | CWORD, CCTL, CWORD, CWORD, | ||
816 | CWORD, CWORD, CWORD, CWORD, | ||
817 | CWORD, CWORD, CWORD, CWORD, | ||
818 | CCTL, CWORD, CWORD, CCTL, | ||
819 | CWORD, CCTL, CWORD, CWORD, | ||
820 | CWORD, CWORD, CWORD, CWORD, | ||
821 | CWORD, CWORD, CWORD, CWORD, | ||
822 | CWORD, CWORD, CWORD, CWORD, | ||
823 | CWORD, CWORD, CWORD, CWORD, | ||
824 | CWORD, CWORD, CWORD, CWORD, | ||
825 | CWORD, CWORD, CWORD, CWORD, | ||
826 | CWORD, CCTL, CBACK, CCTL, | ||
827 | CWORD, CWORD, CBQUOTE, CWORD, | ||
828 | CWORD, CWORD, CWORD, CWORD, | ||
829 | CWORD, CWORD, CWORD, CWORD, | ||
830 | CWORD, CWORD, CWORD, CWORD, | ||
831 | CWORD, CWORD, CWORD, CWORD, | ||
832 | CWORD, CWORD, CWORD, CWORD, | ||
833 | CWORD, CWORD, CWORD, CWORD, | ||
834 | CWORD, CWORD, CWORD, CENDVAR, | ||
835 | CCTL | ||
836 | }; | ||
837 | 699 | ||
838 | /* syntax table used when in single quotes */ | 700 | #ifdef ASH_OPTIMIZE_FOR_SIZE |
839 | static const char sqsyntax[257] = { | 701 | #define USE_SIT_FUNCTION |
840 | CENDFILE, CIGN, CWORD, CCTL, | 702 | #endif |
841 | CCTL, CCTL, CCTL, CCTL, | 703 | |
842 | CCTL, CCTL, CCTL, CWORD, | 704 | /* number syntax index */ |
843 | CWORD, CWORD, CWORD, CWORD, | 705 | #define BASESYNTAX 0 /* not in quotes */ |
844 | CWORD, CWORD, CWORD, CWORD, | 706 | #define DQSYNTAX 1 /* in double quotes */ |
845 | CWORD, CWORD, CWORD, CWORD, | 707 | #define SQSYNTAX 2 /* in single quotes */ |
846 | CWORD, CWORD, CWORD, CWORD, | 708 | #define ARISYNTAX 3 /* in arithmetic */ |
847 | CWORD, CWORD, CWORD, CWORD, | 709 | |
848 | CWORD, CWORD, CWORD, CWORD, | 710 | static const char S_I_T[][4] = { |
849 | CWORD, CWORD, CWORD, CWORD, | 711 | /* 0 */ { CSPCL, CIGN, CIGN, CIGN }, /* PEOA */ |
850 | CWORD, CWORD, CWORD, CWORD, | 712 | /* 1 */ { CSPCL, CWORD, CWORD, CWORD }, /* ' ' */ |
851 | CWORD, CWORD, CWORD, CWORD, | 713 | /* 2 */ { CNL, CNL, CNL, CNL }, /* \n */ |
852 | CWORD, CWORD, CWORD, CWORD, | 714 | /* 3 */ { CWORD, CCTL, CCTL, CWORD }, /* !*-/:=?[]~ */ |
853 | CWORD, CWORD, CWORD, CWORD, | 715 | /* 4 */ { CDQUOTE, CENDQUOTE, CWORD, CDQUOTE }, /* '"' */ |
854 | CWORD, CWORD, CWORD, CWORD, | 716 | /* 5 */ { CVAR, CVAR, CWORD, CVAR }, /* $ */ |
855 | CWORD, CWORD, CWORD, CWORD, | 717 | /* 6 */ { CSQUOTE, CWORD, CENDQUOTE, CSQUOTE }, /* "'" */ |
856 | CWORD, CWORD, CWORD, CWORD, | 718 | /* 7 */ { CSPCL, CWORD, CWORD, CLP }, /* ( */ |
857 | CWORD, CWORD, CWORD, CWORD, | 719 | /* 8 */ { CSPCL, CWORD, CWORD, CRP }, /* ) */ |
858 | CWORD, CWORD, CWORD, CWORD, | 720 | /* 9 */ { CBACK, CBACK, CCTL, CBACK }, /* \ */ |
859 | CWORD, CWORD, CWORD, CWORD, | 721 | /* 10 */ { CBQUOTE, CBQUOTE, CWORD, CBQUOTE }, /* ` */ |
860 | CWORD, CWORD, CWORD, CWORD, | 722 | /* 11 */ { CENDVAR, CENDVAR, CWORD, CENDVAR }, /* } */ |
861 | CWORD, CWORD, CWORD, CWORD, | 723 | #ifndef USE_SIT_FUNCTION |
862 | CWORD, CWORD, CWORD, CWORD, | 724 | /* 12 */ { CENDFILE, CENDFILE, CENDFILE, CENDFILE }, /* PEOF */ |
863 | CWORD, CWORD, CWORD, CWORD, | 725 | /* 13 */ { CWORD, CWORD, CWORD, CWORD }, /* 0-9A-Za-z */ |
864 | CWORD, CWORD, CWORD, CWORD, | 726 | /* 14 */ { CCTL, CCTL, CCTL, CCTL } /* CTLESC ... */ |
865 | CWORD, CWORD, CWORD, CWORD, | 727 | #endif |
866 | CWORD, CWORD, CWORD, CWORD, | ||
867 | CWORD, CWORD, CWORD, CWORD, | ||
868 | CWORD, CWORD, CWORD, CWORD, | ||
869 | CWORD, CWORD, CWORD, CWORD, | ||
870 | CWORD, CWORD, CWORD, CWORD, | ||
871 | CWORD, CWORD, CWORD, CWORD, | ||
872 | CWORD, CWORD, CWORD, CWORD, | ||
873 | CWORD, CWORD, CWORD, CWORD, | ||
874 | CWORD, CWORD, CWORD, CWORD, | ||
875 | CNL, CWORD, CWORD, CWORD, | ||
876 | CWORD, CWORD, CWORD, CWORD, | ||
877 | CWORD, CWORD, CWORD, CWORD, | ||
878 | CWORD, CWORD, CWORD, CWORD, | ||
879 | CWORD, CWORD, CWORD, CWORD, | ||
880 | CWORD, CWORD, CWORD, CCTL, | ||
881 | CWORD, CWORD, CWORD, CWORD, | ||
882 | CWORD, CENDQUOTE,CWORD, CWORD, | ||
883 | CCTL, CWORD, CWORD, CCTL, | ||
884 | CWORD, CCTL, CWORD, CWORD, | ||
885 | CWORD, CWORD, CWORD, CWORD, | ||
886 | CWORD, CWORD, CWORD, CWORD, | ||
887 | CCTL, CWORD, CWORD, CCTL, | ||
888 | CWORD, CCTL, CWORD, CWORD, | ||
889 | CWORD, CWORD, CWORD, CWORD, | ||
890 | CWORD, CWORD, CWORD, CWORD, | ||
891 | CWORD, CWORD, CWORD, CWORD, | ||
892 | CWORD, CWORD, CWORD, CWORD, | ||
893 | CWORD, CWORD, CWORD, CWORD, | ||
894 | CWORD, CWORD, CWORD, CWORD, | ||
895 | CWORD, CCTL, CCTL, CCTL, | ||
896 | CWORD, CWORD, CWORD, CWORD, | ||
897 | CWORD, CWORD, CWORD, CWORD, | ||
898 | CWORD, CWORD, CWORD, CWORD, | ||
899 | CWORD, CWORD, CWORD, CWORD, | ||
900 | CWORD, CWORD, CWORD, CWORD, | ||
901 | CWORD, CWORD, CWORD, CWORD, | ||
902 | CWORD, CWORD, CWORD, CWORD, | ||
903 | CWORD, CWORD, CWORD, CWORD, | ||
904 | CCTL | ||
905 | }; | ||
906 | |||
907 | /* syntax table used when in arithmetic */ | ||
908 | static const char arisyntax[257] = { | ||
909 | CENDFILE, CIGN, CWORD, CCTL, | ||
910 | CCTL, CCTL, CCTL, CCTL, | ||
911 | CCTL, CCTL, CCTL, CWORD, | ||
912 | CWORD, CWORD, CWORD, CWORD, | ||
913 | CWORD, CWORD, CWORD, CWORD, | ||
914 | CWORD, CWORD, CWORD, CWORD, | ||
915 | CWORD, CWORD, CWORD, CWORD, | ||
916 | CWORD, CWORD, CWORD, CWORD, | ||
917 | CWORD, CWORD, CWORD, CWORD, | ||
918 | CWORD, CWORD, CWORD, CWORD, | ||
919 | CWORD, CWORD, CWORD, CWORD, | ||
920 | CWORD, CWORD, CWORD, CWORD, | ||
921 | CWORD, CWORD, CWORD, CWORD, | ||
922 | CWORD, CWORD, CWORD, CWORD, | ||
923 | CWORD, CWORD, CWORD, CWORD, | ||
924 | CWORD, CWORD, CWORD, CWORD, | ||
925 | CWORD, CWORD, CWORD, CWORD, | ||
926 | CWORD, CWORD, CWORD, CWORD, | ||
927 | CWORD, CWORD, CWORD, CWORD, | ||
928 | CWORD, CWORD, CWORD, CWORD, | ||
929 | CWORD, CWORD, CWORD, CWORD, | ||
930 | CWORD, CWORD, CWORD, CWORD, | ||
931 | CWORD, CWORD, CWORD, CWORD, | ||
932 | CWORD, CWORD, CWORD, CWORD, | ||
933 | CWORD, CWORD, CWORD, CWORD, | ||
934 | CWORD, CWORD, CWORD, CWORD, | ||
935 | CWORD, CWORD, CWORD, CWORD, | ||
936 | CWORD, CWORD, CWORD, CWORD, | ||
937 | CWORD, CWORD, CWORD, CWORD, | ||
938 | CWORD, CWORD, CWORD, CWORD, | ||
939 | CWORD, CWORD, CWORD, CWORD, | ||
940 | CWORD, CWORD, CWORD, CWORD, | ||
941 | CWORD, CWORD, CWORD, CWORD, | ||
942 | CWORD, CWORD, CWORD, CWORD, | ||
943 | CWORD, CWORD, CWORD, CWORD, | ||
944 | CNL, CWORD, CWORD, CWORD, | ||
945 | CWORD, CWORD, CWORD, CWORD, | ||
946 | CWORD, CWORD, CWORD, CWORD, | ||
947 | CWORD, CWORD, CWORD, CWORD, | ||
948 | CWORD, CWORD, CWORD, CWORD, | ||
949 | CWORD, CWORD, CWORD, CWORD, | ||
950 | CDQUOTE, CWORD, CVAR, CWORD, | ||
951 | CWORD, CSQUOTE, CLP, CRP, | ||
952 | CWORD, CWORD, CWORD, CWORD, | ||
953 | CWORD, CWORD, CWORD, CWORD, | ||
954 | CWORD, CWORD, CWORD, CWORD, | ||
955 | CWORD, CWORD, CWORD, CWORD, | ||
956 | CWORD, CWORD, CWORD, CWORD, | ||
957 | CWORD, CWORD, CWORD, CWORD, | ||
958 | CWORD, CWORD, CWORD, CWORD, | ||
959 | CWORD, CWORD, CWORD, CWORD, | ||
960 | CWORD, CWORD, CWORD, CWORD, | ||
961 | CWORD, CWORD, CWORD, CWORD, | ||
962 | CWORD, CWORD, CWORD, CWORD, | ||
963 | CWORD, CWORD, CWORD, CWORD, | ||
964 | CWORD, CWORD, CBACK, CWORD, | ||
965 | CWORD, CWORD, CBQUOTE, CWORD, | ||
966 | CWORD, CWORD, CWORD, CWORD, | ||
967 | CWORD, CWORD, CWORD, CWORD, | ||
968 | CWORD, CWORD, CWORD, CWORD, | ||
969 | CWORD, CWORD, CWORD, CWORD, | ||
970 | CWORD, CWORD, CWORD, CWORD, | ||
971 | CWORD, CWORD, CWORD, CWORD, | ||
972 | CWORD, CWORD, CWORD, CENDVAR, | ||
973 | CWORD | ||
974 | }; | 728 | }; |
975 | 729 | ||
976 | /* character classification table */ | 730 | #ifdef USE_SIT_FUNCTION |
977 | static const char is_type[257] = { | ||
978 | 0, 0, 0, 0, | ||
979 | 0, 0, 0, 0, | ||
980 | 0, 0, 0, 0, | ||
981 | 0, 0, 0, 0, | ||
982 | 0, 0, 0, 0, | ||
983 | 0, 0, 0, 0, | ||
984 | 0, 0, 0, 0, | ||
985 | 0, 0, 0, 0, | ||
986 | 0, 0, 0, 0, | ||
987 | 0, 0, 0, 0, | ||
988 | 0, 0, 0, 0, | ||
989 | 0, 0, 0, 0, | ||
990 | 0, 0, 0, 0, | ||
991 | 0, 0, 0, 0, | ||
992 | 0, 0, 0, 0, | ||
993 | 0, 0, 0, 0, | ||
994 | 0, 0, 0, 0, | ||
995 | 0, 0, 0, 0, | ||
996 | 0, 0, 0, 0, | ||
997 | 0, 0, 0, 0, | ||
998 | 0, 0, 0, 0, | ||
999 | 0, 0, 0, 0, | ||
1000 | 0, 0, 0, 0, | ||
1001 | 0, 0, 0, 0, | ||
1002 | 0, 0, 0, 0, | ||
1003 | 0, 0, 0, 0, | ||
1004 | 0, 0, 0, 0, | ||
1005 | 0, 0, 0, 0, | ||
1006 | 0, 0, 0, 0, | ||
1007 | 0, 0, 0, 0, | ||
1008 | 0, 0, 0, 0, | ||
1009 | 0, 0, 0, 0, | ||
1010 | 0, 0, 0, 0, | ||
1011 | 0, 0, 0, 0, | ||
1012 | 0, 0, 0, 0, | ||
1013 | 0, 0, 0, 0, | ||
1014 | 0, 0, 0, 0, | ||
1015 | 0, 0, 0, 0, | ||
1016 | 0, 0, 0, 0, | ||
1017 | 0, 0, 0, 0, | ||
1018 | 0, 0, 0, ISSPECL, | ||
1019 | 0, ISSPECL, ISSPECL, 0, | ||
1020 | 0, 0, 0, 0, | ||
1021 | ISSPECL, 0, 0, ISSPECL, | ||
1022 | 0, 0, ISDIGIT, ISDIGIT, | ||
1023 | ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, | ||
1024 | ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, | ||
1025 | 0, 0, 0, 0, | ||
1026 | 0, ISSPECL, ISSPECL, ISUPPER, | ||
1027 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1028 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1029 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1030 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1031 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1032 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1033 | ISUPPER, 0, 0, 0, | ||
1034 | 0, ISUNDER, 0, ISLOWER, | ||
1035 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1036 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1037 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1038 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1039 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1040 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1041 | ISLOWER, 0, 0, 0, | ||
1042 | 0 | ||
1043 | }; | ||
1044 | 731 | ||
1045 | /* Array indicating which tokens mark the end of a list */ | 732 | #define U_C(c) ((unsigned char)(c)) |
1046 | static const char tokendlist[] = { | ||
1047 | 1, | ||
1048 | 0, | ||
1049 | 0, | ||
1050 | 0, | ||
1051 | 0, | ||
1052 | 0, | ||
1053 | 0, | ||
1054 | 0, | ||
1055 | 1, | ||
1056 | 1, | ||
1057 | 1, | ||
1058 | 0, | ||
1059 | 0, | ||
1060 | 0, | ||
1061 | 0, | ||
1062 | 0, | ||
1063 | 1, | ||
1064 | 1, | ||
1065 | 1, | ||
1066 | 1, | ||
1067 | 1, | ||
1068 | 1, | ||
1069 | 0, | ||
1070 | 0, | ||
1071 | 0, | ||
1072 | 1, | ||
1073 | 0, | ||
1074 | 0, | ||
1075 | 0, | ||
1076 | 1, | ||
1077 | }; | ||
1078 | 733 | ||
1079 | static const char *const tokname[] = { | 734 | static int SIT(int c, int syntax) |
1080 | "end of file", | 735 | { |
1081 | "newline", | 736 | static const char spec_symbls[]="\t\n !\"$&'()*-/:;<=>?[\\]`|}~"; |
1082 | "\";\"", | 737 | static const char syntax_index_table [] = { |
1083 | "\"&\"", | 738 | 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */ |
1084 | "\"&&\"", | 739 | 7, 8, 3, 3, 3, 3, 1, 1, /* "()*-/:;<" */ |
1085 | "\"||\"", | 740 | 3, 1, 3, 3, 9, 3,10, 1, /* "=>?[\\]`|" */ |
1086 | "\"|\"", | 741 | 11,3 }; /* "}~" */ |
1087 | "\"(\"", | 742 | const char *s; |
1088 | "\")\"", | 743 | int indx; |
1089 | "\";;\"", | 744 | |
1090 | "\"`\"", | 745 | if(c==PEOF) /* 2^8+2 */ |
1091 | "redirection", | 746 | return CENDFILE; |
1092 | "word", | 747 | if(c==PEOA) /* 2^8+1 */ |
1093 | "assignment", | 748 | indx = 0; |
1094 | "\"!\"", | 749 | else if(U_C(c)>=U_C(CTLESC) && U_C(c)<=U_C(CTLQUOTEMARK)) |
1095 | "\"case\"", | 750 | return CCTL; |
1096 | "\"do\"", | 751 | else { |
1097 | "\"done\"", | 752 | s = strchr(spec_symbls, c); |
1098 | "\"elif\"", | 753 | if(s==0) |
1099 | "\"else\"", | 754 | return CWORD; |
1100 | "\"esac\"", | 755 | indx = syntax_index_table[(s-spec_symbls)]; |
1101 | "\"fi\"", | 756 | } |
1102 | "\"for\"", | 757 | return S_I_T[indx][syntax]; |
1103 | "\"if\"", | 758 | } |
1104 | "\"in\"", | 759 | |
1105 | "\"then\"", | 760 | #else /* USE_SIT_FUNCTION */ |
1106 | "\"until\"", | 761 | |
1107 | "\"while\"", | 762 | #define SIT(c, syntax) S_I_T[(int)syntax_index_table[((int)c)+SYNBASE]][syntax] |
1108 | "\"{\"", | 763 | |
1109 | "\"}\"", | 764 | #define CSPCL_CIGN_CIGN_CIGN 0 |
765 | #define CSPCL_CWORD_CWORD_CWORD 1 | ||
766 | #define CNL_CNL_CNL_CNL 2 | ||
767 | #define CWORD_CCTL_CCTL_CWORD 3 | ||
768 | #define CDQUOTE_CENDQUOTE_CWORD_CDQUOTE 4 | ||
769 | #define CVAR_CVAR_CWORD_CVAR 5 | ||
770 | #define CSQUOTE_CWORD_CENDQUOTE_CSQUOTE 6 | ||
771 | #define CSPCL_CWORD_CWORD_CLP 7 | ||
772 | #define CSPCL_CWORD_CWORD_CRP 8 | ||
773 | #define CBACK_CBACK_CCTL_CBACK 9 | ||
774 | #define CBQUOTE_CBQUOTE_CWORD_CBQUOTE 10 | ||
775 | #define CENDVAR_CENDVAR_CWORD_CENDVAR 11 | ||
776 | #define CENDFILE_CENDFILE_CENDFILE_CENDFILE 12 | ||
777 | #define CWORD_CWORD_CWORD_CWORD 13 | ||
778 | #define CCTL_CCTL_CCTL_CCTL 14 | ||
779 | |||
780 | static const char syntax_index_table[258] = { | ||
781 | /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */ | ||
782 | /* 0 -130 PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE, | ||
783 | /* 1 -129 PEOA */ CSPCL_CIGN_CIGN_CIGN, | ||
784 | /* 2 -128 0xff */ CWORD_CWORD_CWORD_CWORD, | ||
785 | /* 3 -127 */ CCTL_CCTL_CCTL_CCTL, /* CTLQUOTEMARK */ | ||
786 | /* 4 -126 */ CCTL_CCTL_CCTL_CCTL, | ||
787 | /* 5 -125 */ CCTL_CCTL_CCTL_CCTL, | ||
788 | /* 6 -124 */ CCTL_CCTL_CCTL_CCTL, | ||
789 | /* 7 -123 */ CCTL_CCTL_CCTL_CCTL, | ||
790 | /* 8 -122 */ CCTL_CCTL_CCTL_CCTL, | ||
791 | /* 9 -121 */ CCTL_CCTL_CCTL_CCTL, | ||
792 | /* 10 -120 */ CCTL_CCTL_CCTL_CCTL, /* CTLESC */ | ||
793 | /* 11 -119 */ CWORD_CWORD_CWORD_CWORD, | ||
794 | /* 12 -118 */ CWORD_CWORD_CWORD_CWORD, | ||
795 | /* 13 -117 */ CWORD_CWORD_CWORD_CWORD, | ||
796 | /* 14 -116 */ CWORD_CWORD_CWORD_CWORD, | ||
797 | /* 15 -115 */ CWORD_CWORD_CWORD_CWORD, | ||
798 | /* 16 -114 */ CWORD_CWORD_CWORD_CWORD, | ||
799 | /* 17 -113 */ CWORD_CWORD_CWORD_CWORD, | ||
800 | /* 18 -112 */ CWORD_CWORD_CWORD_CWORD, | ||
801 | /* 19 -111 */ CWORD_CWORD_CWORD_CWORD, | ||
802 | /* 20 -110 */ CWORD_CWORD_CWORD_CWORD, | ||
803 | /* 21 -109 */ CWORD_CWORD_CWORD_CWORD, | ||
804 | /* 22 -108 */ CWORD_CWORD_CWORD_CWORD, | ||
805 | /* 23 -107 */ CWORD_CWORD_CWORD_CWORD, | ||
806 | /* 24 -106 */ CWORD_CWORD_CWORD_CWORD, | ||
807 | /* 25 -105 */ CWORD_CWORD_CWORD_CWORD, | ||
808 | /* 26 -104 */ CWORD_CWORD_CWORD_CWORD, | ||
809 | /* 27 -103 */ CWORD_CWORD_CWORD_CWORD, | ||
810 | /* 28 -102 */ CWORD_CWORD_CWORD_CWORD, | ||
811 | /* 29 -101 */ CWORD_CWORD_CWORD_CWORD, | ||
812 | /* 30 -100 */ CWORD_CWORD_CWORD_CWORD, | ||
813 | /* 31 -99 */ CWORD_CWORD_CWORD_CWORD, | ||
814 | /* 32 -98 */ CWORD_CWORD_CWORD_CWORD, | ||
815 | /* 33 -97 */ CWORD_CWORD_CWORD_CWORD, | ||
816 | /* 34 -96 */ CWORD_CWORD_CWORD_CWORD, | ||
817 | /* 35 -95 */ CWORD_CWORD_CWORD_CWORD, | ||
818 | /* 36 -94 */ CWORD_CWORD_CWORD_CWORD, | ||
819 | /* 37 -93 */ CWORD_CWORD_CWORD_CWORD, | ||
820 | /* 38 -92 */ CWORD_CWORD_CWORD_CWORD, | ||
821 | /* 39 -91 */ CWORD_CWORD_CWORD_CWORD, | ||
822 | /* 40 -90 */ CWORD_CWORD_CWORD_CWORD, | ||
823 | /* 41 -89 */ CWORD_CWORD_CWORD_CWORD, | ||
824 | /* 42 -88 */ CWORD_CWORD_CWORD_CWORD, | ||
825 | /* 43 -87 */ CWORD_CWORD_CWORD_CWORD, | ||
826 | /* 44 -86 */ CWORD_CWORD_CWORD_CWORD, | ||
827 | /* 45 -85 */ CWORD_CWORD_CWORD_CWORD, | ||
828 | /* 46 -84 */ CWORD_CWORD_CWORD_CWORD, | ||
829 | /* 47 -83 */ CWORD_CWORD_CWORD_CWORD, | ||
830 | /* 48 -82 */ CWORD_CWORD_CWORD_CWORD, | ||
831 | /* 49 -81 */ CWORD_CWORD_CWORD_CWORD, | ||
832 | /* 50 -80 */ CWORD_CWORD_CWORD_CWORD, | ||
833 | /* 51 -79 */ CWORD_CWORD_CWORD_CWORD, | ||
834 | /* 52 -78 */ CWORD_CWORD_CWORD_CWORD, | ||
835 | /* 53 -77 */ CWORD_CWORD_CWORD_CWORD, | ||
836 | /* 54 -76 */ CWORD_CWORD_CWORD_CWORD, | ||
837 | /* 55 -75 */ CWORD_CWORD_CWORD_CWORD, | ||
838 | /* 56 -74 */ CWORD_CWORD_CWORD_CWORD, | ||
839 | /* 57 -73 */ CWORD_CWORD_CWORD_CWORD, | ||
840 | /* 58 -72 */ CWORD_CWORD_CWORD_CWORD, | ||
841 | /* 59 -71 */ CWORD_CWORD_CWORD_CWORD, | ||
842 | /* 60 -70 */ CWORD_CWORD_CWORD_CWORD, | ||
843 | /* 61 -69 */ CWORD_CWORD_CWORD_CWORD, | ||
844 | /* 62 -68 */ CWORD_CWORD_CWORD_CWORD, | ||
845 | /* 63 -67 */ CWORD_CWORD_CWORD_CWORD, | ||
846 | /* 64 -66 */ CWORD_CWORD_CWORD_CWORD, | ||
847 | /* 65 -65 */ CWORD_CWORD_CWORD_CWORD, | ||
848 | /* 66 -64 */ CWORD_CWORD_CWORD_CWORD, | ||
849 | /* 67 -63 */ CWORD_CWORD_CWORD_CWORD, | ||
850 | /* 68 -62 */ CWORD_CWORD_CWORD_CWORD, | ||
851 | /* 69 -61 */ CWORD_CWORD_CWORD_CWORD, | ||
852 | /* 70 -60 */ CWORD_CWORD_CWORD_CWORD, | ||
853 | /* 71 -59 */ CWORD_CWORD_CWORD_CWORD, | ||
854 | /* 72 -58 */ CWORD_CWORD_CWORD_CWORD, | ||
855 | /* 73 -57 */ CWORD_CWORD_CWORD_CWORD, | ||
856 | /* 74 -56 */ CWORD_CWORD_CWORD_CWORD, | ||
857 | /* 75 -55 */ CWORD_CWORD_CWORD_CWORD, | ||
858 | /* 76 -54 */ CWORD_CWORD_CWORD_CWORD, | ||
859 | /* 77 -53 */ CWORD_CWORD_CWORD_CWORD, | ||
860 | /* 78 -52 */ CWORD_CWORD_CWORD_CWORD, | ||
861 | /* 79 -51 */ CWORD_CWORD_CWORD_CWORD, | ||
862 | /* 80 -50 */ CWORD_CWORD_CWORD_CWORD, | ||
863 | /* 81 -49 */ CWORD_CWORD_CWORD_CWORD, | ||
864 | /* 82 -48 */ CWORD_CWORD_CWORD_CWORD, | ||
865 | /* 83 -47 */ CWORD_CWORD_CWORD_CWORD, | ||
866 | /* 84 -46 */ CWORD_CWORD_CWORD_CWORD, | ||
867 | /* 85 -45 */ CWORD_CWORD_CWORD_CWORD, | ||
868 | /* 86 -44 */ CWORD_CWORD_CWORD_CWORD, | ||
869 | /* 87 -43 */ CWORD_CWORD_CWORD_CWORD, | ||
870 | /* 88 -42 */ CWORD_CWORD_CWORD_CWORD, | ||
871 | /* 89 -41 */ CWORD_CWORD_CWORD_CWORD, | ||
872 | /* 90 -40 */ CWORD_CWORD_CWORD_CWORD, | ||
873 | /* 91 -39 */ CWORD_CWORD_CWORD_CWORD, | ||
874 | /* 92 -38 */ CWORD_CWORD_CWORD_CWORD, | ||
875 | /* 93 -37 */ CWORD_CWORD_CWORD_CWORD, | ||
876 | /* 94 -36 */ CWORD_CWORD_CWORD_CWORD, | ||
877 | /* 95 -35 */ CWORD_CWORD_CWORD_CWORD, | ||
878 | /* 96 -34 */ CWORD_CWORD_CWORD_CWORD, | ||
879 | /* 97 -33 */ CWORD_CWORD_CWORD_CWORD, | ||
880 | /* 98 -32 */ CWORD_CWORD_CWORD_CWORD, | ||
881 | /* 99 -31 */ CWORD_CWORD_CWORD_CWORD, | ||
882 | /* 100 -30 */ CWORD_CWORD_CWORD_CWORD, | ||
883 | /* 101 -29 */ CWORD_CWORD_CWORD_CWORD, | ||
884 | /* 102 -28 */ CWORD_CWORD_CWORD_CWORD, | ||
885 | /* 103 -27 */ CWORD_CWORD_CWORD_CWORD, | ||
886 | /* 104 -26 */ CWORD_CWORD_CWORD_CWORD, | ||
887 | /* 105 -25 */ CWORD_CWORD_CWORD_CWORD, | ||
888 | /* 106 -24 */ CWORD_CWORD_CWORD_CWORD, | ||
889 | /* 107 -23 */ CWORD_CWORD_CWORD_CWORD, | ||
890 | /* 108 -22 */ CWORD_CWORD_CWORD_CWORD, | ||
891 | /* 109 -21 */ CWORD_CWORD_CWORD_CWORD, | ||
892 | /* 110 -20 */ CWORD_CWORD_CWORD_CWORD, | ||
893 | /* 111 -19 */ CWORD_CWORD_CWORD_CWORD, | ||
894 | /* 112 -18 */ CWORD_CWORD_CWORD_CWORD, | ||
895 | /* 113 -17 */ CWORD_CWORD_CWORD_CWORD, | ||
896 | /* 114 -16 */ CWORD_CWORD_CWORD_CWORD, | ||
897 | /* 115 -15 */ CWORD_CWORD_CWORD_CWORD, | ||
898 | /* 116 -14 */ CWORD_CWORD_CWORD_CWORD, | ||
899 | /* 117 -13 */ CWORD_CWORD_CWORD_CWORD, | ||
900 | /* 118 -12 */ CWORD_CWORD_CWORD_CWORD, | ||
901 | /* 119 -11 */ CWORD_CWORD_CWORD_CWORD, | ||
902 | /* 120 -10 */ CWORD_CWORD_CWORD_CWORD, | ||
903 | /* 121 -9 */ CWORD_CWORD_CWORD_CWORD, | ||
904 | /* 122 -8 */ CWORD_CWORD_CWORD_CWORD, | ||
905 | /* 123 -7 */ CWORD_CWORD_CWORD_CWORD, | ||
906 | /* 124 -6 */ CWORD_CWORD_CWORD_CWORD, | ||
907 | /* 125 -5 */ CWORD_CWORD_CWORD_CWORD, | ||
908 | /* 126 -4 */ CWORD_CWORD_CWORD_CWORD, | ||
909 | /* 127 -3 */ CWORD_CWORD_CWORD_CWORD, | ||
910 | /* 128 -2 */ CWORD_CWORD_CWORD_CWORD, | ||
911 | /* 129 -1 */ CWORD_CWORD_CWORD_CWORD, | ||
912 | /* 130 0 */ CWORD_CWORD_CWORD_CWORD, | ||
913 | /* 131 1 */ CWORD_CWORD_CWORD_CWORD, | ||
914 | /* 132 2 */ CWORD_CWORD_CWORD_CWORD, | ||
915 | /* 133 3 */ CWORD_CWORD_CWORD_CWORD, | ||
916 | /* 134 4 */ CWORD_CWORD_CWORD_CWORD, | ||
917 | /* 135 5 */ CWORD_CWORD_CWORD_CWORD, | ||
918 | /* 136 6 */ CWORD_CWORD_CWORD_CWORD, | ||
919 | /* 137 7 */ CWORD_CWORD_CWORD_CWORD, | ||
920 | /* 138 8 */ CWORD_CWORD_CWORD_CWORD, | ||
921 | /* 139 9 "\t" */ CSPCL_CWORD_CWORD_CWORD, | ||
922 | /* 140 10 "\n" */ CNL_CNL_CNL_CNL, | ||
923 | /* 141 11 */ CWORD_CWORD_CWORD_CWORD, | ||
924 | /* 142 12 */ CWORD_CWORD_CWORD_CWORD, | ||
925 | /* 143 13 */ CWORD_CWORD_CWORD_CWORD, | ||
926 | /* 144 14 */ CWORD_CWORD_CWORD_CWORD, | ||
927 | /* 145 15 */ CWORD_CWORD_CWORD_CWORD, | ||
928 | /* 146 16 */ CWORD_CWORD_CWORD_CWORD, | ||
929 | /* 147 17 */ CWORD_CWORD_CWORD_CWORD, | ||
930 | /* 148 18 */ CWORD_CWORD_CWORD_CWORD, | ||
931 | /* 149 19 */ CWORD_CWORD_CWORD_CWORD, | ||
932 | /* 150 20 */ CWORD_CWORD_CWORD_CWORD, | ||
933 | /* 151 21 */ CWORD_CWORD_CWORD_CWORD, | ||
934 | /* 152 22 */ CWORD_CWORD_CWORD_CWORD, | ||
935 | /* 153 23 */ CWORD_CWORD_CWORD_CWORD, | ||
936 | /* 154 24 */ CWORD_CWORD_CWORD_CWORD, | ||
937 | /* 155 25 */ CWORD_CWORD_CWORD_CWORD, | ||
938 | /* 156 26 */ CWORD_CWORD_CWORD_CWORD, | ||
939 | /* 157 27 */ CWORD_CWORD_CWORD_CWORD, | ||
940 | /* 158 28 */ CWORD_CWORD_CWORD_CWORD, | ||
941 | /* 159 29 */ CWORD_CWORD_CWORD_CWORD, | ||
942 | /* 160 30 */ CWORD_CWORD_CWORD_CWORD, | ||
943 | /* 161 31 */ CWORD_CWORD_CWORD_CWORD, | ||
944 | /* 162 32 " " */ CSPCL_CWORD_CWORD_CWORD, | ||
945 | /* 163 33 "!" */ CWORD_CCTL_CCTL_CWORD, | ||
946 | /* 164 34 """ */ CDQUOTE_CENDQUOTE_CWORD_CDQUOTE, | ||
947 | /* 165 35 "#" */ CWORD_CWORD_CWORD_CWORD, | ||
948 | /* 166 36 "$" */ CVAR_CVAR_CWORD_CVAR, | ||
949 | /* 167 37 "%" */ CWORD_CWORD_CWORD_CWORD, | ||
950 | /* 168 38 "&" */ CSPCL_CWORD_CWORD_CWORD, | ||
951 | /* 169 39 "'" */ CSQUOTE_CWORD_CENDQUOTE_CSQUOTE, | ||
952 | /* 170 40 "(" */ CSPCL_CWORD_CWORD_CLP, | ||
953 | /* 171 41 ")" */ CSPCL_CWORD_CWORD_CRP, | ||
954 | /* 172 42 "*" */ CWORD_CCTL_CCTL_CWORD, | ||
955 | /* 173 43 "+" */ CWORD_CWORD_CWORD_CWORD, | ||
956 | /* 174 44 "," */ CWORD_CWORD_CWORD_CWORD, | ||
957 | /* 175 45 "-" */ CWORD_CCTL_CCTL_CWORD, | ||
958 | /* 176 46 "." */ CWORD_CWORD_CWORD_CWORD, | ||
959 | /* 177 47 "/" */ CWORD_CCTL_CCTL_CWORD, | ||
960 | /* 178 48 "0" */ CWORD_CWORD_CWORD_CWORD, | ||
961 | /* 179 49 "1" */ CWORD_CWORD_CWORD_CWORD, | ||
962 | /* 180 50 "2" */ CWORD_CWORD_CWORD_CWORD, | ||
963 | /* 181 51 "3" */ CWORD_CWORD_CWORD_CWORD, | ||
964 | /* 182 52 "4" */ CWORD_CWORD_CWORD_CWORD, | ||
965 | /* 183 53 "5" */ CWORD_CWORD_CWORD_CWORD, | ||
966 | /* 184 54 "6" */ CWORD_CWORD_CWORD_CWORD, | ||
967 | /* 185 55 "7" */ CWORD_CWORD_CWORD_CWORD, | ||
968 | /* 186 56 "8" */ CWORD_CWORD_CWORD_CWORD, | ||
969 | /* 187 57 "9" */ CWORD_CWORD_CWORD_CWORD, | ||
970 | /* 188 58 ":" */ CWORD_CCTL_CCTL_CWORD, | ||
971 | /* 189 59 ";" */ CSPCL_CWORD_CWORD_CWORD, | ||
972 | /* 190 60 "<" */ CSPCL_CWORD_CWORD_CWORD, | ||
973 | /* 191 61 "=" */ CWORD_CCTL_CCTL_CWORD, | ||
974 | /* 192 62 ">" */ CSPCL_CWORD_CWORD_CWORD, | ||
975 | /* 193 63 "?" */ CWORD_CCTL_CCTL_CWORD, | ||
976 | /* 194 64 "@" */ CWORD_CWORD_CWORD_CWORD, | ||
977 | /* 195 65 "A" */ CWORD_CWORD_CWORD_CWORD, | ||
978 | /* 196 66 "B" */ CWORD_CWORD_CWORD_CWORD, | ||
979 | /* 197 67 "C" */ CWORD_CWORD_CWORD_CWORD, | ||
980 | /* 198 68 "D" */ CWORD_CWORD_CWORD_CWORD, | ||
981 | /* 199 69 "E" */ CWORD_CWORD_CWORD_CWORD, | ||
982 | /* 200 70 "F" */ CWORD_CWORD_CWORD_CWORD, | ||
983 | /* 201 71 "G" */ CWORD_CWORD_CWORD_CWORD, | ||
984 | /* 202 72 "H" */ CWORD_CWORD_CWORD_CWORD, | ||
985 | /* 203 73 "I" */ CWORD_CWORD_CWORD_CWORD, | ||
986 | /* 204 74 "J" */ CWORD_CWORD_CWORD_CWORD, | ||
987 | /* 205 75 "K" */ CWORD_CWORD_CWORD_CWORD, | ||
988 | /* 206 76 "L" */ CWORD_CWORD_CWORD_CWORD, | ||
989 | /* 207 77 "M" */ CWORD_CWORD_CWORD_CWORD, | ||
990 | /* 208 78 "N" */ CWORD_CWORD_CWORD_CWORD, | ||
991 | /* 209 79 "O" */ CWORD_CWORD_CWORD_CWORD, | ||
992 | /* 210 80 "P" */ CWORD_CWORD_CWORD_CWORD, | ||
993 | /* 211 81 "Q" */ CWORD_CWORD_CWORD_CWORD, | ||
994 | /* 212 82 "R" */ CWORD_CWORD_CWORD_CWORD, | ||
995 | /* 213 83 "S" */ CWORD_CWORD_CWORD_CWORD, | ||
996 | /* 214 84 "T" */ CWORD_CWORD_CWORD_CWORD, | ||
997 | /* 215 85 "U" */ CWORD_CWORD_CWORD_CWORD, | ||
998 | /* 216 86 "V" */ CWORD_CWORD_CWORD_CWORD, | ||
999 | /* 217 87 "W" */ CWORD_CWORD_CWORD_CWORD, | ||
1000 | /* 218 88 "X" */ CWORD_CWORD_CWORD_CWORD, | ||
1001 | /* 219 89 "Y" */ CWORD_CWORD_CWORD_CWORD, | ||
1002 | /* 220 90 "Z" */ CWORD_CWORD_CWORD_CWORD, | ||
1003 | /* 221 91 "[" */ CWORD_CCTL_CCTL_CWORD, | ||
1004 | /* 222 92 "\" */ CBACK_CBACK_CCTL_CBACK, | ||
1005 | /* 223 93 "]" */ CWORD_CCTL_CCTL_CWORD, | ||
1006 | /* 224 94 "^" */ CWORD_CWORD_CWORD_CWORD, | ||
1007 | /* 225 95 "_" */ CWORD_CWORD_CWORD_CWORD, | ||
1008 | /* 226 96 "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE, | ||
1009 | /* 227 97 "a" */ CWORD_CWORD_CWORD_CWORD, | ||
1010 | /* 228 98 "b" */ CWORD_CWORD_CWORD_CWORD, | ||
1011 | /* 229 99 "c" */ CWORD_CWORD_CWORD_CWORD, | ||
1012 | /* 230 100 "d" */ CWORD_CWORD_CWORD_CWORD, | ||
1013 | /* 231 101 "e" */ CWORD_CWORD_CWORD_CWORD, | ||
1014 | /* 232 102 "f" */ CWORD_CWORD_CWORD_CWORD, | ||
1015 | /* 233 103 "g" */ CWORD_CWORD_CWORD_CWORD, | ||
1016 | /* 234 104 "h" */ CWORD_CWORD_CWORD_CWORD, | ||
1017 | /* 235 105 "i" */ CWORD_CWORD_CWORD_CWORD, | ||
1018 | /* 236 106 "j" */ CWORD_CWORD_CWORD_CWORD, | ||
1019 | /* 237 107 "k" */ CWORD_CWORD_CWORD_CWORD, | ||
1020 | /* 238 108 "l" */ CWORD_CWORD_CWORD_CWORD, | ||
1021 | /* 239 109 "m" */ CWORD_CWORD_CWORD_CWORD, | ||
1022 | /* 240 110 "n" */ CWORD_CWORD_CWORD_CWORD, | ||
1023 | /* 241 111 "o" */ CWORD_CWORD_CWORD_CWORD, | ||
1024 | /* 242 112 "p" */ CWORD_CWORD_CWORD_CWORD, | ||
1025 | /* 243 113 "q" */ CWORD_CWORD_CWORD_CWORD, | ||
1026 | /* 244 114 "r" */ CWORD_CWORD_CWORD_CWORD, | ||
1027 | /* 245 115 "s" */ CWORD_CWORD_CWORD_CWORD, | ||
1028 | /* 246 116 "t" */ CWORD_CWORD_CWORD_CWORD, | ||
1029 | /* 247 117 "u" */ CWORD_CWORD_CWORD_CWORD, | ||
1030 | /* 248 118 "v" */ CWORD_CWORD_CWORD_CWORD, | ||
1031 | /* 249 119 "w" */ CWORD_CWORD_CWORD_CWORD, | ||
1032 | /* 250 120 "x" */ CWORD_CWORD_CWORD_CWORD, | ||
1033 | /* 251 121 "y" */ CWORD_CWORD_CWORD_CWORD, | ||
1034 | /* 252 122 "z" */ CWORD_CWORD_CWORD_CWORD, | ||
1035 | /* 253 123 "{" */ CWORD_CWORD_CWORD_CWORD, | ||
1036 | /* 254 124 "|" */ CSPCL_CWORD_CWORD_CWORD, | ||
1037 | /* 255 125 "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR, | ||
1038 | /* 256 126 "~" */ CWORD_CCTL_CCTL_CWORD, | ||
1039 | /* 257 127 */ CWORD_CWORD_CWORD_CWORD, | ||
1110 | }; | 1040 | }; |
1111 | 1041 | ||
1042 | #endif /* USE_SIT_FUNCTION */ | ||
1043 | |||
1044 | |||
1045 | /* first char is indicating which tokens mark the end of a list */ | ||
1046 | static const char *const tokname_array[] = { | ||
1047 | "\1end of file", | ||
1048 | "\0newline", | ||
1049 | "\0redirection", | ||
1050 | "\0word", | ||
1051 | "\0assignment", | ||
1052 | "\0;", | ||
1053 | "\0&", | ||
1054 | "\0&&", | ||
1055 | "\0||", | ||
1056 | "\0|", | ||
1057 | "\0(", | ||
1058 | "\1)", | ||
1059 | "\1;;", | ||
1060 | "\1`", | ||
1112 | #define KWDOFFSET 14 | 1061 | #define KWDOFFSET 14 |
1113 | 1062 | /* the following are keywords */ | |
1114 | static const char *const parsekwd[] = { | 1063 | "\0!", |
1115 | "!", | 1064 | "\0case", |
1116 | "case", | 1065 | "\1do", |
1117 | "do", | 1066 | "\1done", |
1118 | "done", | 1067 | "\1elif", |
1119 | "elif", | 1068 | "\1else", |
1120 | "else", | 1069 | "\1esac", |
1121 | "esac", | 1070 | "\1fi", |
1122 | "fi", | 1071 | "\0for", |
1123 | "for", | 1072 | "\0if", |
1124 | "if", | 1073 | "\0in", |
1125 | "in", | 1074 | "\1then", |
1126 | "then", | 1075 | "\0until", |
1127 | "until", | 1076 | "\0while", |
1128 | "while", | 1077 | "\0{", |
1129 | "{", | 1078 | "\1}", |
1130 | "}" | ||
1131 | }; | 1079 | }; |
1132 | 1080 | ||
1081 | static const char *tokname(int tok) | ||
1082 | { | ||
1083 | static char buf[16]; | ||
1084 | |||
1085 | if(tok>=TSEMI) | ||
1086 | buf[0] = '"'; | ||
1087 | sprintf(buf+(tok>=TSEMI), "%s%c", | ||
1088 | tokname_array[tok]+1, (tok>=TSEMI ? '"' : 0)); | ||
1089 | return buf; | ||
1090 | } | ||
1133 | 1091 | ||
1134 | static int plinno = 1; /* input line number */ | 1092 | static int plinno = 1; /* input line number */ |
1135 | 1093 | ||
@@ -1562,8 +1520,8 @@ __lookupalias(const char *name) { | |||
1562 | 1520 | ||
1563 | #ifdef ASH_MATH_SUPPORT | 1521 | #ifdef ASH_MATH_SUPPORT |
1564 | /* The generated file arith.c has been replaced with a custom hand | 1522 | /* The generated file arith.c has been replaced with a custom hand |
1565 | * written implementation written by Aaron Lehmann <aaronl@vitelus.com>. | 1523 | * written implementation written by Aaron Lehmann <aaronl@vitelus.com>. |
1566 | * This is now part of libbb, so that it can be used by all the shells | 1524 | * This is now part of libbb, so that it can be used by all the shells |
1567 | * in busybox. */ | 1525 | * in busybox. */ |
1568 | #define ARITH_NUM 257 | 1526 | #define ARITH_NUM 257 |
1569 | #define ARITH_LPAREN 258 | 1527 | #define ARITH_LPAREN 258 |
@@ -1744,7 +1702,7 @@ static const struct builtincmd builtincmds[] = { | |||
1744 | }; | 1702 | }; |
1745 | #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) ) | 1703 | #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) ) |
1746 | 1704 | ||
1747 | static const struct builtincmd *DOTCMD = &builtincmds[0]; | 1705 | #define DOTCMD &builtincmds[0] |
1748 | static struct builtincmd *BLTINCMD; | 1706 | static struct builtincmd *BLTINCMD; |
1749 | static struct builtincmd *EXECCMD; | 1707 | static struct builtincmd *EXECCMD; |
1750 | static struct builtincmd *EVALCMD; | 1708 | static struct builtincmd *EVALCMD; |
@@ -2165,7 +2123,7 @@ exverror(int cond, const char *msg, va_list ap) | |||
2165 | } | 2123 | } |
2166 | 2124 | ||
2167 | 2125 | ||
2168 | static void | 2126 | static void |
2169 | error(const char *msg, ...) | 2127 | error(const char *msg, ...) |
2170 | { | 2128 | { |
2171 | va_list ap; | 2129 | va_list ap; |
@@ -3690,7 +3648,7 @@ padvance(const char **path, const char *name) | |||
3690 | static int | 3648 | static int |
3691 | pstrcmp(const void *a, const void *b) | 3649 | pstrcmp(const void *a, const void *b) |
3692 | { | 3650 | { |
3693 | return strcmp((const char *) a, *(const char *const *) b); | 3651 | return strcmp((const char *) a, (*(const char *const *) b) + 1); |
3694 | } | 3652 | } |
3695 | 3653 | ||
3696 | /* | 3654 | /* |
@@ -3700,8 +3658,9 @@ pstrcmp(const void *a, const void *b) | |||
3700 | static const char *const * | 3658 | static const char *const * |
3701 | findkwd(const char *s) | 3659 | findkwd(const char *s) |
3702 | { | 3660 | { |
3703 | return bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *), | 3661 | return bsearch(s, tokname_array + KWDOFFSET, |
3704 | sizeof(const char *), pstrcmp); | 3662 | (sizeof(tokname_array)/sizeof(const char *)) - KWDOFFSET, |
3663 | sizeof(const char *), pstrcmp); | ||
3705 | } | 3664 | } |
3706 | 3665 | ||
3707 | 3666 | ||
@@ -4228,7 +4187,7 @@ delete_cmd_entry() { | |||
4228 | 4187 | ||
4229 | 4188 | ||
4230 | 4189 | ||
4231 | static const short nodesize[26] = { | 4190 | static const unsigned char nodesize[26] = { |
4232 | ALIGN(sizeof (struct nbinary)), | 4191 | ALIGN(sizeof (struct nbinary)), |
4233 | ALIGN(sizeof (struct ncmd)), | 4192 | ALIGN(sizeof (struct ncmd)), |
4234 | ALIGN(sizeof (struct npipe)), | 4193 | ALIGN(sizeof (struct npipe)), |
@@ -4412,7 +4371,7 @@ static char *exptilde (char *, int); | |||
4412 | static void expbackq (union node *, int, int); | 4371 | static void expbackq (union node *, int, int); |
4413 | static int subevalvar (char *, char *, int, int, int, int, int); | 4372 | static int subevalvar (char *, char *, int, int, int, int, int); |
4414 | static int varisset (char *, int); | 4373 | static int varisset (char *, int); |
4415 | static void strtodest (const char *, const char *, int); | 4374 | static void strtodest (const char *, int, int); |
4416 | static void varvalue (char *, int, int); | 4375 | static void varvalue (char *, int, int); |
4417 | static void recordregion (int, int, int); | 4376 | static void recordregion (int, int, int); |
4418 | static void removerecordregions (int); | 4377 | static void removerecordregions (int); |
@@ -4916,7 +4875,7 @@ expbackq(cmd, quoted, flag) | |||
4916 | struct nodelist *volatile saveargbackq; | 4875 | struct nodelist *volatile saveargbackq; |
4917 | char lastc; | 4876 | char lastc; |
4918 | int startloc = dest - stackblock(); | 4877 | int startloc = dest - stackblock(); |
4919 | char const *syntax = quoted? DQSYNTAX : BASESYNTAX; | 4878 | int syntax = quoted ? DQSYNTAX : BASESYNTAX; |
4920 | volatile int saveherefd; | 4879 | volatile int saveherefd; |
4921 | int quotes = flag & (EXP_FULL | EXP_CASE); | 4880 | int quotes = flag & (EXP_FULL | EXP_CASE); |
4922 | struct jmploc jmploc; | 4881 | struct jmploc jmploc; |
@@ -4973,7 +4932,7 @@ err1: | |||
4973 | } | 4932 | } |
4974 | lastc = *p++; | 4933 | lastc = *p++; |
4975 | if (lastc != '\0') { | 4934 | if (lastc != '\0') { |
4976 | if (quotes && syntax[(int)lastc] == CCTL) | 4935 | if (quotes && SIT(lastc, syntax) == CCTL) |
4977 | STPUTC(CTLESC, dest); | 4936 | STPUTC(CTLESC, dest); |
4978 | STPUTC(lastc, dest); | 4937 | STPUTC(lastc, dest); |
4979 | } | 4938 | } |
@@ -5174,13 +5133,10 @@ varisset(name, nulok) | |||
5174 | */ | 5133 | */ |
5175 | 5134 | ||
5176 | static void | 5135 | static void |
5177 | strtodest(p, syntax, quotes) | 5136 | strtodest(const char *p, int syntax, int quotes) |
5178 | const char *p; | ||
5179 | const char *syntax; | ||
5180 | int quotes; | ||
5181 | { | 5137 | { |
5182 | while (*p) { | 5138 | while (*p) { |
5183 | if (quotes && syntax[(int) *p] == CCTL) | 5139 | if (quotes && SIT(*p,syntax) == CCTL) |
5184 | STPUTC(CTLESC, expdest); | 5140 | STPUTC(CTLESC, expdest); |
5185 | STPUTC(*p++, expdest); | 5141 | STPUTC(*p++, expdest); |
5186 | } | 5142 | } |
@@ -5191,10 +5147,7 @@ strtodest(p, syntax, quotes) | |||
5191 | */ | 5147 | */ |
5192 | 5148 | ||
5193 | static void | 5149 | static void |
5194 | varvalue(name, quoted, flags) | 5150 | varvalue(char *name, int quoted, int flags) |
5195 | char *name; | ||
5196 | int quoted; | ||
5197 | int flags; | ||
5198 | { | 5151 | { |
5199 | int num; | 5152 | int num; |
5200 | char *p; | 5153 | char *p; |
@@ -5202,7 +5155,7 @@ varvalue(name, quoted, flags) | |||
5202 | int sep; | 5155 | int sep; |
5203 | int sepq = 0; | 5156 | int sepq = 0; |
5204 | char **ap; | 5157 | char **ap; |
5205 | char const *syntax; | 5158 | int syntax; |
5206 | int allow_split = flags & EXP_FULL; | 5159 | int allow_split = flags & EXP_FULL; |
5207 | int quotes = flags & (EXP_FULL | EXP_CASE); | 5160 | int quotes = flags & (EXP_FULL | EXP_CASE); |
5208 | 5161 | ||
@@ -5237,7 +5190,7 @@ numvar: | |||
5237 | case '*': | 5190 | case '*': |
5238 | sep = ifsset() ? ifsval()[0] : ' '; | 5191 | sep = ifsset() ? ifsval()[0] : ' '; |
5239 | if (quotes) { | 5192 | if (quotes) { |
5240 | sepq = syntax[(int) sep] == CCTL; | 5193 | sepq = SIT(sep,syntax) == CCTL; |
5241 | } | 5194 | } |
5242 | param: | 5195 | param: |
5243 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { | 5196 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { |
@@ -5572,7 +5525,7 @@ expmeta(enddir, name) | |||
5572 | break; | 5525 | break; |
5573 | } | 5526 | } |
5574 | } | 5527 | } |
5575 | } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) { | 5528 | } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) { |
5576 | metaflag = 1; | 5529 | metaflag = 1; |
5577 | } else if (*p == '\0') | 5530 | } else if (*p == '\0') |
5578 | break; | 5531 | break; |
@@ -7341,10 +7294,219 @@ cmdputs(const char *s) | |||
7341 | cmdnextc = q; | 7294 | cmdnextc = q; |
7342 | } | 7295 | } |
7343 | 7296 | ||
7297 | //#define CMDTXT_TABLE | ||
7298 | #ifdef CMDTXT_TABLE | ||
7299 | /* | ||
7300 | * To collect a lot of redundant code in cmdtxt() case statements, we | ||
7301 | * implement a mini language here. Each type of node struct has an | ||
7302 | * associated instruction sequence that operates on its members via | ||
7303 | * their offsets. The instruction are pack in unsigned chars with | ||
7304 | * format IIDDDDDE where the bits are | ||
7305 | * I : part of the instruction opcode, which are | ||
7306 | * 00 : member is a pointer to another node -- process it recursively | ||
7307 | * 40 : member is a pointer to a char string -- output it | ||
7308 | * 80 : output the string whose index is stored in the data field | ||
7309 | * CC : flag signaling that this case needs external processing | ||
7310 | * D : data - either the (shifted) index of a fixed string to output or | ||
7311 | * the actual offset of the member to operate on in the struct | ||
7312 | * (since we assume bit 0 is set, the offset is not shifted) | ||
7313 | * E : flag signaling end of instruction sequence | ||
7314 | * | ||
7315 | * WARNING: In order to handle larger offsets for 64bit archs, this code | ||
7316 | * assumes that no offset can be an odd number and stores the | ||
7317 | * end-of-instructions flag in bit 0. | ||
7318 | */ | ||
7319 | |||
7320 | #define CMDTXT_NOMORE 0x01 /* NOTE: no offset should be odd */ | ||
7321 | #define CMDTXT_CHARPTR 0x40 | ||
7322 | #define CMDTXT_STRING 0x80 | ||
7323 | #define CMDTXT_SPECIAL 0xC0 | ||
7324 | #define CMDTXT_OFFSETMASK 0x3E | ||
7325 | |||
7326 | static const char * const cmdtxt_strings[] = { | ||
7327 | /* 0 1 2 3 4 5 6 7 */ | ||
7328 | "; ", "(", ")", " && ", " || ", "if ", "; then ", "...", | ||
7329 | /* 8 9 10 11 12 13 */ | ||
7330 | "while ", "; do ", "; done", "until ", "for ", " in ...", | ||
7331 | /* 14 15 16 17 */ | ||
7332 | "case ", "???", "() ...", "<<..." | ||
7333 | }; | ||
7334 | |||
7335 | static const char * const redir_strings[] = { | ||
7336 | ">", "<", "<>", ">>", ">|", ">&", "<&" | ||
7337 | }; | ||
7338 | |||
7339 | static const unsigned char cmdtxt_ops[] = { | ||
7340 | #define CMDTXT_NSEMI 0 | ||
7341 | offsetof(union node, nbinary.ch1), | ||
7342 | 0|CMDTXT_STRING, | ||
7343 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | ||
7344 | #define CMDTXT_NCMD (CMDTXT_NSEMI + 3) | ||
7345 | #define CMDTXT_NPIPE (CMDTXT_NCMD) | ||
7346 | #define CMDTXT_NCASE (CMDTXT_NCMD) | ||
7347 | #define CMDTXT_NTO (CMDTXT_NCMD) | ||
7348 | #define CMDTXT_NFROM (CMDTXT_NCMD) | ||
7349 | #define CMDTXT_NFROMTO (CMDTXT_NCMD) | ||
7350 | #define CMDTXT_NAPPEND (CMDTXT_NCMD) | ||
7351 | #define CMDTXT_NTOOV (CMDTXT_NCMD) | ||
7352 | #define CMDTXT_NTOFD (CMDTXT_NCMD) | ||
7353 | #define CMDTXT_NFROMFD (CMDTXT_NCMD) | ||
7354 | CMDTXT_SPECIAL, | ||
7355 | #define CMDTXT_NREDIR (CMDTXT_NPIPE + 1) | ||
7356 | #define CMDTXT_NBACKGND (CMDTXT_NREDIR) | ||
7357 | offsetof(union node, nredir.n)|CMDTXT_NOMORE, | ||
7358 | #define CMDTXT_NSUBSHELL (CMDTXT_NBACKGND + 1) | ||
7359 | (1*2)|CMDTXT_STRING, | ||
7360 | offsetof(union node, nredir.n), | ||
7361 | (2*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7362 | #define CMDTXT_NAND (CMDTXT_NSUBSHELL + 3) | ||
7363 | offsetof(union node, nbinary.ch1), | ||
7364 | (3*2)|CMDTXT_STRING, | ||
7365 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | ||
7366 | #define CMDTXT_NOR (CMDTXT_NAND + 3) | ||
7367 | offsetof(union node, nbinary.ch1), | ||
7368 | (4*2)|CMDTXT_STRING, | ||
7369 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | ||
7370 | #define CMDTXT_NIF (CMDTXT_NOR + 3) | ||
7371 | (5*2)|CMDTXT_STRING, | ||
7372 | offsetof(union node, nif.test), | ||
7373 | (6*2)|CMDTXT_STRING, | ||
7374 | offsetof(union node, nif.ifpart), | ||
7375 | (7*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7376 | #define CMDTXT_NWHILE (CMDTXT_NIF + 5) | ||
7377 | (8*2)|CMDTXT_STRING, | ||
7378 | offsetof(union node, nbinary.ch1), | ||
7379 | (9*2)|CMDTXT_STRING, | ||
7380 | offsetof(union node, nbinary.ch2), | ||
7381 | (10*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7382 | #define CMDTXT_NUNTIL (CMDTXT_NWHILE + 5) | ||
7383 | (11*2)|CMDTXT_STRING, | ||
7384 | offsetof(union node, nbinary.ch1), | ||
7385 | (9*2)|CMDTXT_STRING, | ||
7386 | offsetof(union node, nbinary.ch2), | ||
7387 | (10*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7388 | #define CMDTXT_NFOR (CMDTXT_NUNTIL + 5) | ||
7389 | (12*2)|CMDTXT_STRING, | ||
7390 | offsetof(union node, nfor.var)|CMDTXT_CHARPTR, | ||
7391 | (13*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7392 | #define CMDTXT_NCLIST (CMDTXT_NFOR + 3) /* TODO: IS THIS CORRECT??? */ | ||
7393 | #define CMDTXT_NNOT (CMDTXT_NCLIST) /* TODO: IS THIS CORRECT??? */ | ||
7394 | (15*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7395 | #define CMDTXT_NDEFUN (CMDTXT_NCLIST + 1) | ||
7396 | offsetof(union node, narg.text)|CMDTXT_CHARPTR, | ||
7397 | (16*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7398 | #define CMDTXT_NARG (CMDTXT_NDEFUN + 2) | ||
7399 | offsetof(union node, narg.text)|CMDTXT_CHARPTR|CMDTXT_NOMORE, | ||
7400 | #define CMDTXT_NHERE (CMDTXT_NARG + 1) | ||
7401 | #define CMDTXT_NXHERE (CMDTXT_NHERE) | ||
7402 | (17*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7403 | }; | ||
7404 | |||
7405 | #if CMDTXT_NXHERE != 36 | ||
7406 | #error CMDTXT_NXHERE | ||
7407 | #endif | ||
7408 | |||
7409 | static const unsigned char cmdtxt_ops_index[26] = { | ||
7410 | CMDTXT_NSEMI, | ||
7411 | CMDTXT_NCMD, | ||
7412 | CMDTXT_NPIPE, | ||
7413 | CMDTXT_NREDIR, | ||
7414 | CMDTXT_NBACKGND, | ||
7415 | CMDTXT_NSUBSHELL, | ||
7416 | CMDTXT_NAND, | ||
7417 | CMDTXT_NOR, | ||
7418 | CMDTXT_NIF, | ||
7419 | CMDTXT_NWHILE, | ||
7420 | CMDTXT_NUNTIL, | ||
7421 | CMDTXT_NFOR, | ||
7422 | CMDTXT_NCASE, | ||
7423 | CMDTXT_NCLIST, | ||
7424 | CMDTXT_NDEFUN, | ||
7425 | CMDTXT_NARG, | ||
7426 | CMDTXT_NTO, | ||
7427 | CMDTXT_NFROM, | ||
7428 | CMDTXT_NFROMTO, | ||
7429 | CMDTXT_NAPPEND, | ||
7430 | CMDTXT_NTOOV, | ||
7431 | CMDTXT_NTOFD, | ||
7432 | CMDTXT_NFROMFD, | ||
7433 | CMDTXT_NHERE, | ||
7434 | CMDTXT_NXHERE, | ||
7435 | CMDTXT_NNOT, | ||
7436 | }; | ||
7344 | 7437 | ||
7345 | static void | 7438 | static void |
7346 | cmdtxt(const union node *n) | 7439 | cmdtxt(const union node *n) |
7347 | { | 7440 | { |
7441 | const char *p; | ||
7442 | |||
7443 | if (n == NULL) | ||
7444 | return; | ||
7445 | |||
7446 | p = cmdtxt_ops + (int) cmdtxt_ops_index[n->type]; | ||
7447 | if ((*p & CMDTXT_SPECIAL) != CMDTXT_SPECIAL) { /* normal case */ | ||
7448 | do { | ||
7449 | if (*p & CMDTXT_STRING) { /* output fixed string */ | ||
7450 | cmdputs(cmdtxt_strings[((int)(*p & CMDTXT_OFFSETMASK) >> 1)]); | ||
7451 | } else if (*p & CMDTXT_CHARPTR) { /* output dynamic string */ | ||
7452 | cmdputs(((const char *) n) + ((int)(*p & CMDTXT_OFFSETMASK))); | ||
7453 | } else { /* output field */ | ||
7454 | cmdtxt((const union node *) | ||
7455 | (((const char *) n) + ((int)(*p & CMDTXT_OFFSETMASK)))); | ||
7456 | } | ||
7457 | } while (!(*p++ & CMDTXT_NOMORE)); | ||
7458 | } else if (n->type == NCMD) { | ||
7459 | union node *np; | ||
7460 | for (np = n->ncmd.args ; np ; np = np->narg.next) { | ||
7461 | cmdtxt(np); | ||
7462 | if (np->narg.next) | ||
7463 | cmdputs(spcstr); | ||
7464 | } | ||
7465 | for (np = n->ncmd.redirect ; np ; np = np->nfile.next) { | ||
7466 | cmdputs(spcstr); | ||
7467 | cmdtxt(np); | ||
7468 | } | ||
7469 | } else if (n->type == NPIPE) { | ||
7470 | struct nodelist *lp; | ||
7471 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { | ||
7472 | cmdtxt(lp->n); | ||
7473 | if (lp->next) | ||
7474 | cmdputs(" | "); | ||
7475 | } | ||
7476 | } else if (n->type == NCASE) { | ||
7477 | cmdputs(cmdtxt_strings[14]); | ||
7478 | cmdputs(n->ncase.expr->narg.text); | ||
7479 | cmdputs(cmdtxt_strings[13]); | ||
7480 | } else { | ||
7481 | #if (NTO != 16) || (NFROM != 17) || (NFROMTO != 18) || (NAPPEND != 19) || (NTOOV != 20) || (NTOFD != 21) || (NFROMFD != 22) | ||
7482 | #error Assumption violated regarding range and ordering of NTO ... NFROMFD! | ||
7483 | #endif | ||
7484 | char s[2]; | ||
7485 | |||
7486 | #ifdef DEBUG | ||
7487 | assert((n->type >= NTO) && (n->type <= NFROMFD)); | ||
7488 | #endif | ||
7489 | |||
7490 | p = redir_strings[n->type - NTO]; | ||
7491 | if (n->nfile.fd != ('>' == *p)) { | ||
7492 | s[0] = n->nfile.fd + '0'; | ||
7493 | s[1] = '\0'; | ||
7494 | cmdputs(s); | ||
7495 | } | ||
7496 | cmdputs(p); | ||
7497 | if (n->type >= NTOFD) { | ||
7498 | s[0] = n->ndup.dupfd + '0'; | ||
7499 | s[1] = '\0'; | ||
7500 | cmdputs(s); | ||
7501 | } else { | ||
7502 | cmdtxt(n->nfile.fname); | ||
7503 | } | ||
7504 | } | ||
7505 | } | ||
7506 | #else /* CMDTXT_TABLE */ | ||
7507 | static void | ||
7508 | cmdtxt(const union node *n) | ||
7509 | { | ||
7348 | union node *np; | 7510 | union node *np; |
7349 | struct nodelist *lp; | 7511 | struct nodelist *lp; |
7350 | const char *p; | 7512 | const char *p; |
@@ -7469,7 +7631,7 @@ redir: | |||
7469 | break; | 7631 | break; |
7470 | } | 7632 | } |
7471 | } | 7633 | } |
7472 | 7634 | #endif | |
7473 | 7635 | ||
7474 | static char * | 7636 | static char * |
7475 | commandtext(const union node *n) | 7637 | commandtext(const union node *n) |
@@ -7602,27 +7764,17 @@ ash_main(argc, argv) | |||
7602 | * exception EXSHELLPROC to clean up before executing | 7764 | * exception EXSHELLPROC to clean up before executing |
7603 | * the shell procedure. | 7765 | * the shell procedure. |
7604 | */ | 7766 | */ |
7605 | switch (exception) { | 7767 | if (exception == EXSHELLPROC) { |
7606 | case EXSHELLPROC: | ||
7607 | rootpid = getpid(); | 7768 | rootpid = getpid(); |
7608 | rootshell = 1; | 7769 | rootshell = 1; |
7609 | minusc = NULL; | 7770 | minusc = NULL; |
7610 | state = 3; | 7771 | state = 3; |
7611 | break; | 7772 | } else { |
7612 | 7773 | if (exception == EXEXEC) { | |
7613 | case EXEXEC: | 7774 | exitstatus = exerrno; |
7614 | exitstatus = exerrno; | 7775 | } else if (exception == EXERROR) { |
7615 | break; | 7776 | exitstatus = 2; |
7616 | 7777 | } | |
7617 | case EXERROR: | ||
7618 | exitstatus = 2; | ||
7619 | break; | ||
7620 | |||
7621 | default: | ||
7622 | break; | ||
7623 | } | ||
7624 | |||
7625 | if (exception != EXSHELLPROC) { | ||
7626 | if (state == 0 || iflag == 0 || ! rootshell) | 7778 | if (state == 0 || iflag == 0 || ! rootshell) |
7627 | exitshell(exitstatus); | 7779 | exitshell(exitstatus); |
7628 | } | 7780 | } |
@@ -7673,14 +7825,14 @@ state2: | |||
7673 | state3: | 7825 | state3: |
7674 | state = 4; | 7826 | state = 4; |
7675 | if (sflag == 0 || minusc) { | 7827 | if (sflag == 0 || minusc) { |
7676 | static int sigs[] = { | 7828 | static const char sigs[] = { |
7677 | SIGINT, SIGQUIT, SIGHUP, | 7829 | SIGINT, SIGQUIT, SIGHUP, |
7678 | #ifdef SIGTSTP | 7830 | #ifdef SIGTSTP |
7679 | SIGTSTP, | 7831 | SIGTSTP, |
7680 | #endif | 7832 | #endif |
7681 | SIGPIPE | 7833 | SIGPIPE |
7682 | }; | 7834 | }; |
7683 | #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0])) | 7835 | #define SIGSSIZE ((sizeof(sigs)/sizeof(sigs[0])) - 1) /* trailing nul */ |
7684 | int i; | 7836 | int i; |
7685 | 7837 | ||
7686 | for (i = 0; i < SIGSSIZE; i++) | 7838 | for (i = 0; i < SIGSSIZE; i++) |
@@ -7764,8 +7916,8 @@ read_profile(name) | |||
7764 | const char *name; | 7916 | const char *name; |
7765 | { | 7917 | { |
7766 | int fd; | 7918 | int fd; |
7767 | int xflag_set = 0; | 7919 | int xflag_save; |
7768 | int vflag_set = 0; | 7920 | int vflag_save; |
7769 | 7921 | ||
7770 | INTOFF; | 7922 | INTOFF; |
7771 | if ((fd = open(name, O_RDONLY)) >= 0) | 7923 | if ((fd = open(name, O_RDONLY)) >= 0) |
@@ -7774,19 +7926,15 @@ read_profile(name) | |||
7774 | if (fd < 0) | 7926 | if (fd < 0) |
7775 | return; | 7927 | return; |
7776 | /* -q turns off -x and -v just when executing init files */ | 7928 | /* -q turns off -x and -v just when executing init files */ |
7929 | /* Note: Might do a little redundant work, but reduces code size. */ | ||
7930 | xflag_save = xflag; | ||
7931 | vflag_save = vflag; | ||
7777 | if (qflag) { | 7932 | if (qflag) { |
7778 | if (xflag) | 7933 | vflag = xflag = 0; |
7779 | xflag = 0, xflag_set = 1; | ||
7780 | if (vflag) | ||
7781 | vflag = 0, vflag_set = 1; | ||
7782 | } | 7934 | } |
7783 | cmdloop(0); | 7935 | cmdloop(0); |
7784 | if (qflag) { | 7936 | xflag = xflag_save; |
7785 | if (xflag_set) | 7937 | vflag = vflag_save; |
7786 | xflag = 1; | ||
7787 | if (vflag_set) | ||
7788 | vflag = 1; | ||
7789 | } | ||
7790 | popfile(); | 7938 | popfile(); |
7791 | } | 7939 | } |
7792 | 7940 | ||
@@ -8089,11 +8237,6 @@ ungrabstackstr(char *s, char *p) | |||
8089 | 8237 | ||
8090 | #undef rflag | 8238 | #undef rflag |
8091 | 8239 | ||
8092 | //#ifdef __GLIBC__ | ||
8093 | static mode_t getmode(const void *, mode_t); | ||
8094 | static void *setmode(const char *); | ||
8095 | //#endif | ||
8096 | |||
8097 | #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1 | 8240 | #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1 |
8098 | typedef long rlim_t; | 8241 | typedef long rlim_t; |
8099 | #endif | 8242 | #endif |
@@ -8108,9 +8251,7 @@ typedef long rlim_t; | |||
8108 | */ | 8251 | */ |
8109 | 8252 | ||
8110 | static int | 8253 | static int |
8111 | readcmd(argc, argv) | 8254 | readcmd(int argc, char **argv) |
8112 | int argc; | ||
8113 | char **argv; | ||
8114 | { | 8255 | { |
8115 | char **ap; | 8256 | char **ap; |
8116 | int backslash; | 8257 | int backslash; |
@@ -8132,7 +8273,7 @@ readcmd(argc, argv) | |||
8132 | rflag = 1; | 8273 | rflag = 1; |
8133 | } | 8274 | } |
8134 | if (prompt && isatty(0)) { | 8275 | if (prompt && isatty(0)) { |
8135 | putprompt(prompt); | 8276 | out2str(prompt); /* read without cmdedit */ |
8136 | flushall(); | 8277 | flushall(); |
8137 | } | 8278 | } |
8138 | if (*(ap = argptr) == NULL) | 8279 | if (*(ap = argptr) == NULL) |
@@ -8199,8 +8340,16 @@ umaskcmd(argc, argv) | |||
8199 | int argc; | 8340 | int argc; |
8200 | char **argv; | 8341 | char **argv; |
8201 | { | 8342 | { |
8343 | static const char permuser[3] = "ugo"; | ||
8344 | static const char permmode[3] = "rwx"; | ||
8345 | static const short int permmask[] = { | ||
8346 | S_IRUSR, S_IWUSR, S_IXUSR, | ||
8347 | S_IRGRP, S_IWGRP, S_IXGRP, | ||
8348 | S_IROTH, S_IWOTH, S_IXOTH | ||
8349 | }; | ||
8350 | |||
8202 | char *ap; | 8351 | char *ap; |
8203 | int mask; | 8352 | mode_t mask; |
8204 | int i; | 8353 | int i; |
8205 | int symbolic_mode = 0; | 8354 | int symbolic_mode = 0; |
8206 | 8355 | ||
@@ -8215,36 +8364,21 @@ umaskcmd(argc, argv) | |||
8215 | 8364 | ||
8216 | if ((ap = *argptr) == NULL) { | 8365 | if ((ap = *argptr) == NULL) { |
8217 | if (symbolic_mode) { | 8366 | if (symbolic_mode) { |
8218 | char u[4], g[4], o[4]; | 8367 | char buf[18]; |
8219 | 8368 | char *p = buf; | |
8220 | i = 0; | 8369 | for (i=0 ; i<3 ; i++) { |
8221 | if ((mask & S_IRUSR) == 0) | 8370 | int j; |
8222 | u[i++] = 'r'; | 8371 | *p++ = permuser[i]; |
8223 | if ((mask & S_IWUSR) == 0) | 8372 | *p++ = '='; |
8224 | u[i++] = 'w'; | 8373 | for (j=0 ; j<3 ; j++) { |
8225 | if ((mask & S_IXUSR) == 0) | 8374 | if ((mask & permmask[3*i+j]) == 0) { |
8226 | u[i++] = 'x'; | 8375 | *p++ = permmode[j]; |
8227 | u[i] = '\0'; | 8376 | } |
8228 | 8377 | } | |
8229 | i = 0; | 8378 | *p++ = ','; |
8230 | if ((mask & S_IRGRP) == 0) | 8379 | } |
8231 | g[i++] = 'r'; | 8380 | *--p = 0; |
8232 | if ((mask & S_IWGRP) == 0) | 8381 | puts(buf); |
8233 | g[i++] = 'w'; | ||
8234 | if ((mask & S_IXGRP) == 0) | ||
8235 | g[i++] = 'x'; | ||
8236 | g[i] = '\0'; | ||
8237 | |||
8238 | i = 0; | ||
8239 | if ((mask & S_IROTH) == 0) | ||
8240 | o[i++] = 'r'; | ||
8241 | if ((mask & S_IWOTH) == 0) | ||
8242 | o[i++] = 'w'; | ||
8243 | if ((mask & S_IXOTH) == 0) | ||
8244 | o[i++] = 'x'; | ||
8245 | o[i] = '\0'; | ||
8246 | |||
8247 | printf("u=%s,g=%s,o=%s\n", u, g, o); | ||
8248 | } else { | 8382 | } else { |
8249 | printf("%.4o\n", mask); | 8383 | printf("%.4o\n", mask); |
8250 | } | 8384 | } |
@@ -8258,17 +8392,10 @@ umaskcmd(argc, argv) | |||
8258 | } while (*++ap != '\0'); | 8392 | } while (*++ap != '\0'); |
8259 | umask(mask); | 8393 | umask(mask); |
8260 | } else { | 8394 | } else { |
8261 | void *set; | 8395 | mask = ~mask & 0777; |
8262 | 8396 | if (parse_mode(ap, &mask) == FALSE) { | |
8263 | INTOFF; | ||
8264 | if ((set = setmode(ap)) != 0) { | ||
8265 | mask = getmode(set, ~mask & 0777); | ||
8266 | ckfree(set); | ||
8267 | } | ||
8268 | INTON; | ||
8269 | if (!set) | ||
8270 | error("Illegal mode: %s", ap); | 8397 | error("Illegal mode: %s", ap); |
8271 | 8398 | } | |
8272 | umask(~mask & 0777); | 8399 | umask(~mask & 0777); |
8273 | } | 8400 | } |
8274 | } | 8401 | } |
@@ -8287,46 +8414,45 @@ umaskcmd(argc, argv) | |||
8287 | 8414 | ||
8288 | struct limits { | 8415 | struct limits { |
8289 | const char *name; | 8416 | const char *name; |
8290 | int cmd; | 8417 | short cmd; |
8291 | int factor; /* multiply by to get rlim_{cur,max} values */ | 8418 | short factor; /* multiply by to get rlim_{cur,max} values */ |
8292 | char option; | ||
8293 | }; | 8419 | }; |
8294 | 8420 | ||
8295 | static const struct limits limits[] = { | 8421 | static const struct limits limits[] = { |
8296 | #ifdef RLIMIT_CPU | 8422 | #ifdef RLIMIT_CPU |
8297 | { "time(seconds)", RLIMIT_CPU, 1, 't' }, | 8423 | { "time(seconds)", RLIMIT_CPU, 1 }, |
8298 | #endif | 8424 | #endif |
8299 | #ifdef RLIMIT_FSIZE | 8425 | #ifdef RLIMIT_FSIZE |
8300 | { "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, | 8426 | { "file(blocks)", RLIMIT_FSIZE, 512 }, |
8301 | #endif | 8427 | #endif |
8302 | #ifdef RLIMIT_DATA | 8428 | #ifdef RLIMIT_DATA |
8303 | { "data(kbytes)", RLIMIT_DATA, 1024, 'd' }, | 8429 | { "data(kbytes)", RLIMIT_DATA, 1024 }, |
8304 | #endif | 8430 | #endif |
8305 | #ifdef RLIMIT_STACK | 8431 | #ifdef RLIMIT_STACK |
8306 | { "stack(kbytes)", RLIMIT_STACK, 1024, 's' }, | 8432 | { "stack(kbytes)", RLIMIT_STACK, 1024 }, |
8307 | #endif | 8433 | #endif |
8308 | #ifdef RLIMIT_CORE | 8434 | #ifdef RLIMIT_CORE |
8309 | { "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, | 8435 | { "coredump(blocks)", RLIMIT_CORE, 512 }, |
8310 | #endif | 8436 | #endif |
8311 | #ifdef RLIMIT_RSS | 8437 | #ifdef RLIMIT_RSS |
8312 | { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' }, | 8438 | { "memory(kbytes)", RLIMIT_RSS, 1024 }, |
8313 | #endif | 8439 | #endif |
8314 | #ifdef RLIMIT_MEMLOCK | 8440 | #ifdef RLIMIT_MEMLOCK |
8315 | { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' }, | 8441 | { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024 }, |
8316 | #endif | 8442 | #endif |
8317 | #ifdef RLIMIT_NPROC | 8443 | #ifdef RLIMIT_NPROC |
8318 | { "process(processes)", RLIMIT_NPROC, 1, 'p' }, | 8444 | { "process(processes)", RLIMIT_NPROC, 1 }, |
8319 | #endif | 8445 | #endif |
8320 | #ifdef RLIMIT_NOFILE | 8446 | #ifdef RLIMIT_NOFILE |
8321 | { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, | 8447 | { "nofiles(descriptors)", RLIMIT_NOFILE, 1 }, |
8322 | #endif | 8448 | #endif |
8323 | #ifdef RLIMIT_VMEM | 8449 | #ifdef RLIMIT_VMEM |
8324 | { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' }, | 8450 | { "vmemory(kbytes)", RLIMIT_VMEM, 1024 }, |
8325 | #endif | 8451 | #endif |
8326 | #ifdef RLIMIT_SWAP | 8452 | #ifdef RLIMIT_SWAP |
8327 | { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' }, | 8453 | { "swap(kbytes)", RLIMIT_SWAP, 1024 }, |
8328 | #endif | 8454 | #endif |
8329 | { (char *) 0, 0, 0, '\0' } | 8455 | { NULL, 0, 0 } |
8330 | }; | 8456 | }; |
8331 | 8457 | ||
8332 | static int | 8458 | static int |
@@ -8334,6 +8460,7 @@ ulimitcmd(argc, argv) | |||
8334 | int argc; | 8460 | int argc; |
8335 | char **argv; | 8461 | char **argv; |
8336 | { | 8462 | { |
8463 | static const char unlimited_string[] = "unlimited"; | ||
8337 | int c; | 8464 | int c; |
8338 | rlim_t val = 0; | 8465 | rlim_t val = 0; |
8339 | enum { SOFT = 0x1, HARD = 0x2 } | 8466 | enum { SOFT = 0x1, HARD = 0x2 } |
@@ -8344,25 +8471,59 @@ ulimitcmd(argc, argv) | |||
8344 | struct rlimit limit; | 8471 | struct rlimit limit; |
8345 | 8472 | ||
8346 | what = 'f'; | 8473 | what = 'f'; |
8347 | while ((optc = nextopt("HSatfdsmcnpl")) != '\0') | 8474 | |
8348 | switch (optc) { | 8475 | while ((optc = nextopt("HSa" |
8349 | case 'H': | 8476 | #ifdef RLIMIT_CPU |
8477 | "t" | ||
8478 | #endif | ||
8479 | #ifdef RLIMIT_FSIZE | ||
8480 | "f" | ||
8481 | #endif | ||
8482 | #ifdef RLIMIT_DATA | ||
8483 | "d" | ||
8484 | #endif | ||
8485 | #ifdef RLIMIT_STACK | ||
8486 | "s" | ||
8487 | #endif | ||
8488 | #ifdef RLIMIT_CORE | ||
8489 | "c" | ||
8490 | #endif | ||
8491 | #ifdef RLIMIT_RSS | ||
8492 | "m" | ||
8493 | #endif | ||
8494 | #ifdef RLIMIT_MEMLOCK | ||
8495 | "l" | ||
8496 | #endif | ||
8497 | #ifdef RLIMIT_NPROC | ||
8498 | "p" | ||
8499 | #endif | ||
8500 | #ifdef RLIMIT_NOFILE | ||
8501 | "n" | ||
8502 | #endif | ||
8503 | #ifdef RLIMIT_VMEM | ||
8504 | "v" | ||
8505 | #endif | ||
8506 | #ifdef RLIMIT_SWAP | ||
8507 | "w" | ||
8508 | #endif | ||
8509 | )) != '\0') { | ||
8510 | if (optc == 'H') { | ||
8350 | how = HARD; | 8511 | how = HARD; |
8351 | break; | 8512 | } else if (optc == 'S') { |
8352 | case 'S': | ||
8353 | how = SOFT; | 8513 | how = SOFT; |
8354 | break; | 8514 | } else if (optc == 'a') { |
8355 | case 'a': | ||
8356 | all = 1; | 8515 | all = 1; |
8357 | break; | 8516 | } else { |
8358 | default: | ||
8359 | what = optc; | 8517 | what = optc; |
8360 | } | 8518 | } |
8519 | } | ||
8361 | 8520 | ||
8362 | for (l = limits; l->name && l->option != what; l++) | 8521 | for (l = limits; l->name; l++) { |
8363 | ; | 8522 | if(l->name[0] == what) |
8364 | if (!l->name) | 8523 | break; |
8365 | error("internal error (%c)", what); | 8524 | if(l->name[1]=='w' && what=='w') |
8525 | break; | ||
8526 | } | ||
8366 | 8527 | ||
8367 | set = *argptr ? 1 : 0; | 8528 | set = *argptr ? 1 : 0; |
8368 | if (set) { | 8529 | if (set) { |
@@ -8370,7 +8531,7 @@ ulimitcmd(argc, argv) | |||
8370 | 8531 | ||
8371 | if (all || argptr[1]) | 8532 | if (all || argptr[1]) |
8372 | error("too many arguments"); | 8533 | error("too many arguments"); |
8373 | if (strcmp(p, "unlimited") == 0) | 8534 | if (strcmp(p, unlimited_string) == 0) |
8374 | val = RLIM_INFINITY; | 8535 | val = RLIM_INFINITY; |
8375 | else { | 8536 | else { |
8376 | val = (rlim_t) 0; | 8537 | val = (rlim_t) 0; |
@@ -8386,48 +8547,42 @@ ulimitcmd(argc, argv) | |||
8386 | val *= l->factor; | 8547 | val *= l->factor; |
8387 | } | 8548 | } |
8388 | } | 8549 | } |
8550 | |||
8389 | if (all) { | 8551 | if (all) { |
8390 | for (l = limits; l->name; l++) { | 8552 | for (l = limits; l->name; l++) { |
8553 | printf("%-20s ", l->name); | ||
8391 | getrlimit(l->cmd, &limit); | 8554 | getrlimit(l->cmd, &limit); |
8555 | OUTPUT_LIMIT: | ||
8392 | if (how & SOFT) | 8556 | if (how & SOFT) |
8393 | val = limit.rlim_cur; | 8557 | val = limit.rlim_cur; |
8394 | else if (how & HARD) | 8558 | else if (how & HARD) |
8395 | val = limit.rlim_max; | 8559 | val = limit.rlim_max; |
8396 | 8560 | ||
8397 | printf("%-20s ", l->name); | ||
8398 | if (val == RLIM_INFINITY) | 8561 | if (val == RLIM_INFINITY) |
8399 | printf("unlimited\n"); | 8562 | puts(unlimited_string); |
8400 | else | 8563 | else |
8401 | { | 8564 | { |
8402 | val /= l->factor; | 8565 | val /= l->factor; |
8403 | printf("%lld\n", (long long) val); | 8566 | printf("%lld\n", (long long) val); |
8404 | } | 8567 | } |
8568 | if (!all) { | ||
8569 | break; | ||
8570 | } | ||
8405 | } | 8571 | } |
8406 | return 0; | 8572 | return 0; |
8407 | } | 8573 | } |
8408 | 8574 | ||
8409 | getrlimit(l->cmd, &limit); | 8575 | if (!set) { |
8410 | if (set) { | 8576 | goto OUTPUT_LIMIT; |
8411 | if (how & HARD) | ||
8412 | limit.rlim_max = val; | ||
8413 | if (how & SOFT) | ||
8414 | limit.rlim_cur = val; | ||
8415 | if (setrlimit(l->cmd, &limit) < 0) | ||
8416 | error("error setting limit (%m)"); | ||
8417 | } else { | ||
8418 | if (how & SOFT) | ||
8419 | val = limit.rlim_cur; | ||
8420 | else if (how & HARD) | ||
8421 | val = limit.rlim_max; | ||
8422 | |||
8423 | if (val == RLIM_INFINITY) | ||
8424 | printf("unlimited\n"); | ||
8425 | else | ||
8426 | { | ||
8427 | val /= l->factor; | ||
8428 | printf("%lld\n", (long long) val); | ||
8429 | } | ||
8430 | } | 8577 | } |
8578 | |||
8579 | getrlimit(l->cmd, &limit); | ||
8580 | if (how & HARD) | ||
8581 | limit.rlim_max = val; | ||
8582 | if (how & SOFT) | ||
8583 | limit.rlim_cur = val; | ||
8584 | if (setrlimit(l->cmd, &limit) < 0) | ||
8585 | error("error setting limit (%m)"); | ||
8431 | return 0; | 8586 | return 0; |
8432 | } | 8587 | } |
8433 | /* | 8588 | /* |
@@ -8499,16 +8654,7 @@ single_quote(const char *s) { | |||
8499 | len2 = strspn(s + len1, "'"); | 8654 | len2 = strspn(s + len1, "'"); |
8500 | 8655 | ||
8501 | len1p = len1 ? len1 + 2 : len1; | 8656 | len1p = len1 ? len1 + 2 : len1; |
8502 | switch (len2) { | 8657 | len2p = len2 + ((len2 < 2) ? len2 : 2); |
8503 | case 0: | ||
8504 | len2p = 0; | ||
8505 | break; | ||
8506 | case 1: | ||
8507 | len2p = 2; | ||
8508 | break; | ||
8509 | default: | ||
8510 | len2p = len2 + 2; | ||
8511 | } | ||
8512 | 8658 | ||
8513 | CHECKSTRSPACE(len1p + len2p + 1, p); | 8659 | CHECKSTRSPACE(len1p + len2p + 1, p); |
8514 | 8660 | ||
@@ -8520,20 +8666,16 @@ single_quote(const char *s) { | |||
8520 | s += len1; | 8666 | s += len1; |
8521 | } | 8667 | } |
8522 | 8668 | ||
8523 | switch (len2) { | 8669 | if (len2 > 1) { |
8524 | case 0: | ||
8525 | break; | ||
8526 | case 1: | ||
8527 | *q++ = '\\'; | ||
8528 | *q = '\''; | ||
8529 | s++; | ||
8530 | break; | ||
8531 | default: | ||
8532 | *q = '"'; | 8670 | *q = '"'; |
8533 | q += 1 + len2; | 8671 | q += 1 + len2; |
8534 | memcpy(q + 1, s, len2); | 8672 | memcpy(q + 1, s, len2); |
8535 | *q = '"'; | 8673 | *q = '"'; |
8536 | s += len2; | 8674 | s += len2; |
8675 | } else if (len2 == 1) { | ||
8676 | *q++ = '\\'; | ||
8677 | *q = '\''; | ||
8678 | s++; | ||
8537 | } | 8679 | } |
8538 | 8680 | ||
8539 | STADJUST(len1p + len2p, p); | 8681 | STADJUST(len1p + len2p, p); |
@@ -8565,182 +8707,357 @@ static void sizenodelist (const struct nodelist *); | |||
8565 | static struct nodelist *copynodelist (const struct nodelist *); | 8707 | static struct nodelist *copynodelist (const struct nodelist *); |
8566 | static char *nodesavestr (const char *); | 8708 | static char *nodesavestr (const char *); |
8567 | 8709 | ||
8568 | static void | 8710 | //#define CALCSIZE_TABLE |
8569 | calcsize(const union node *n) | 8711 | //#define COPYNODE_TABLE |
8712 | #if defined(CALCSIZE_TABLE) || defined(COPYNODE_TABLE) | ||
8713 | /* | ||
8714 | * To collect a lot of redundant code in case statements for copynode() | ||
8715 | * and calcsize(), we implement a mini language here. Each type of node | ||
8716 | * struct has an associated instruction sequence that operates on its | ||
8717 | * members via their offsets. The instruction are pack in unsigned chars | ||
8718 | * with format IIDDDDDE where the bits are | ||
8719 | * I : part of the instruction opcode, which are | ||
8720 | * 00 : member is a pointer to another node | ||
8721 | * 40 : member is an integer | ||
8722 | * 80 : member is a pointer to a nodelist | ||
8723 | * CC : member is a pointer to a char string | ||
8724 | * D : data - the actual offset of the member to operate on in the struct | ||
8725 | * (since we assume bit 0 is set, it is not shifted) | ||
8726 | * E : flag signaling end of instruction sequence | ||
8727 | * | ||
8728 | * WARNING: In order to handle larger offsets for 64bit archs, this code | ||
8729 | * assumes that no offset can be an odd number and stores the | ||
8730 | * end-of-instructions flag in bit 0. | ||
8731 | */ | ||
8732 | |||
8733 | #define NODE_INTEGER 0x40 | ||
8734 | #define NODE_NODELIST 0x80 | ||
8735 | #define NODE_CHARPTR 0xC0 | ||
8736 | #define NODE_NOMORE 0x01 /* Note: no offset should be odd (aligned)*/ | ||
8737 | #define NODE_MBRMASK 0xC0 | ||
8738 | #define NODE_OFFSETMASK 0x3E | ||
8739 | |||
8740 | static const unsigned char copynode_ops[35] = { | ||
8741 | #define COPYNODE_OPS0 0 | ||
8742 | offsetof(union node, nbinary.ch2), | ||
8743 | offsetof(union node, nbinary.ch1)|NODE_NOMORE, | ||
8744 | #define COPYNODE_OPS1 (COPYNODE_OPS0 + 2) | ||
8745 | offsetof(union node, ncmd.redirect), | ||
8746 | offsetof(union node, ncmd.args), | ||
8747 | offsetof(union node, ncmd.assign), | ||
8748 | offsetof(union node, ncmd.backgnd)|NODE_INTEGER|NODE_NOMORE, | ||
8749 | #define COPYNODE_OPS2 (COPYNODE_OPS1 + 4) | ||
8750 | offsetof(union node, npipe.cmdlist)|NODE_NODELIST, | ||
8751 | offsetof(union node, npipe.backgnd)|NODE_INTEGER|NODE_NOMORE, | ||
8752 | #define COPYNODE_OPS3 (COPYNODE_OPS2 + 2) | ||
8753 | offsetof(union node, nredir.redirect), | ||
8754 | offsetof(union node, nredir.n)|NODE_NOMORE, | ||
8755 | #define COPYNODE_OPS4 (COPYNODE_OPS3 + 2) | ||
8756 | offsetof(union node, nif.elsepart), | ||
8757 | offsetof(union node, nif.ifpart), | ||
8758 | offsetof(union node, nif.test)|NODE_NOMORE, | ||
8759 | #define COPYNODE_OPS5 (COPYNODE_OPS4 + 3) | ||
8760 | offsetof(union node, nfor.var)|NODE_CHARPTR, | ||
8761 | offsetof(union node, nfor.body), | ||
8762 | offsetof(union node, nfor.args)|NODE_NOMORE, | ||
8763 | #define COPYNODE_OPS6 (COPYNODE_OPS5 + 3) | ||
8764 | offsetof(union node, ncase.cases), | ||
8765 | offsetof(union node, ncase.expr)|NODE_NOMORE, | ||
8766 | #define COPYNODE_OPS7 (COPYNODE_OPS6 + 2) | ||
8767 | offsetof(union node, nclist.body), | ||
8768 | offsetof(union node, nclist.pattern), | ||
8769 | offsetof(union node, nclist.next)|NODE_NOMORE, | ||
8770 | #define COPYNODE_OPS8 (COPYNODE_OPS7 + 3) | ||
8771 | offsetof(union node, narg.backquote)|NODE_NODELIST, | ||
8772 | offsetof(union node, narg.text)|NODE_CHARPTR, | ||
8773 | offsetof(union node, narg.next)|NODE_NOMORE, | ||
8774 | #define COPYNODE_OPS9 (COPYNODE_OPS8 + 3) | ||
8775 | offsetof(union node, nfile.fname), | ||
8776 | offsetof(union node, nfile.fd)|NODE_INTEGER, | ||
8777 | offsetof(union node, nfile.next)|NODE_NOMORE, | ||
8778 | #define COPYNODE_OPS10 (COPYNODE_OPS9 + 3) | ||
8779 | offsetof(union node, ndup.vname), | ||
8780 | offsetof(union node, ndup.dupfd)|NODE_INTEGER, | ||
8781 | offsetof(union node, ndup.fd)|NODE_INTEGER, | ||
8782 | offsetof(union node, ndup.next)|NODE_NOMORE, | ||
8783 | #define COPYNODE_OPS11 (COPYNODE_OPS10 + 4) | ||
8784 | offsetof(union node, nhere.doc), | ||
8785 | offsetof(union node, nhere.fd)|NODE_INTEGER, | ||
8786 | offsetof(union node, nhere.next)|NODE_NOMORE, | ||
8787 | #define COPYNODE_OPS12 (COPYNODE_OPS11 + 3) | ||
8788 | offsetof(union node, nnot.com)|NODE_NOMORE, | ||
8789 | }; | ||
8790 | |||
8791 | #if COPYNODE_OPS12 != 34 | ||
8792 | #error COPYNODE_OPS12 is incorrect | ||
8793 | #endif | ||
8794 | |||
8795 | static const unsigned char copynode_ops_index[26] = { | ||
8796 | COPYNODE_OPS0, /* NSEMI */ | ||
8797 | COPYNODE_OPS1, /* NCMD */ | ||
8798 | COPYNODE_OPS2, /* NPIPE */ | ||
8799 | COPYNODE_OPS3, /* NREDIR */ | ||
8800 | COPYNODE_OPS3, /* NBACKGND */ | ||
8801 | COPYNODE_OPS3, /* NSUBSHELL */ | ||
8802 | COPYNODE_OPS0, /* NAND */ | ||
8803 | COPYNODE_OPS0, /* NOR */ | ||
8804 | COPYNODE_OPS4, /* NIF */ | ||
8805 | COPYNODE_OPS0, /* NWHILE */ | ||
8806 | COPYNODE_OPS0, /* NUNTIL */ | ||
8807 | COPYNODE_OPS5, /* NFOR */ | ||
8808 | COPYNODE_OPS6, /* NCASE */ | ||
8809 | COPYNODE_OPS7, /* NCLIST */ | ||
8810 | COPYNODE_OPS8, /* NDEFUN */ | ||
8811 | COPYNODE_OPS8, /* NARG */ | ||
8812 | COPYNODE_OPS9, /* NTO */ | ||
8813 | COPYNODE_OPS9, /* NFROM */ | ||
8814 | COPYNODE_OPS9, /* NFROMTO */ | ||
8815 | COPYNODE_OPS9, /* NAPPEND */ | ||
8816 | COPYNODE_OPS9, /* NTOOV */ | ||
8817 | COPYNODE_OPS10, /* NTOFD */ | ||
8818 | COPYNODE_OPS10, /* NFROMFD */ | ||
8819 | COPYNODE_OPS11, /* NHERE */ | ||
8820 | COPYNODE_OPS11, /* NXHERE */ | ||
8821 | COPYNODE_OPS12, /* NNOT */ | ||
8822 | }; | ||
8823 | |||
8824 | #if NODE_CHARPTR != NODE_MBRMASK | ||
8825 | #error NODE_CHARPTR != NODE_MBRMASK!!! | ||
8826 | #endif | ||
8827 | #endif /* defined(CALCSIZE_TABLE) || defined(COPYNODE_TABLE) */ | ||
8828 | |||
8829 | #ifdef COPYNODE_TABLE | ||
8830 | static union node * | ||
8831 | copynode(const union node *n) | ||
8570 | { | 8832 | { |
8833 | union node *new; | ||
8834 | const unsigned char *p; | ||
8835 | |||
8571 | if (n == NULL) | 8836 | if (n == NULL) |
8572 | return; | 8837 | return NULL; |
8573 | funcblocksize += nodesize[n->type]; | 8838 | new = funcblock; |
8839 | new->type = n->type; | ||
8840 | funcblock = (char *) funcblock + (int) nodesize[n->type]; | ||
8841 | p = copynode_ops + (int) copynode_ops_index[n->type]; | ||
8842 | do { | ||
8843 | char *nn = ((char *) new) + ((int)(*p & NODE_OFFSETMASK)); | ||
8844 | const char *no = ((const char *) n) + ((int)(*p & NODE_OFFSETMASK)); | ||
8845 | |||
8846 | if (!(*p & NODE_MBRMASK)) { /* standard node */ | ||
8847 | (union node *) nn = copynode((const union node *) no); | ||
8848 | } else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */ | ||
8849 | nn = nodesavestr(no); | ||
8850 | } else if (*p & NODE_NODELIST) { /* nodelist */ | ||
8851 | (struct nodelist *) nn | ||
8852 | = copynodelist((const struct nodelist *) no); | ||
8853 | } else { /* integer */ | ||
8854 | *((int *) nn) = *((int *) no); | ||
8855 | } | ||
8856 | } while (!(*p++ & NODE_NOMORE)); | ||
8857 | return new; | ||
8858 | } | ||
8859 | #else /* COPYNODE_TABLE */ | ||
8860 | static union node * | ||
8861 | copynode(const union node *n) | ||
8862 | { | ||
8863 | union node *new; | ||
8864 | |||
8865 | if (n == NULL) | ||
8866 | return NULL; | ||
8867 | new = funcblock; | ||
8868 | funcblock = (char *) funcblock + nodesize[n->type]; | ||
8574 | switch (n->type) { | 8869 | switch (n->type) { |
8575 | case NSEMI: | 8870 | case NSEMI: |
8576 | case NAND: | 8871 | case NAND: |
8577 | case NOR: | 8872 | case NOR: |
8578 | case NWHILE: | 8873 | case NWHILE: |
8579 | case NUNTIL: | 8874 | case NUNTIL: |
8580 | calcsize(n->nbinary.ch2); | 8875 | new->nbinary.ch2 = copynode(n->nbinary.ch2); |
8581 | calcsize(n->nbinary.ch1); | 8876 | new->nbinary.ch1 = copynode(n->nbinary.ch1); |
8582 | break; | 8877 | break; |
8583 | case NCMD: | 8878 | case NCMD: |
8584 | calcsize(n->ncmd.redirect); | 8879 | new->ncmd.redirect = copynode(n->ncmd.redirect); |
8585 | calcsize(n->ncmd.args); | 8880 | new->ncmd.args = copynode(n->ncmd.args); |
8586 | calcsize(n->ncmd.assign); | 8881 | new->ncmd.assign = copynode(n->ncmd.assign); |
8882 | new->ncmd.backgnd = n->ncmd.backgnd; | ||
8587 | break; | 8883 | break; |
8588 | case NPIPE: | 8884 | case NPIPE: |
8589 | sizenodelist(n->npipe.cmdlist); | 8885 | new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); |
8886 | new->npipe.backgnd = n->npipe.backgnd; | ||
8590 | break; | 8887 | break; |
8591 | case NREDIR: | 8888 | case NREDIR: |
8592 | case NBACKGND: | 8889 | case NBACKGND: |
8593 | case NSUBSHELL: | 8890 | case NSUBSHELL: |
8594 | calcsize(n->nredir.redirect); | 8891 | new->nredir.redirect = copynode(n->nredir.redirect); |
8595 | calcsize(n->nredir.n); | 8892 | new->nredir.n = copynode(n->nredir.n); |
8596 | break; | 8893 | break; |
8597 | case NIF: | 8894 | case NIF: |
8598 | calcsize(n->nif.elsepart); | 8895 | new->nif.elsepart = copynode(n->nif.elsepart); |
8599 | calcsize(n->nif.ifpart); | 8896 | new->nif.ifpart = copynode(n->nif.ifpart); |
8600 | calcsize(n->nif.test); | 8897 | new->nif.test = copynode(n->nif.test); |
8601 | break; | 8898 | break; |
8602 | case NFOR: | 8899 | case NFOR: |
8603 | funcstringsize += strlen(n->nfor.var) + 1; | 8900 | new->nfor.var = nodesavestr(n->nfor.var); |
8604 | calcsize(n->nfor.body); | 8901 | new->nfor.body = copynode(n->nfor.body); |
8605 | calcsize(n->nfor.args); | 8902 | new->nfor.args = copynode(n->nfor.args); |
8606 | break; | 8903 | break; |
8607 | case NCASE: | 8904 | case NCASE: |
8608 | calcsize(n->ncase.cases); | 8905 | new->ncase.cases = copynode(n->ncase.cases); |
8609 | calcsize(n->ncase.expr); | 8906 | new->ncase.expr = copynode(n->ncase.expr); |
8610 | break; | 8907 | break; |
8611 | case NCLIST: | 8908 | case NCLIST: |
8612 | calcsize(n->nclist.body); | 8909 | new->nclist.body = copynode(n->nclist.body); |
8613 | calcsize(n->nclist.pattern); | 8910 | new->nclist.pattern = copynode(n->nclist.pattern); |
8614 | calcsize(n->nclist.next); | 8911 | new->nclist.next = copynode(n->nclist.next); |
8615 | break; | 8912 | break; |
8616 | case NDEFUN: | 8913 | case NDEFUN: |
8617 | case NARG: | 8914 | case NARG: |
8618 | sizenodelist(n->narg.backquote); | 8915 | new->narg.backquote = copynodelist(n->narg.backquote); |
8619 | funcstringsize += strlen(n->narg.text) + 1; | 8916 | new->narg.text = nodesavestr(n->narg.text); |
8620 | calcsize(n->narg.next); | 8917 | new->narg.next = copynode(n->narg.next); |
8621 | break; | 8918 | break; |
8622 | case NTO: | 8919 | case NTO: |
8623 | case NFROM: | 8920 | case NFROM: |
8624 | case NFROMTO: | 8921 | case NFROMTO: |
8625 | case NAPPEND: | 8922 | case NAPPEND: |
8626 | case NTOOV: | 8923 | case NTOOV: |
8627 | calcsize(n->nfile.fname); | 8924 | new->nfile.fname = copynode(n->nfile.fname); |
8628 | calcsize(n->nfile.next); | 8925 | new->nfile.fd = n->nfile.fd; |
8926 | new->nfile.next = copynode(n->nfile.next); | ||
8629 | break; | 8927 | break; |
8630 | case NTOFD: | 8928 | case NTOFD: |
8631 | case NFROMFD: | 8929 | case NFROMFD: |
8632 | calcsize(n->ndup.vname); | 8930 | new->ndup.vname = copynode(n->ndup.vname); |
8633 | calcsize(n->ndup.next); | 8931 | new->ndup.dupfd = n->ndup.dupfd; |
8932 | new->ndup.fd = n->ndup.fd; | ||
8933 | new->ndup.next = copynode(n->ndup.next); | ||
8634 | break; | 8934 | break; |
8635 | case NHERE: | 8935 | case NHERE: |
8636 | case NXHERE: | 8936 | case NXHERE: |
8637 | calcsize(n->nhere.doc); | 8937 | new->nhere.doc = copynode(n->nhere.doc); |
8638 | calcsize(n->nhere.next); | 8938 | new->nhere.fd = n->nhere.fd; |
8939 | new->nhere.next = copynode(n->nhere.next); | ||
8639 | break; | 8940 | break; |
8640 | case NNOT: | 8941 | case NNOT: |
8641 | calcsize(n->nnot.com); | 8942 | new->nnot.com = copynode(n->nnot.com); |
8642 | break; | 8943 | break; |
8643 | }; | 8944 | }; |
8945 | new->type = n->type; | ||
8946 | return new; | ||
8644 | } | 8947 | } |
8948 | #endif /* COPYNODE_TABLE */ | ||
8645 | 8949 | ||
8950 | #ifdef CALCSIZE_TABLE | ||
8646 | static void | 8951 | static void |
8647 | sizenodelist(const struct nodelist *lp) | 8952 | calcsize(const union node *n) |
8648 | { | 8953 | { |
8649 | while (lp) { | 8954 | const unsigned char *p; |
8650 | funcblocksize += ALIGN(sizeof(struct nodelist)); | ||
8651 | calcsize(lp->n); | ||
8652 | lp = lp->next; | ||
8653 | } | ||
8654 | } | ||
8655 | |||
8656 | 8955 | ||
8657 | static union node * | 8956 | if (n == NULL) |
8658 | copynode(const union node *n) | 8957 | return; |
8958 | funcblocksize += (int) nodesize[n->type]; | ||
8959 | |||
8960 | p = copynode_ops + (int) copynode_ops_index[n->type]; | ||
8961 | do { | ||
8962 | const char *no = ((const char *) n) + ((int)(*p & NODE_OFFSETMASK)); | ||
8963 | |||
8964 | if (!(*p & NODE_MBRMASK)) { /* standard node */ | ||
8965 | calcsize((const union node *) no); | ||
8966 | } else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */ | ||
8967 | funcstringsize += strlen(no) + 1; | ||
8968 | } else if (*p & NODE_NODELIST) { /* nodelist */ | ||
8969 | sizenodelist((const struct nodelist *) no); | ||
8970 | } | ||
8971 | } while (!(*p++ & NODE_NOMORE)); | ||
8972 | } | ||
8973 | #else /* CALCSIZE_TABLE */ | ||
8974 | static void | ||
8975 | calcsize(const union node *n) | ||
8659 | { | 8976 | { |
8660 | union node *new; | ||
8661 | |||
8662 | if (n == NULL) | 8977 | if (n == NULL) |
8663 | return NULL; | 8978 | return; |
8664 | new = funcblock; | 8979 | funcblocksize += nodesize[n->type]; |
8665 | funcblock = (char *) funcblock + nodesize[n->type]; | ||
8666 | switch (n->type) { | 8980 | switch (n->type) { |
8667 | case NSEMI: | 8981 | case NSEMI: |
8668 | case NAND: | 8982 | case NAND: |
8669 | case NOR: | 8983 | case NOR: |
8670 | case NWHILE: | 8984 | case NWHILE: |
8671 | case NUNTIL: | 8985 | case NUNTIL: |
8672 | new->nbinary.ch2 = copynode(n->nbinary.ch2); | 8986 | calcsize(n->nbinary.ch2); |
8673 | new->nbinary.ch1 = copynode(n->nbinary.ch1); | 8987 | calcsize(n->nbinary.ch1); |
8674 | break; | 8988 | break; |
8675 | case NCMD: | 8989 | case NCMD: |
8676 | new->ncmd.redirect = copynode(n->ncmd.redirect); | 8990 | calcsize(n->ncmd.redirect); |
8677 | new->ncmd.args = copynode(n->ncmd.args); | 8991 | calcsize(n->ncmd.args); |
8678 | new->ncmd.assign = copynode(n->ncmd.assign); | 8992 | calcsize(n->ncmd.assign); |
8679 | new->ncmd.backgnd = n->ncmd.backgnd; | ||
8680 | break; | 8993 | break; |
8681 | case NPIPE: | 8994 | case NPIPE: |
8682 | new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); | 8995 | sizenodelist(n->npipe.cmdlist); |
8683 | new->npipe.backgnd = n->npipe.backgnd; | ||
8684 | break; | 8996 | break; |
8685 | case NREDIR: | 8997 | case NREDIR: |
8686 | case NBACKGND: | 8998 | case NBACKGND: |
8687 | case NSUBSHELL: | 8999 | case NSUBSHELL: |
8688 | new->nredir.redirect = copynode(n->nredir.redirect); | 9000 | calcsize(n->nredir.redirect); |
8689 | new->nredir.n = copynode(n->nredir.n); | 9001 | calcsize(n->nredir.n); |
8690 | break; | 9002 | break; |
8691 | case NIF: | 9003 | case NIF: |
8692 | new->nif.elsepart = copynode(n->nif.elsepart); | 9004 | calcsize(n->nif.elsepart); |
8693 | new->nif.ifpart = copynode(n->nif.ifpart); | 9005 | calcsize(n->nif.ifpart); |
8694 | new->nif.test = copynode(n->nif.test); | 9006 | calcsize(n->nif.test); |
8695 | break; | 9007 | break; |
8696 | case NFOR: | 9008 | case NFOR: |
8697 | new->nfor.var = nodesavestr(n->nfor.var); | 9009 | funcstringsize += strlen(n->nfor.var) + 1; |
8698 | new->nfor.body = copynode(n->nfor.body); | 9010 | calcsize(n->nfor.body); |
8699 | new->nfor.args = copynode(n->nfor.args); | 9011 | calcsize(n->nfor.args); |
8700 | break; | 9012 | break; |
8701 | case NCASE: | 9013 | case NCASE: |
8702 | new->ncase.cases = copynode(n->ncase.cases); | 9014 | calcsize(n->ncase.cases); |
8703 | new->ncase.expr = copynode(n->ncase.expr); | 9015 | calcsize(n->ncase.expr); |
8704 | break; | 9016 | break; |
8705 | case NCLIST: | 9017 | case NCLIST: |
8706 | new->nclist.body = copynode(n->nclist.body); | 9018 | calcsize(n->nclist.body); |
8707 | new->nclist.pattern = copynode(n->nclist.pattern); | 9019 | calcsize(n->nclist.pattern); |
8708 | new->nclist.next = copynode(n->nclist.next); | 9020 | calcsize(n->nclist.next); |
8709 | break; | 9021 | break; |
8710 | case NDEFUN: | 9022 | case NDEFUN: |
8711 | case NARG: | 9023 | case NARG: |
8712 | new->narg.backquote = copynodelist(n->narg.backquote); | 9024 | sizenodelist(n->narg.backquote); |
8713 | new->narg.text = nodesavestr(n->narg.text); | 9025 | funcstringsize += strlen(n->narg.text) + 1; |
8714 | new->narg.next = copynode(n->narg.next); | 9026 | calcsize(n->narg.next); |
8715 | break; | 9027 | break; |
8716 | case NTO: | 9028 | case NTO: |
8717 | case NFROM: | 9029 | case NFROM: |
8718 | case NFROMTO: | 9030 | case NFROMTO: |
8719 | case NAPPEND: | 9031 | case NAPPEND: |
8720 | case NTOOV: | 9032 | case NTOOV: |
8721 | new->nfile.fname = copynode(n->nfile.fname); | 9033 | calcsize(n->nfile.fname); |
8722 | new->nfile.fd = n->nfile.fd; | 9034 | calcsize(n->nfile.next); |
8723 | new->nfile.next = copynode(n->nfile.next); | ||
8724 | break; | 9035 | break; |
8725 | case NTOFD: | 9036 | case NTOFD: |
8726 | case NFROMFD: | 9037 | case NFROMFD: |
8727 | new->ndup.vname = copynode(n->ndup.vname); | 9038 | calcsize(n->ndup.vname); |
8728 | new->ndup.dupfd = n->ndup.dupfd; | 9039 | calcsize(n->ndup.next); |
8729 | new->ndup.fd = n->ndup.fd; | ||
8730 | new->ndup.next = copynode(n->ndup.next); | ||
8731 | break; | 9040 | break; |
8732 | case NHERE: | 9041 | case NHERE: |
8733 | case NXHERE: | 9042 | case NXHERE: |
8734 | new->nhere.doc = copynode(n->nhere.doc); | 9043 | calcsize(n->nhere.doc); |
8735 | new->nhere.fd = n->nhere.fd; | 9044 | calcsize(n->nhere.next); |
8736 | new->nhere.next = copynode(n->nhere.next); | ||
8737 | break; | 9045 | break; |
8738 | case NNOT: | 9046 | case NNOT: |
8739 | new->nnot.com = copynode(n->nnot.com); | 9047 | calcsize(n->nnot.com); |
8740 | break; | 9048 | break; |
8741 | }; | 9049 | }; |
8742 | new->type = n->type; | 9050 | } |
8743 | return new; | 9051 | #endif /* CALCSIZE_TABLE */ |
9052 | |||
9053 | static void | ||
9054 | sizenodelist(const struct nodelist *lp) | ||
9055 | { | ||
9056 | while (lp) { | ||
9057 | funcblocksize += ALIGN(sizeof(struct nodelist)); | ||
9058 | calcsize(lp->n); | ||
9059 | lp = lp->next; | ||
9060 | } | ||
8744 | } | 9061 | } |
8745 | 9062 | ||
8746 | 9063 | ||
@@ -9346,10 +9663,10 @@ static union node *command (void); | |||
9346 | static union node *simplecmd (void); | 9663 | static union node *simplecmd (void); |
9347 | static void parsefname (void); | 9664 | static void parsefname (void); |
9348 | static void parseheredoc (void); | 9665 | static void parseheredoc (void); |
9349 | static int peektoken (void); | 9666 | static char peektoken (void); |
9350 | static int readtoken (void); | 9667 | static int readtoken (void); |
9351 | static int xxreadtoken (void); | 9668 | static int xxreadtoken (void); |
9352 | static int readtoken1 (int, char const *, char *, int); | 9669 | static int readtoken1 (int, int, const char *, int); |
9353 | static int noexpand (char *); | 9670 | static int noexpand (char *); |
9354 | static void synexpect (int) __attribute__((noreturn)); | 9671 | static void synexpect (int) __attribute__((noreturn)); |
9355 | static void synerror (const char *) __attribute__((noreturn)); | 9672 | static void synerror (const char *) __attribute__((noreturn)); |
@@ -9391,7 +9708,7 @@ list(nlflag) | |||
9391 | int tok; | 9708 | int tok; |
9392 | 9709 | ||
9393 | checkkwd = 2; | 9710 | checkkwd = 2; |
9394 | if (nlflag == 0 && tokendlist[peektoken()]) | 9711 | if (nlflag == 0 && peektoken()) |
9395 | return NULL; | 9712 | return NULL; |
9396 | n1 = NULL; | 9713 | n1 = NULL; |
9397 | for (;;) { | 9714 | for (;;) { |
@@ -9434,7 +9751,7 @@ list(nlflag) | |||
9434 | tokpushback++; | 9751 | tokpushback++; |
9435 | } | 9752 | } |
9436 | checkkwd = 2; | 9753 | checkkwd = 2; |
9437 | if (tokendlist[peektoken()]) | 9754 | if (peektoken()) |
9438 | return n1; | 9755 | return n1; |
9439 | break; | 9756 | break; |
9440 | case TEOF: | 9757 | case TEOF: |
@@ -9572,7 +9889,7 @@ command() { | |||
9572 | n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; | 9889 | n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; |
9573 | n1->nbinary.ch1 = list(0); | 9890 | n1->nbinary.ch1 = list(0); |
9574 | if ((got=readtoken()) != TDO) { | 9891 | if ((got=readtoken()) != TDO) { |
9575 | TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); | 9892 | TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); |
9576 | synexpect(TDO); | 9893 | synexpect(TDO); |
9577 | } | 9894 | } |
9578 | n1->nbinary.ch2 = list(0); | 9895 | n1->nbinary.ch2 = list(0); |
@@ -9901,13 +10218,13 @@ parseheredoc() { | |||
9901 | } | 10218 | } |
9902 | } | 10219 | } |
9903 | 10220 | ||
9904 | static int | 10221 | static char |
9905 | peektoken() { | 10222 | peektoken() { |
9906 | int t; | 10223 | int t; |
9907 | 10224 | ||
9908 | t = readtoken(); | 10225 | t = readtoken(); |
9909 | tokpushback++; | 10226 | tokpushback++; |
9910 | return (t); | 10227 | return tokname_array[t][0]; |
9911 | } | 10228 | } |
9912 | 10229 | ||
9913 | static int | 10230 | static int |
@@ -9954,8 +10271,8 @@ top: | |||
9954 | const char *const *pp; | 10271 | const char *const *pp; |
9955 | 10272 | ||
9956 | if ((pp = findkwd(wordtext))) { | 10273 | if ((pp = findkwd(wordtext))) { |
9957 | lasttoken = t = pp - parsekwd + KWDOFFSET; | 10274 | lasttoken = t = pp - tokname_array; |
9958 | TRACE(("keyword %s recognized\n", tokname[t])); | 10275 | TRACE(("keyword %s recognized\n", tokname(t))); |
9959 | goto out; | 10276 | goto out; |
9960 | } | 10277 | } |
9961 | } | 10278 | } |
@@ -9983,9 +10300,9 @@ top: | |||
9983 | out: | 10300 | out: |
9984 | #ifdef DEBUG | 10301 | #ifdef DEBUG |
9985 | if (!alreadyseen) | 10302 | if (!alreadyseen) |
9986 | TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : "")); | 10303 | TRACE(("token %s %s\n", tokname(t), t == TWORD || t == TASSIGN ? wordtext : "")); |
9987 | else | 10304 | else |
9988 | TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : "")); | 10305 | TRACE(("reread token %s %s\n", tokname(t), t == TWORD || t == TASSIGN ? wordtext : "")); |
9989 | #endif | 10306 | #endif |
9990 | return (t); | 10307 | return (t); |
9991 | } | 10308 | } |
@@ -10103,12 +10420,8 @@ breakloop: | |||
10103 | #define PARSEARITH() {goto parsearith; parsearith_return:;} | 10420 | #define PARSEARITH() {goto parsearith; parsearith_return:;} |
10104 | 10421 | ||
10105 | static int | 10422 | static int |
10106 | readtoken1(firstc, syntax, eofmark, striptabs) | 10423 | readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) |
10107 | int firstc; | 10424 | { |
10108 | char const *syntax; | ||
10109 | char *eofmark; | ||
10110 | int striptabs; | ||
10111 | { | ||
10112 | int c = firstc; | 10425 | int c = firstc; |
10113 | char *out; | 10426 | char *out; |
10114 | int len; | 10427 | int len; |
@@ -10121,7 +10434,7 @@ readtoken1(firstc, syntax, eofmark, striptabs) | |||
10121 | int parenlevel; /* levels of parens in arithmetic */ | 10434 | int parenlevel; /* levels of parens in arithmetic */ |
10122 | int dqvarnest; /* levels of variables expansion within double quotes */ | 10435 | int dqvarnest; /* levels of variables expansion within double quotes */ |
10123 | int oldstyle; | 10436 | int oldstyle; |
10124 | char const *prevsyntax; /* syntax before arithmetic */ | 10437 | int prevsyntax; /* syntax before arithmetic */ |
10125 | #if __GNUC__ | 10438 | #if __GNUC__ |
10126 | /* Avoid longjmp clobbering */ | 10439 | /* Avoid longjmp clobbering */ |
10127 | (void) &out; | 10440 | (void) &out; |
@@ -10152,7 +10465,7 @@ readtoken1(firstc, syntax, eofmark, striptabs) | |||
10152 | CHECKEND(); /* set c to PEOF if at end of here document */ | 10465 | CHECKEND(); /* set c to PEOF if at end of here document */ |
10153 | for (;;) { /* until end of line or end of word */ | 10466 | for (;;) { /* until end of line or end of word */ |
10154 | CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ | 10467 | CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ |
10155 | switch(syntax[c]) { | 10468 | switch(SIT(c,syntax)) { |
10156 | case CNL: /* '\n' */ | 10469 | case CNL: /* '\n' */ |
10157 | if (syntax == BASESYNTAX) | 10470 | if (syntax == BASESYNTAX) |
10158 | goto endword; /* exit outer loop */ | 10471 | goto endword; /* exit outer loop */ |
@@ -10187,7 +10500,7 @@ readtoken1(firstc, syntax, eofmark, striptabs) | |||
10187 | if (dblquote && c != '\\' && c != '`' && c != '$' | 10500 | if (dblquote && c != '\\' && c != '`' && c != '$' |
10188 | && (c != '"' || eofmark != NULL)) | 10501 | && (c != '"' || eofmark != NULL)) |
10189 | USTPUTC('\\', out); | 10502 | USTPUTC('\\', out); |
10190 | if (SQSYNTAX[c] == CCTL) | 10503 | if (SIT(c,SQSYNTAX) == CCTL) |
10191 | USTPUTC(CTLESC, out); | 10504 | USTPUTC(CTLESC, out); |
10192 | else if (eofmark == NULL) | 10505 | else if (eofmark == NULL) |
10193 | USTPUTC(CTLQUOTEMARK, out); | 10506 | USTPUTC(CTLQUOTEMARK, out); |
@@ -10338,7 +10651,7 @@ checkend: { | |||
10338 | } | 10651 | } |
10339 | if (c == *eofmark) { | 10652 | if (c == *eofmark) { |
10340 | if (pfgets(line, sizeof line) != NULL) { | 10653 | if (pfgets(line, sizeof line) != NULL) { |
10341 | char *p, *q; | 10654 | const char *p, *q; |
10342 | 10655 | ||
10343 | p = line; | 10656 | p = line; |
10344 | for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); | 10657 | for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); |
@@ -10728,7 +11041,7 @@ noexpand(text) | |||
10728 | continue; | 11041 | continue; |
10729 | if (c == CTLESC) | 11042 | if (c == CTLESC) |
10730 | p++; | 11043 | p++; |
10731 | else if (BASESYNTAX[(int)c] == CCTL) | 11044 | else if (SIT(c,BASESYNTAX) == CCTL) |
10732 | return 0; | 11045 | return 0; |
10733 | } | 11046 | } |
10734 | return 1; | 11047 | return 1; |
@@ -10767,13 +11080,11 @@ synexpect(token) | |||
10767 | int token; | 11080 | int token; |
10768 | { | 11081 | { |
10769 | char msg[64]; | 11082 | char msg[64]; |
11083 | int l; | ||
10770 | 11084 | ||
10771 | if (token >= 0) { | 11085 | l = sprintf(msg, "%s unexpected", tokname(lasttoken)); |
10772 | snprintf(msg, 64, "%s unexpected (expecting %s)", | 11086 | if (token >= 0) |
10773 | tokname[lasttoken], tokname[token]); | 11087 | sprintf(msg+l, " (expecting %s)", tokname(token)); |
10774 | } else { | ||
10775 | snprintf(msg, 64, "%s unexpected", tokname[lasttoken]); | ||
10776 | } | ||
10777 | synerror(msg); | 11088 | synerror(msg); |
10778 | /* NOTREACHED */ | 11089 | /* NOTREACHED */ |
10779 | } | 11090 | } |
@@ -11162,435 +11473,6 @@ dup_as_newfd(from, to) | |||
11162 | return newfd; | 11473 | return newfd; |
11163 | } | 11474 | } |
11164 | 11475 | ||
11165 | /*#ifdef __weak_alias | ||
11166 | __weak_alias(getmode,_getmode) | ||
11167 | __weak_alias(setmode,_setmode) | ||
11168 | #endif*/ | ||
11169 | |||
11170 | #ifndef S_ISTXT | ||
11171 | #if defined(__GLIBC__) && __GLIBC__ >= 2 | ||
11172 | #define S_ISTXT __S_ISVTX | ||
11173 | #else | ||
11174 | #define S_ISTXT S_ISVTX | ||
11175 | #endif | ||
11176 | #endif | ||
11177 | |||
11178 | #define SET_LEN 6 /* initial # of bitcmd struct to malloc */ | ||
11179 | #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */ | ||
11180 | |||
11181 | typedef struct bitcmd { | ||
11182 | char cmd; | ||
11183 | char cmd2; | ||
11184 | mode_t bits; | ||
11185 | } BITCMD; | ||
11186 | |||
11187 | #define CMD2_CLR 0x01 | ||
11188 | #define CMD2_SET 0x02 | ||
11189 | #define CMD2_GBITS 0x04 | ||
11190 | #define CMD2_OBITS 0x08 | ||
11191 | #define CMD2_UBITS 0x10 | ||
11192 | |||
11193 | static BITCMD *addcmd (BITCMD *, int, int, int, u_int); | ||
11194 | static void compress_mode (BITCMD *); | ||
11195 | #ifdef SETMODE_DEBUG | ||
11196 | static void dumpmode (BITCMD *); | ||
11197 | #endif | ||
11198 | |||
11199 | /* | ||
11200 | * Given the old mode and an array of bitcmd structures, apply the operations | ||
11201 | * described in the bitcmd structures to the old mode, and return the new mode. | ||
11202 | * Note that there is no '=' command; a strict assignment is just a '-' (clear | ||
11203 | * bits) followed by a '+' (set bits). | ||
11204 | */ | ||
11205 | static mode_t | ||
11206 | getmode(bbox, omode) | ||
11207 | const void *bbox; | ||
11208 | mode_t omode; | ||
11209 | { | ||
11210 | const BITCMD *set; | ||
11211 | mode_t clrval, newmode, value; | ||
11212 | |||
11213 | _DIAGASSERT(bbox != NULL); | ||
11214 | |||
11215 | set = (const BITCMD *)bbox; | ||
11216 | newmode = omode; | ||
11217 | for (value = 0;; set++) | ||
11218 | switch(set->cmd) { | ||
11219 | /* | ||
11220 | * When copying the user, group or other bits around, we "know" | ||
11221 | * where the bits are in the mode so that we can do shifts to | ||
11222 | * copy them around. If we don't use shifts, it gets real | ||
11223 | * grundgy with lots of single bit checks and bit sets. | ||
11224 | */ | ||
11225 | case 'u': | ||
11226 | value = (newmode & S_IRWXU) >> 6; | ||
11227 | goto common; | ||
11228 | |||
11229 | case 'g': | ||
11230 | value = (newmode & S_IRWXG) >> 3; | ||
11231 | goto common; | ||
11232 | |||
11233 | case 'o': | ||
11234 | value = newmode & S_IRWXO; | ||
11235 | common: if (set->cmd2 & CMD2_CLR) { | ||
11236 | clrval = | ||
11237 | (set->cmd2 & CMD2_SET) ? S_IRWXO : value; | ||
11238 | if (set->cmd2 & CMD2_UBITS) | ||
11239 | newmode &= ~((clrval<<6) & set->bits); | ||
11240 | if (set->cmd2 & CMD2_GBITS) | ||
11241 | newmode &= ~((clrval<<3) & set->bits); | ||
11242 | if (set->cmd2 & CMD2_OBITS) | ||
11243 | newmode &= ~(clrval & set->bits); | ||
11244 | } | ||
11245 | if (set->cmd2 & CMD2_SET) { | ||
11246 | if (set->cmd2 & CMD2_UBITS) | ||
11247 | newmode |= (value<<6) & set->bits; | ||
11248 | if (set->cmd2 & CMD2_GBITS) | ||
11249 | newmode |= (value<<3) & set->bits; | ||
11250 | if (set->cmd2 & CMD2_OBITS) | ||
11251 | newmode |= value & set->bits; | ||
11252 | } | ||
11253 | break; | ||
11254 | |||
11255 | case '+': | ||
11256 | newmode |= set->bits; | ||
11257 | break; | ||
11258 | |||
11259 | case '-': | ||
11260 | newmode &= ~set->bits; | ||
11261 | break; | ||
11262 | |||
11263 | case 'X': | ||
11264 | if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH)) | ||
11265 | newmode |= set->bits; | ||
11266 | break; | ||
11267 | |||
11268 | case '\0': | ||
11269 | default: | ||
11270 | #ifdef SETMODE_DEBUG | ||
11271 | (void)printf("getmode:%04o -> %04o\n", omode, newmode); | ||
11272 | #endif | ||
11273 | return (newmode); | ||
11274 | } | ||
11275 | } | ||
11276 | |||
11277 | #define ADDCMD(a, b, c, d) do { \ | ||
11278 | if (set >= endset) { \ | ||
11279 | BITCMD *newset; \ | ||
11280 | setlen += SET_LEN_INCR; \ | ||
11281 | newset = realloc(saveset, sizeof(BITCMD) * setlen); \ | ||
11282 | if (newset == NULL) { \ | ||
11283 | free(saveset); \ | ||
11284 | return (NULL); \ | ||
11285 | } \ | ||
11286 | set = newset + (set - saveset); \ | ||
11287 | saveset = newset; \ | ||
11288 | endset = newset + (setlen - 2); \ | ||
11289 | } \ | ||
11290 | set = addcmd(set, (a), (b), (c), (d)); \ | ||
11291 | } while (/*CONSTCOND*/0) | ||
11292 | |||
11293 | #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) | ||
11294 | |||
11295 | static void * | ||
11296 | setmode(p) | ||
11297 | const char *p; | ||
11298 | { | ||
11299 | int perm, who; | ||
11300 | char op, *ep; | ||
11301 | BITCMD *set, *saveset, *endset; | ||
11302 | sigset_t mysigset, sigoset; | ||
11303 | mode_t mask; | ||
11304 | int equalopdone = 0; /* pacify gcc */ | ||
11305 | int permXbits, setlen; | ||
11306 | |||
11307 | if (!*p) | ||
11308 | return (NULL); | ||
11309 | |||
11310 | /* | ||
11311 | * Get a copy of the mask for the permissions that are mask relative. | ||
11312 | * Flip the bits, we want what's not set. Since it's possible that | ||
11313 | * the caller is opening files inside a signal handler, protect them | ||
11314 | * as best we can. | ||
11315 | */ | ||
11316 | sigfillset(&mysigset); | ||
11317 | (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset); | ||
11318 | (void)umask(mask = umask(0)); | ||
11319 | mask = ~mask; | ||
11320 | (void)sigprocmask(SIG_SETMASK, &sigoset, NULL); | ||
11321 | |||
11322 | setlen = SET_LEN + 2; | ||
11323 | |||
11324 | if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL) | ||
11325 | return (NULL); | ||
11326 | saveset = set; | ||
11327 | endset = set + (setlen - 2); | ||
11328 | |||
11329 | /* | ||
11330 | * If an absolute number, get it and return; disallow non-octal digits | ||
11331 | * or illegal bits. | ||
11332 | */ | ||
11333 | if (is_digit((unsigned char)*p)) { | ||
11334 | perm = (mode_t)strtol(p, &ep, 8); | ||
11335 | if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) { | ||
11336 | free(saveset); | ||
11337 | return (NULL); | ||
11338 | } | ||
11339 | ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); | ||
11340 | set->cmd = 0; | ||
11341 | return (saveset); | ||
11342 | } | ||
11343 | |||
11344 | /* | ||
11345 | * Build list of structures to set/clear/copy bits as described by | ||
11346 | * each clause of the symbolic mode. | ||
11347 | */ | ||
11348 | for (;;) { | ||
11349 | /* First, find out which bits might be modified. */ | ||
11350 | for (who = 0;; ++p) { | ||
11351 | switch (*p) { | ||
11352 | case 'a': | ||
11353 | who |= STANDARD_BITS; | ||
11354 | break; | ||
11355 | case 'u': | ||
11356 | who |= S_ISUID|S_IRWXU; | ||
11357 | break; | ||
11358 | case 'g': | ||
11359 | who |= S_ISGID|S_IRWXG; | ||
11360 | break; | ||
11361 | case 'o': | ||
11362 | who |= S_IRWXO; | ||
11363 | break; | ||
11364 | default: | ||
11365 | goto getop; | ||
11366 | } | ||
11367 | } | ||
11368 | |||
11369 | getop: if ((op = *p++) != '+' && op != '-' && op != '=') { | ||
11370 | free(saveset); | ||
11371 | return (NULL); | ||
11372 | } | ||
11373 | if (op == '=') | ||
11374 | equalopdone = 0; | ||
11375 | |||
11376 | who &= ~S_ISTXT; | ||
11377 | for (perm = 0, permXbits = 0;; ++p) { | ||
11378 | switch (*p) { | ||
11379 | case 'r': | ||
11380 | perm |= S_IRUSR|S_IRGRP|S_IROTH; | ||
11381 | break; | ||
11382 | case 's': | ||
11383 | /* | ||
11384 | * If specific bits where requested and | ||
11385 | * only "other" bits ignore set-id. | ||
11386 | */ | ||
11387 | if (who == 0 || (who & ~S_IRWXO)) | ||
11388 | perm |= S_ISUID|S_ISGID; | ||
11389 | break; | ||
11390 | case 't': | ||
11391 | /* | ||
11392 | * If specific bits where requested and | ||
11393 | * only "other" bits ignore set-id. | ||
11394 | */ | ||
11395 | if (who == 0 || (who & ~S_IRWXO)) { | ||
11396 | who |= S_ISTXT; | ||
11397 | perm |= S_ISTXT; | ||
11398 | } | ||
11399 | break; | ||
11400 | case 'w': | ||
11401 | perm |= S_IWUSR|S_IWGRP|S_IWOTH; | ||
11402 | break; | ||
11403 | case 'X': | ||
11404 | permXbits = S_IXUSR|S_IXGRP|S_IXOTH; | ||
11405 | break; | ||
11406 | case 'x': | ||
11407 | perm |= S_IXUSR|S_IXGRP|S_IXOTH; | ||
11408 | break; | ||
11409 | case 'u': | ||
11410 | case 'g': | ||
11411 | case 'o': | ||
11412 | /* | ||
11413 | * When ever we hit 'u', 'g', or 'o', we have | ||
11414 | * to flush out any partial mode that we have, | ||
11415 | * and then do the copying of the mode bits. | ||
11416 | */ | ||
11417 | if (perm) { | ||
11418 | ADDCMD(op, who, perm, mask); | ||
11419 | perm = 0; | ||
11420 | } | ||
11421 | if (op == '=') | ||
11422 | equalopdone = 1; | ||
11423 | if (op == '+' && permXbits) { | ||
11424 | ADDCMD('X', who, permXbits, mask); | ||
11425 | permXbits = 0; | ||
11426 | } | ||
11427 | ADDCMD(*p, who, op, mask); | ||
11428 | break; | ||
11429 | |||
11430 | default: | ||
11431 | /* | ||
11432 | * Add any permissions that we haven't already | ||
11433 | * done. | ||
11434 | */ | ||
11435 | if (perm || (op == '=' && !equalopdone)) { | ||
11436 | if (op == '=') | ||
11437 | equalopdone = 1; | ||
11438 | ADDCMD(op, who, perm, mask); | ||
11439 | perm = 0; | ||
11440 | } | ||
11441 | if (permXbits) { | ||
11442 | ADDCMD('X', who, permXbits, mask); | ||
11443 | permXbits = 0; | ||
11444 | } | ||
11445 | goto apply; | ||
11446 | } | ||
11447 | } | ||
11448 | |||
11449 | apply: if (!*p) | ||
11450 | break; | ||
11451 | if (*p != ',') | ||
11452 | goto getop; | ||
11453 | ++p; | ||
11454 | } | ||
11455 | set->cmd = 0; | ||
11456 | #ifdef SETMODE_DEBUG | ||
11457 | (void)printf("Before compress_mode()\n"); | ||
11458 | dumpmode(saveset); | ||
11459 | #endif | ||
11460 | compress_mode(saveset); | ||
11461 | #ifdef SETMODE_DEBUG | ||
11462 | (void)printf("After compress_mode()\n"); | ||
11463 | dumpmode(saveset); | ||
11464 | #endif | ||
11465 | return (saveset); | ||
11466 | } | ||
11467 | |||
11468 | static BITCMD * | ||
11469 | addcmd(set, op, who, oparg, mask) | ||
11470 | BITCMD *set; | ||
11471 | int oparg, who; | ||
11472 | int op; | ||
11473 | u_int mask; | ||
11474 | { | ||
11475 | |||
11476 | _DIAGASSERT(set != NULL); | ||
11477 | |||
11478 | switch (op) { | ||
11479 | case '=': | ||
11480 | set->cmd = '-'; | ||
11481 | set->bits = who ? who : STANDARD_BITS; | ||
11482 | set++; | ||
11483 | |||
11484 | op = '+'; | ||
11485 | /* FALLTHROUGH */ | ||
11486 | case '+': | ||
11487 | case '-': | ||
11488 | case 'X': | ||
11489 | set->cmd = op; | ||
11490 | set->bits = (who ? who : mask) & oparg; | ||
11491 | break; | ||
11492 | |||
11493 | case 'u': | ||
11494 | case 'g': | ||
11495 | case 'o': | ||
11496 | set->cmd = op; | ||
11497 | if (who) { | ||
11498 | set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) | | ||
11499 | ((who & S_IRGRP) ? CMD2_GBITS : 0) | | ||
11500 | ((who & S_IROTH) ? CMD2_OBITS : 0); | ||
11501 | set->bits = (mode_t)~0; | ||
11502 | } else { | ||
11503 | set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS; | ||
11504 | set->bits = mask; | ||
11505 | } | ||
11506 | |||
11507 | if (oparg == '+') | ||
11508 | set->cmd2 |= CMD2_SET; | ||
11509 | else if (oparg == '-') | ||
11510 | set->cmd2 |= CMD2_CLR; | ||
11511 | else if (oparg == '=') | ||
11512 | set->cmd2 |= CMD2_SET|CMD2_CLR; | ||
11513 | break; | ||
11514 | } | ||
11515 | return (set + 1); | ||
11516 | } | ||
11517 | |||
11518 | #ifdef SETMODE_DEBUG | ||
11519 | static void | ||
11520 | dumpmode(set) | ||
11521 | BITCMD *set; | ||
11522 | { | ||
11523 | |||
11524 | _DIAGASSERT(set != NULL); | ||
11525 | |||
11526 | for (; set->cmd; ++set) | ||
11527 | (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", | ||
11528 | set->cmd, set->bits, set->cmd2 ? " cmd2:" : "", | ||
11529 | set->cmd2 & CMD2_CLR ? " CLR" : "", | ||
11530 | set->cmd2 & CMD2_SET ? " SET" : "", | ||
11531 | set->cmd2 & CMD2_UBITS ? " UBITS" : "", | ||
11532 | set->cmd2 & CMD2_GBITS ? " GBITS" : "", | ||
11533 | set->cmd2 & CMD2_OBITS ? " OBITS" : ""); | ||
11534 | } | ||
11535 | #endif | ||
11536 | |||
11537 | /* | ||
11538 | * Given an array of bitcmd structures, compress by compacting consecutive | ||
11539 | * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u', | ||
11540 | * 'g' and 'o' commands continue to be separate. They could probably be | ||
11541 | * compacted, but it's not worth the effort. | ||
11542 | */ | ||
11543 | static void | ||
11544 | compress_mode(set) | ||
11545 | BITCMD *set; | ||
11546 | { | ||
11547 | BITCMD *nset; | ||
11548 | int setbits, clrbits, Xbits, op; | ||
11549 | |||
11550 | _DIAGASSERT(set != NULL); | ||
11551 | |||
11552 | for (nset = set;;) { | ||
11553 | /* Copy over any 'u', 'g' and 'o' commands. */ | ||
11554 | while ((op = nset->cmd) != '+' && op != '-' && op != 'X') { | ||
11555 | *set++ = *nset++; | ||
11556 | if (!op) | ||
11557 | return; | ||
11558 | } | ||
11559 | |||
11560 | for (setbits = clrbits = Xbits = 0;; nset++) { | ||
11561 | if ((op = nset->cmd) == '-') { | ||
11562 | clrbits |= nset->bits; | ||
11563 | setbits &= ~nset->bits; | ||
11564 | Xbits &= ~nset->bits; | ||
11565 | } else if (op == '+') { | ||
11566 | setbits |= nset->bits; | ||
11567 | clrbits &= ~nset->bits; | ||
11568 | Xbits &= ~nset->bits; | ||
11569 | } else if (op == 'X') | ||
11570 | Xbits |= nset->bits & ~setbits; | ||
11571 | else | ||
11572 | break; | ||
11573 | } | ||
11574 | if (clrbits) { | ||
11575 | set->cmd = '-'; | ||
11576 | set->cmd2 = 0; | ||
11577 | set->bits = clrbits; | ||
11578 | set++; | ||
11579 | } | ||
11580 | if (setbits) { | ||
11581 | set->cmd = '+'; | ||
11582 | set->cmd2 = 0; | ||
11583 | set->bits = setbits; | ||
11584 | set++; | ||
11585 | } | ||
11586 | if (Xbits) { | ||
11587 | set->cmd = 'X'; | ||
11588 | set->cmd2 = 0; | ||
11589 | set->bits = Xbits; | ||
11590 | set++; | ||
11591 | } | ||
11592 | } | ||
11593 | } | ||
11594 | #ifdef DEBUG | 11476 | #ifdef DEBUG |
11595 | static void shtree (union node *, int, char *, FILE*); | 11477 | static void shtree (union node *, int, char *, FILE*); |
11596 | static void shcmd (union node *, FILE *); | 11478 | static void shcmd (union node *, FILE *); |
@@ -11683,6 +11565,16 @@ shcmd(cmd, fp) | |||
11683 | for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { | 11565 | for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { |
11684 | if (! first) | 11566 | if (! first) |
11685 | putchar(' '); | 11567 | putchar(' '); |
11568 | #if 1 | ||
11569 | s = "*error*"; | ||
11570 | dftfd = 0; | ||
11571 | if ((np->nfile.type <= NFROMFD) && (np->nfile.type >= NTO)) { | ||
11572 | s = redir_strings[np->nfile.type - NTO]; | ||
11573 | if (*s == '>') { | ||
11574 | dftfd = 1; | ||
11575 | } | ||
11576 | } | ||
11577 | #else | ||
11686 | switch (np->nfile.type) { | 11578 | switch (np->nfile.type) { |
11687 | case NTO: s = ">"; dftfd = 1; break; | 11579 | case NTO: s = ">"; dftfd = 1; break; |
11688 | case NAPPEND: s = ">>"; dftfd = 1; break; | 11580 | case NAPPEND: s = ">>"; dftfd = 1; break; |
@@ -11693,6 +11585,7 @@ shcmd(cmd, fp) | |||
11693 | case NFROMTO: s = "<>"; dftfd = 0; break; | 11585 | case NFROMTO: s = "<>"; dftfd = 0; break; |
11694 | default: s = "*error*"; dftfd = 0; break; | 11586 | default: s = "*error*"; dftfd = 0; break; |
11695 | } | 11587 | } |
11588 | #endif | ||
11696 | if (np->nfile.fd != dftfd) | 11589 | if (np->nfile.fd != dftfd) |
11697 | fprintf(fp, "%d", np->nfile.fd); | 11590 | fprintf(fp, "%d", np->nfile.fd); |
11698 | fputs(s, fp); | 11591 | fputs(s, fp); |
@@ -12094,16 +11987,8 @@ setsignal(int signo) | |||
12094 | } | 11987 | } |
12095 | if (*t == S_HARD_IGN || *t == action) | 11988 | if (*t == S_HARD_IGN || *t == action) |
12096 | return; | 11989 | return; |
12097 | switch (action) { | 11990 | act.sa_handler = ((action == S_CATCH) ? onsig |
12098 | case S_CATCH: | 11991 | : ((action == S_IGN) ? SIG_IGN : SIG_DFL)); |
12099 | act.sa_handler = onsig; | ||
12100 | break; | ||
12101 | case S_IGN: | ||
12102 | act.sa_handler = SIG_IGN; | ||
12103 | break; | ||
12104 | default: | ||
12105 | act.sa_handler = SIG_DFL; | ||
12106 | } | ||
12107 | *t = action; | 11992 | *t = action; |
12108 | act.sa_flags = 0; | 11993 | act.sa_flags = 0; |
12109 | sigemptyset(&act.sa_mask); | 11994 | sigemptyset(&act.sa_mask); |
@@ -12785,7 +12670,7 @@ findvar(struct var **vpp, const char *name) | |||
12785 | /* | 12670 | /* |
12786 | * Copyright (c) 1999 Herbert Xu <herbert@debian.org> | 12671 | * Copyright (c) 1999 Herbert Xu <herbert@debian.org> |
12787 | * This file contains code for the times builtin. | 12672 | * This file contains code for the times builtin. |
12788 | * $Id: ash.c,v 1.19 2001/08/10 18:42:04 andersen Exp $ | 12673 | * $Id: ash.c,v 1.20 2001/08/10 19:36:07 mjn3 Exp $ |
12789 | */ | 12674 | */ |
12790 | static int timescmd (int argc, char **argv) | 12675 | static int timescmd (int argc, char **argv) |
12791 | { | 12676 | { |
diff --git a/shell/ash.c b/shell/ash.c index 91b6241c6..bbde91cd1 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -58,7 +58,7 @@ | |||
58 | /* Getopts is used by shell procedures to parse positional parameters. | 58 | /* Getopts is used by shell procedures to parse positional parameters. |
59 | * You probably want to leave this disabled, and use the busybox getopt | 59 | * You probably want to leave this disabled, and use the busybox getopt |
60 | * applet if you want to do this sort of thing. There are some scripts | 60 | * applet if you want to do this sort of thing. There are some scripts |
61 | * out there that use it, so if you need it, enable it. Most people will | 61 | * out there that use it, so it you need it, enable. Most people will |
62 | * leave this disabled. This adds 1k on an x86 system. */ | 62 | * leave this disabled. This adds 1k on an x86 system. */ |
63 | #undef ASH_GETOPTS | 63 | #undef ASH_GETOPTS |
64 | 64 | ||
@@ -81,6 +81,7 @@ | |||
81 | #undef GLOB_BROKEN | 81 | #undef GLOB_BROKEN |
82 | 82 | ||
83 | #include <assert.h> | 83 | #include <assert.h> |
84 | #include <stddef.h> | ||
84 | #include <ctype.h> | 85 | #include <ctype.h> |
85 | #include <dirent.h> | 86 | #include <dirent.h> |
86 | #include <errno.h> | 87 | #include <errno.h> |
@@ -142,13 +143,6 @@ | |||
142 | #define CSPCL 13 /* these terminate a word */ | 143 | #define CSPCL 13 /* these terminate a word */ |
143 | #define CIGN 14 /* character should be ignored */ | 144 | #define CIGN 14 /* character should be ignored */ |
144 | 145 | ||
145 | /* Syntax classes for is_ functions */ | ||
146 | #define ISDIGIT 01 /* a digit */ | ||
147 | #define ISUPPER 02 /* an upper case letter */ | ||
148 | #define ISLOWER 04 /* a lower case letter */ | ||
149 | #define ISUNDER 010 /* an underscore */ | ||
150 | #define ISSPECL 020 /* the name of a special parameter */ | ||
151 | |||
152 | #define SYNBASE 130 | 146 | #define SYNBASE 130 |
153 | #define PEOF -130 | 147 | #define PEOF -130 |
154 | 148 | ||
@@ -156,18 +150,18 @@ | |||
156 | 150 | ||
157 | #define TEOF 0 | 151 | #define TEOF 0 |
158 | #define TNL 1 | 152 | #define TNL 1 |
159 | #define TSEMI 2 | 153 | #define TREDIR 2 |
160 | #define TBACKGND 3 | 154 | #define TWORD 3 |
161 | #define TAND 4 | 155 | #define TASSIGN 4 |
162 | #define TOR 5 | 156 | #define TSEMI 5 |
163 | #define TPIPE 6 | 157 | #define TBACKGND 6 |
164 | #define TLP 7 | 158 | #define TAND 7 |
165 | #define TRP 8 | 159 | #define TOR 8 |
166 | #define TENDCASE 9 | 160 | #define TPIPE 9 |
167 | #define TENDBQUOTE 10 | 161 | #define TLP 10 |
168 | #define TREDIR 11 | 162 | #define TRP 11 |
169 | #define TWORD 12 | 163 | #define TENDCASE 12 |
170 | #define TASSIGN 13 | 164 | #define TENDBQUOTE 13 |
171 | #define TNOT 14 | 165 | #define TNOT 14 |
172 | #define TCASE 15 | 166 | #define TCASE 15 |
173 | #define TDO 16 | 167 | #define TDO 16 |
@@ -186,10 +180,6 @@ | |||
186 | #define TEND 29 | 180 | #define TEND 29 |
187 | 181 | ||
188 | 182 | ||
189 | #define BASESYNTAX (basesyntax + SYNBASE) | ||
190 | #define DQSYNTAX (dqsyntax + SYNBASE) | ||
191 | #define SQSYNTAX (sqsyntax + SYNBASE) | ||
192 | #define ARISYNTAX (arisyntax + SYNBASE) | ||
193 | 183 | ||
194 | /* control characters in argument strings */ | 184 | /* control characters in argument strings */ |
195 | #define CTLESC '\201' | 185 | #define CTLESC '\201' |
@@ -202,11 +192,19 @@ | |||
202 | #define CTLENDARI '\207' | 192 | #define CTLENDARI '\207' |
203 | #define CTLQUOTEMARK '\210' | 193 | #define CTLQUOTEMARK '\210' |
204 | 194 | ||
195 | |||
205 | #define is_digit(c) ((c)>='0' && (c)<='9') | 196 | #define is_digit(c) ((c)>='0' && (c)<='9') |
206 | #define is_alpha(c) (((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c))) | ||
207 | #define is_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c)))) | 197 | #define is_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c)))) |
208 | #define is_in_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c)))) | 198 | #define is_in_name(c) (((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c)))) |
209 | #define is_special(c) ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT)) | 199 | |
200 | /* | ||
201 | * is_special(c) evaluates to 1 for c in "!#$*-0123456789?@"; 0 otherwise | ||
202 | * (assuming ascii char codes, as the original implementation did) | ||
203 | */ | ||
204 | #define is_special(c) \ | ||
205 | ( (((unsigned int)c) - 33 < 32) \ | ||
206 | && ((0xc1ff920dUL >> (((unsigned int)c) - 33)) & 1)) | ||
207 | |||
210 | #define digit_val(c) ((c) - '0') | 208 | #define digit_val(c) ((c) - '0') |
211 | 209 | ||
212 | 210 | ||
@@ -688,6 +686,7 @@ static void out2fmt (const char *, ...) | |||
688 | static int xwrite (int, const char *, int); | 686 | static int xwrite (int, const char *, int); |
689 | 687 | ||
690 | #define outstr(p,file) fputs(p, file) | 688 | #define outstr(p,file) fputs(p, file) |
689 | static void outstr (const char *p, FILE *file) { fputs(p, file); } | ||
691 | static void out1str(const char *p) { outstr(p, stdout); } | 690 | static void out1str(const char *p) { outstr(p, stdout); } |
692 | static void out2str(const char *p) { outstr(p, stderr); } | 691 | static void out2str(const char *p) { outstr(p, stderr); } |
693 | 692 | ||
@@ -697,439 +696,398 @@ static void out2str(const char *p) { outstr(p, stderr); } | |||
697 | static void out2c(int c) { putc(c, stderr); } | 696 | static void out2c(int c) { putc(c, stderr); } |
698 | #endif | 697 | #endif |
699 | 698 | ||
700 | /* syntax table used when not in quotes */ | ||
701 | static const char basesyntax[257] = { | ||
702 | CENDFILE, CSPCL, CWORD, CCTL, | ||
703 | CCTL, CCTL, CCTL, CCTL, | ||
704 | CCTL, CCTL, CCTL, CWORD, | ||
705 | CWORD, CWORD, CWORD, CWORD, | ||
706 | CWORD, CWORD, CWORD, CWORD, | ||
707 | CWORD, CWORD, CWORD, CWORD, | ||
708 | CWORD, CWORD, CWORD, CWORD, | ||
709 | CWORD, CWORD, CWORD, CWORD, | ||
710 | CWORD, CWORD, CWORD, CWORD, | ||
711 | CWORD, CWORD, CWORD, CWORD, | ||
712 | CWORD, CWORD, CWORD, CWORD, | ||
713 | CWORD, CWORD, CWORD, CWORD, | ||
714 | CWORD, CWORD, CWORD, CWORD, | ||
715 | CWORD, CWORD, CWORD, CWORD, | ||
716 | CWORD, CWORD, CWORD, CWORD, | ||
717 | CWORD, CWORD, CWORD, CWORD, | ||
718 | CWORD, CWORD, CWORD, CWORD, | ||
719 | CWORD, CWORD, CWORD, CWORD, | ||
720 | CWORD, CWORD, CWORD, CWORD, | ||
721 | CWORD, CWORD, CWORD, CWORD, | ||
722 | CWORD, CWORD, CWORD, CWORD, | ||
723 | CWORD, CWORD, CWORD, CWORD, | ||
724 | CWORD, CWORD, CWORD, CWORD, | ||
725 | CWORD, CWORD, CWORD, CWORD, | ||
726 | CWORD, CWORD, CWORD, CWORD, | ||
727 | CWORD, CWORD, CWORD, CWORD, | ||
728 | CWORD, CWORD, CWORD, CWORD, | ||
729 | CWORD, CWORD, CWORD, CWORD, | ||
730 | CWORD, CWORD, CWORD, CWORD, | ||
731 | CWORD, CWORD, CWORD, CWORD, | ||
732 | CWORD, CWORD, CWORD, CWORD, | ||
733 | CWORD, CWORD, CWORD, CWORD, | ||
734 | CWORD, CWORD, CWORD, CWORD, | ||
735 | CWORD, CWORD, CWORD, CWORD, | ||
736 | CWORD, CWORD, CWORD, CSPCL, | ||
737 | CNL, CWORD, CWORD, CWORD, | ||
738 | CWORD, CWORD, CWORD, CWORD, | ||
739 | CWORD, CWORD, CWORD, CWORD, | ||
740 | CWORD, CWORD, CWORD, CWORD, | ||
741 | CWORD, CWORD, CWORD, CWORD, | ||
742 | CWORD, CWORD, CSPCL, CWORD, | ||
743 | CDQUOTE, CWORD, CVAR, CWORD, | ||
744 | CSPCL, CSQUOTE, CSPCL, CSPCL, | ||
745 | CWORD, CWORD, CWORD, CWORD, | ||
746 | CWORD, CWORD, CWORD, CWORD, | ||
747 | CWORD, CWORD, CWORD, CWORD, | ||
748 | CWORD, CWORD, CWORD, CWORD, | ||
749 | CWORD, CSPCL, CSPCL, CWORD, | ||
750 | CSPCL, CWORD, CWORD, CWORD, | ||
751 | CWORD, CWORD, CWORD, CWORD, | ||
752 | CWORD, CWORD, CWORD, CWORD, | ||
753 | CWORD, CWORD, CWORD, CWORD, | ||
754 | CWORD, CWORD, CWORD, CWORD, | ||
755 | CWORD, CWORD, CWORD, CWORD, | ||
756 | CWORD, CWORD, CWORD, CWORD, | ||
757 | CWORD, CWORD, CBACK, CWORD, | ||
758 | CWORD, CWORD, CBQUOTE, CWORD, | ||
759 | CWORD, CWORD, CWORD, CWORD, | ||
760 | CWORD, CWORD, CWORD, CWORD, | ||
761 | CWORD, CWORD, CWORD, CWORD, | ||
762 | CWORD, CWORD, CWORD, CWORD, | ||
763 | CWORD, CWORD, CWORD, CWORD, | ||
764 | CWORD, CWORD, CWORD, CWORD, | ||
765 | CWORD, CWORD, CSPCL, CENDVAR, | ||
766 | CWORD | ||
767 | }; | ||
768 | |||
769 | /* syntax table used when in double quotes */ | ||
770 | static const char dqsyntax[257] = { | ||
771 | CENDFILE, CIGN, CWORD, CCTL, | ||
772 | CCTL, CCTL, CCTL, CCTL, | ||
773 | CCTL, CCTL, CCTL, CWORD, | ||
774 | CWORD, CWORD, CWORD, CWORD, | ||
775 | CWORD, CWORD, CWORD, CWORD, | ||
776 | CWORD, CWORD, CWORD, CWORD, | ||
777 | CWORD, CWORD, CWORD, CWORD, | ||
778 | CWORD, CWORD, CWORD, CWORD, | ||
779 | CWORD, CWORD, CWORD, CWORD, | ||
780 | CWORD, CWORD, CWORD, CWORD, | ||
781 | CWORD, CWORD, CWORD, CWORD, | ||
782 | CWORD, CWORD, CWORD, CWORD, | ||
783 | CWORD, CWORD, CWORD, CWORD, | ||
784 | CWORD, CWORD, CWORD, CWORD, | ||
785 | CWORD, CWORD, CWORD, CWORD, | ||
786 | CWORD, CWORD, CWORD, CWORD, | ||
787 | CWORD, CWORD, CWORD, CWORD, | ||
788 | CWORD, CWORD, CWORD, CWORD, | ||
789 | CWORD, CWORD, CWORD, CWORD, | ||
790 | CWORD, CWORD, CWORD, CWORD, | ||
791 | CWORD, CWORD, CWORD, CWORD, | ||
792 | CWORD, CWORD, CWORD, CWORD, | ||
793 | CWORD, CWORD, CWORD, CWORD, | ||
794 | CWORD, CWORD, CWORD, CWORD, | ||
795 | CWORD, CWORD, CWORD, CWORD, | ||
796 | CWORD, CWORD, CWORD, CWORD, | ||
797 | CWORD, CWORD, CWORD, CWORD, | ||
798 | CWORD, CWORD, CWORD, CWORD, | ||
799 | CWORD, CWORD, CWORD, CWORD, | ||
800 | CWORD, CWORD, CWORD, CWORD, | ||
801 | CWORD, CWORD, CWORD, CWORD, | ||
802 | CWORD, CWORD, CWORD, CWORD, | ||
803 | CWORD, CWORD, CWORD, CWORD, | ||
804 | CWORD, CWORD, CWORD, CWORD, | ||
805 | CWORD, CWORD, CWORD, CWORD, | ||
806 | CNL, CWORD, CWORD, CWORD, | ||
807 | CWORD, CWORD, CWORD, CWORD, | ||
808 | CWORD, CWORD, CWORD, CWORD, | ||
809 | CWORD, CWORD, CWORD, CWORD, | ||
810 | CWORD, CWORD, CWORD, CWORD, | ||
811 | CWORD, CWORD, CWORD, CCTL, | ||
812 | CENDQUOTE,CWORD, CVAR, CWORD, | ||
813 | CWORD, CWORD, CWORD, CWORD, | ||
814 | CCTL, CWORD, CWORD, CCTL, | ||
815 | CWORD, CCTL, CWORD, CWORD, | ||
816 | CWORD, CWORD, CWORD, CWORD, | ||
817 | CWORD, CWORD, CWORD, CWORD, | ||
818 | CCTL, CWORD, CWORD, CCTL, | ||
819 | CWORD, CCTL, CWORD, CWORD, | ||
820 | CWORD, CWORD, CWORD, CWORD, | ||
821 | CWORD, CWORD, CWORD, CWORD, | ||
822 | CWORD, CWORD, CWORD, CWORD, | ||
823 | CWORD, CWORD, CWORD, CWORD, | ||
824 | CWORD, CWORD, CWORD, CWORD, | ||
825 | CWORD, CWORD, CWORD, CWORD, | ||
826 | CWORD, CCTL, CBACK, CCTL, | ||
827 | CWORD, CWORD, CBQUOTE, CWORD, | ||
828 | CWORD, CWORD, CWORD, CWORD, | ||
829 | CWORD, CWORD, CWORD, CWORD, | ||
830 | CWORD, CWORD, CWORD, CWORD, | ||
831 | CWORD, CWORD, CWORD, CWORD, | ||
832 | CWORD, CWORD, CWORD, CWORD, | ||
833 | CWORD, CWORD, CWORD, CWORD, | ||
834 | CWORD, CWORD, CWORD, CENDVAR, | ||
835 | CCTL | ||
836 | }; | ||
837 | 699 | ||
838 | /* syntax table used when in single quotes */ | 700 | #ifdef ASH_OPTIMIZE_FOR_SIZE |
839 | static const char sqsyntax[257] = { | 701 | #define USE_SIT_FUNCTION |
840 | CENDFILE, CIGN, CWORD, CCTL, | 702 | #endif |
841 | CCTL, CCTL, CCTL, CCTL, | 703 | |
842 | CCTL, CCTL, CCTL, CWORD, | 704 | /* number syntax index */ |
843 | CWORD, CWORD, CWORD, CWORD, | 705 | #define BASESYNTAX 0 /* not in quotes */ |
844 | CWORD, CWORD, CWORD, CWORD, | 706 | #define DQSYNTAX 1 /* in double quotes */ |
845 | CWORD, CWORD, CWORD, CWORD, | 707 | #define SQSYNTAX 2 /* in single quotes */ |
846 | CWORD, CWORD, CWORD, CWORD, | 708 | #define ARISYNTAX 3 /* in arithmetic */ |
847 | CWORD, CWORD, CWORD, CWORD, | 709 | |
848 | CWORD, CWORD, CWORD, CWORD, | 710 | static const char S_I_T[][4] = { |
849 | CWORD, CWORD, CWORD, CWORD, | 711 | /* 0 */ { CSPCL, CIGN, CIGN, CIGN }, /* PEOA */ |
850 | CWORD, CWORD, CWORD, CWORD, | 712 | /* 1 */ { CSPCL, CWORD, CWORD, CWORD }, /* ' ' */ |
851 | CWORD, CWORD, CWORD, CWORD, | 713 | /* 2 */ { CNL, CNL, CNL, CNL }, /* \n */ |
852 | CWORD, CWORD, CWORD, CWORD, | 714 | /* 3 */ { CWORD, CCTL, CCTL, CWORD }, /* !*-/:=?[]~ */ |
853 | CWORD, CWORD, CWORD, CWORD, | 715 | /* 4 */ { CDQUOTE, CENDQUOTE, CWORD, CDQUOTE }, /* '"' */ |
854 | CWORD, CWORD, CWORD, CWORD, | 716 | /* 5 */ { CVAR, CVAR, CWORD, CVAR }, /* $ */ |
855 | CWORD, CWORD, CWORD, CWORD, | 717 | /* 6 */ { CSQUOTE, CWORD, CENDQUOTE, CSQUOTE }, /* "'" */ |
856 | CWORD, CWORD, CWORD, CWORD, | 718 | /* 7 */ { CSPCL, CWORD, CWORD, CLP }, /* ( */ |
857 | CWORD, CWORD, CWORD, CWORD, | 719 | /* 8 */ { CSPCL, CWORD, CWORD, CRP }, /* ) */ |
858 | CWORD, CWORD, CWORD, CWORD, | 720 | /* 9 */ { CBACK, CBACK, CCTL, CBACK }, /* \ */ |
859 | CWORD, CWORD, CWORD, CWORD, | 721 | /* 10 */ { CBQUOTE, CBQUOTE, CWORD, CBQUOTE }, /* ` */ |
860 | CWORD, CWORD, CWORD, CWORD, | 722 | /* 11 */ { CENDVAR, CENDVAR, CWORD, CENDVAR }, /* } */ |
861 | CWORD, CWORD, CWORD, CWORD, | 723 | #ifndef USE_SIT_FUNCTION |
862 | CWORD, CWORD, CWORD, CWORD, | 724 | /* 12 */ { CENDFILE, CENDFILE, CENDFILE, CENDFILE }, /* PEOF */ |
863 | CWORD, CWORD, CWORD, CWORD, | 725 | /* 13 */ { CWORD, CWORD, CWORD, CWORD }, /* 0-9A-Za-z */ |
864 | CWORD, CWORD, CWORD, CWORD, | 726 | /* 14 */ { CCTL, CCTL, CCTL, CCTL } /* CTLESC ... */ |
865 | CWORD, CWORD, CWORD, CWORD, | 727 | #endif |
866 | CWORD, CWORD, CWORD, CWORD, | ||
867 | CWORD, CWORD, CWORD, CWORD, | ||
868 | CWORD, CWORD, CWORD, CWORD, | ||
869 | CWORD, CWORD, CWORD, CWORD, | ||
870 | CWORD, CWORD, CWORD, CWORD, | ||
871 | CWORD, CWORD, CWORD, CWORD, | ||
872 | CWORD, CWORD, CWORD, CWORD, | ||
873 | CWORD, CWORD, CWORD, CWORD, | ||
874 | CWORD, CWORD, CWORD, CWORD, | ||
875 | CNL, CWORD, CWORD, CWORD, | ||
876 | CWORD, CWORD, CWORD, CWORD, | ||
877 | CWORD, CWORD, CWORD, CWORD, | ||
878 | CWORD, CWORD, CWORD, CWORD, | ||
879 | CWORD, CWORD, CWORD, CWORD, | ||
880 | CWORD, CWORD, CWORD, CCTL, | ||
881 | CWORD, CWORD, CWORD, CWORD, | ||
882 | CWORD, CENDQUOTE,CWORD, CWORD, | ||
883 | CCTL, CWORD, CWORD, CCTL, | ||
884 | CWORD, CCTL, CWORD, CWORD, | ||
885 | CWORD, CWORD, CWORD, CWORD, | ||
886 | CWORD, CWORD, CWORD, CWORD, | ||
887 | CCTL, CWORD, CWORD, CCTL, | ||
888 | CWORD, CCTL, CWORD, CWORD, | ||
889 | CWORD, CWORD, CWORD, CWORD, | ||
890 | CWORD, CWORD, CWORD, CWORD, | ||
891 | CWORD, CWORD, CWORD, CWORD, | ||
892 | CWORD, CWORD, CWORD, CWORD, | ||
893 | CWORD, CWORD, CWORD, CWORD, | ||
894 | CWORD, CWORD, CWORD, CWORD, | ||
895 | CWORD, CCTL, CCTL, CCTL, | ||
896 | CWORD, CWORD, CWORD, CWORD, | ||
897 | CWORD, CWORD, CWORD, CWORD, | ||
898 | CWORD, CWORD, CWORD, CWORD, | ||
899 | CWORD, CWORD, CWORD, CWORD, | ||
900 | CWORD, CWORD, CWORD, CWORD, | ||
901 | CWORD, CWORD, CWORD, CWORD, | ||
902 | CWORD, CWORD, CWORD, CWORD, | ||
903 | CWORD, CWORD, CWORD, CWORD, | ||
904 | CCTL | ||
905 | }; | ||
906 | |||
907 | /* syntax table used when in arithmetic */ | ||
908 | static const char arisyntax[257] = { | ||
909 | CENDFILE, CIGN, CWORD, CCTL, | ||
910 | CCTL, CCTL, CCTL, CCTL, | ||
911 | CCTL, CCTL, CCTL, CWORD, | ||
912 | CWORD, CWORD, CWORD, CWORD, | ||
913 | CWORD, CWORD, CWORD, CWORD, | ||
914 | CWORD, CWORD, CWORD, CWORD, | ||
915 | CWORD, CWORD, CWORD, CWORD, | ||
916 | CWORD, CWORD, CWORD, CWORD, | ||
917 | CWORD, CWORD, CWORD, CWORD, | ||
918 | CWORD, CWORD, CWORD, CWORD, | ||
919 | CWORD, CWORD, CWORD, CWORD, | ||
920 | CWORD, CWORD, CWORD, CWORD, | ||
921 | CWORD, CWORD, CWORD, CWORD, | ||
922 | CWORD, CWORD, CWORD, CWORD, | ||
923 | CWORD, CWORD, CWORD, CWORD, | ||
924 | CWORD, CWORD, CWORD, CWORD, | ||
925 | CWORD, CWORD, CWORD, CWORD, | ||
926 | CWORD, CWORD, CWORD, CWORD, | ||
927 | CWORD, CWORD, CWORD, CWORD, | ||
928 | CWORD, CWORD, CWORD, CWORD, | ||
929 | CWORD, CWORD, CWORD, CWORD, | ||
930 | CWORD, CWORD, CWORD, CWORD, | ||
931 | CWORD, CWORD, CWORD, CWORD, | ||
932 | CWORD, CWORD, CWORD, CWORD, | ||
933 | CWORD, CWORD, CWORD, CWORD, | ||
934 | CWORD, CWORD, CWORD, CWORD, | ||
935 | CWORD, CWORD, CWORD, CWORD, | ||
936 | CWORD, CWORD, CWORD, CWORD, | ||
937 | CWORD, CWORD, CWORD, CWORD, | ||
938 | CWORD, CWORD, CWORD, CWORD, | ||
939 | CWORD, CWORD, CWORD, CWORD, | ||
940 | CWORD, CWORD, CWORD, CWORD, | ||
941 | CWORD, CWORD, CWORD, CWORD, | ||
942 | CWORD, CWORD, CWORD, CWORD, | ||
943 | CWORD, CWORD, CWORD, CWORD, | ||
944 | CNL, CWORD, CWORD, CWORD, | ||
945 | CWORD, CWORD, CWORD, CWORD, | ||
946 | CWORD, CWORD, CWORD, CWORD, | ||
947 | CWORD, CWORD, CWORD, CWORD, | ||
948 | CWORD, CWORD, CWORD, CWORD, | ||
949 | CWORD, CWORD, CWORD, CWORD, | ||
950 | CDQUOTE, CWORD, CVAR, CWORD, | ||
951 | CWORD, CSQUOTE, CLP, CRP, | ||
952 | CWORD, CWORD, CWORD, CWORD, | ||
953 | CWORD, CWORD, CWORD, CWORD, | ||
954 | CWORD, CWORD, CWORD, CWORD, | ||
955 | CWORD, CWORD, CWORD, CWORD, | ||
956 | CWORD, CWORD, CWORD, CWORD, | ||
957 | CWORD, CWORD, CWORD, CWORD, | ||
958 | CWORD, CWORD, CWORD, CWORD, | ||
959 | CWORD, CWORD, CWORD, CWORD, | ||
960 | CWORD, CWORD, CWORD, CWORD, | ||
961 | CWORD, CWORD, CWORD, CWORD, | ||
962 | CWORD, CWORD, CWORD, CWORD, | ||
963 | CWORD, CWORD, CWORD, CWORD, | ||
964 | CWORD, CWORD, CBACK, CWORD, | ||
965 | CWORD, CWORD, CBQUOTE, CWORD, | ||
966 | CWORD, CWORD, CWORD, CWORD, | ||
967 | CWORD, CWORD, CWORD, CWORD, | ||
968 | CWORD, CWORD, CWORD, CWORD, | ||
969 | CWORD, CWORD, CWORD, CWORD, | ||
970 | CWORD, CWORD, CWORD, CWORD, | ||
971 | CWORD, CWORD, CWORD, CWORD, | ||
972 | CWORD, CWORD, CWORD, CENDVAR, | ||
973 | CWORD | ||
974 | }; | 728 | }; |
975 | 729 | ||
976 | /* character classification table */ | 730 | #ifdef USE_SIT_FUNCTION |
977 | static const char is_type[257] = { | ||
978 | 0, 0, 0, 0, | ||
979 | 0, 0, 0, 0, | ||
980 | 0, 0, 0, 0, | ||
981 | 0, 0, 0, 0, | ||
982 | 0, 0, 0, 0, | ||
983 | 0, 0, 0, 0, | ||
984 | 0, 0, 0, 0, | ||
985 | 0, 0, 0, 0, | ||
986 | 0, 0, 0, 0, | ||
987 | 0, 0, 0, 0, | ||
988 | 0, 0, 0, 0, | ||
989 | 0, 0, 0, 0, | ||
990 | 0, 0, 0, 0, | ||
991 | 0, 0, 0, 0, | ||
992 | 0, 0, 0, 0, | ||
993 | 0, 0, 0, 0, | ||
994 | 0, 0, 0, 0, | ||
995 | 0, 0, 0, 0, | ||
996 | 0, 0, 0, 0, | ||
997 | 0, 0, 0, 0, | ||
998 | 0, 0, 0, 0, | ||
999 | 0, 0, 0, 0, | ||
1000 | 0, 0, 0, 0, | ||
1001 | 0, 0, 0, 0, | ||
1002 | 0, 0, 0, 0, | ||
1003 | 0, 0, 0, 0, | ||
1004 | 0, 0, 0, 0, | ||
1005 | 0, 0, 0, 0, | ||
1006 | 0, 0, 0, 0, | ||
1007 | 0, 0, 0, 0, | ||
1008 | 0, 0, 0, 0, | ||
1009 | 0, 0, 0, 0, | ||
1010 | 0, 0, 0, 0, | ||
1011 | 0, 0, 0, 0, | ||
1012 | 0, 0, 0, 0, | ||
1013 | 0, 0, 0, 0, | ||
1014 | 0, 0, 0, 0, | ||
1015 | 0, 0, 0, 0, | ||
1016 | 0, 0, 0, 0, | ||
1017 | 0, 0, 0, 0, | ||
1018 | 0, 0, 0, ISSPECL, | ||
1019 | 0, ISSPECL, ISSPECL, 0, | ||
1020 | 0, 0, 0, 0, | ||
1021 | ISSPECL, 0, 0, ISSPECL, | ||
1022 | 0, 0, ISDIGIT, ISDIGIT, | ||
1023 | ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, | ||
1024 | ISDIGIT, ISDIGIT, ISDIGIT, ISDIGIT, | ||
1025 | 0, 0, 0, 0, | ||
1026 | 0, ISSPECL, ISSPECL, ISUPPER, | ||
1027 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1028 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1029 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1030 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1031 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1032 | ISUPPER, ISUPPER, ISUPPER, ISUPPER, | ||
1033 | ISUPPER, 0, 0, 0, | ||
1034 | 0, ISUNDER, 0, ISLOWER, | ||
1035 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1036 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1037 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1038 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1039 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1040 | ISLOWER, ISLOWER, ISLOWER, ISLOWER, | ||
1041 | ISLOWER, 0, 0, 0, | ||
1042 | 0 | ||
1043 | }; | ||
1044 | 731 | ||
1045 | /* Array indicating which tokens mark the end of a list */ | 732 | #define U_C(c) ((unsigned char)(c)) |
1046 | static const char tokendlist[] = { | ||
1047 | 1, | ||
1048 | 0, | ||
1049 | 0, | ||
1050 | 0, | ||
1051 | 0, | ||
1052 | 0, | ||
1053 | 0, | ||
1054 | 0, | ||
1055 | 1, | ||
1056 | 1, | ||
1057 | 1, | ||
1058 | 0, | ||
1059 | 0, | ||
1060 | 0, | ||
1061 | 0, | ||
1062 | 0, | ||
1063 | 1, | ||
1064 | 1, | ||
1065 | 1, | ||
1066 | 1, | ||
1067 | 1, | ||
1068 | 1, | ||
1069 | 0, | ||
1070 | 0, | ||
1071 | 0, | ||
1072 | 1, | ||
1073 | 0, | ||
1074 | 0, | ||
1075 | 0, | ||
1076 | 1, | ||
1077 | }; | ||
1078 | 733 | ||
1079 | static const char *const tokname[] = { | 734 | static int SIT(int c, int syntax) |
1080 | "end of file", | 735 | { |
1081 | "newline", | 736 | static const char spec_symbls[]="\t\n !\"$&'()*-/:;<=>?[\\]`|}~"; |
1082 | "\";\"", | 737 | static const char syntax_index_table [] = { |
1083 | "\"&\"", | 738 | 1, 2, 1, 3, 4, 5, 1, 6, /* "\t\n !\"$&'" */ |
1084 | "\"&&\"", | 739 | 7, 8, 3, 3, 3, 3, 1, 1, /* "()*-/:;<" */ |
1085 | "\"||\"", | 740 | 3, 1, 3, 3, 9, 3,10, 1, /* "=>?[\\]`|" */ |
1086 | "\"|\"", | 741 | 11,3 }; /* "}~" */ |
1087 | "\"(\"", | 742 | const char *s; |
1088 | "\")\"", | 743 | int indx; |
1089 | "\";;\"", | 744 | |
1090 | "\"`\"", | 745 | if(c==PEOF) /* 2^8+2 */ |
1091 | "redirection", | 746 | return CENDFILE; |
1092 | "word", | 747 | if(c==PEOA) /* 2^8+1 */ |
1093 | "assignment", | 748 | indx = 0; |
1094 | "\"!\"", | 749 | else if(U_C(c)>=U_C(CTLESC) && U_C(c)<=U_C(CTLQUOTEMARK)) |
1095 | "\"case\"", | 750 | return CCTL; |
1096 | "\"do\"", | 751 | else { |
1097 | "\"done\"", | 752 | s = strchr(spec_symbls, c); |
1098 | "\"elif\"", | 753 | if(s==0) |
1099 | "\"else\"", | 754 | return CWORD; |
1100 | "\"esac\"", | 755 | indx = syntax_index_table[(s-spec_symbls)]; |
1101 | "\"fi\"", | 756 | } |
1102 | "\"for\"", | 757 | return S_I_T[indx][syntax]; |
1103 | "\"if\"", | 758 | } |
1104 | "\"in\"", | 759 | |
1105 | "\"then\"", | 760 | #else /* USE_SIT_FUNCTION */ |
1106 | "\"until\"", | 761 | |
1107 | "\"while\"", | 762 | #define SIT(c, syntax) S_I_T[(int)syntax_index_table[((int)c)+SYNBASE]][syntax] |
1108 | "\"{\"", | 763 | |
1109 | "\"}\"", | 764 | #define CSPCL_CIGN_CIGN_CIGN 0 |
765 | #define CSPCL_CWORD_CWORD_CWORD 1 | ||
766 | #define CNL_CNL_CNL_CNL 2 | ||
767 | #define CWORD_CCTL_CCTL_CWORD 3 | ||
768 | #define CDQUOTE_CENDQUOTE_CWORD_CDQUOTE 4 | ||
769 | #define CVAR_CVAR_CWORD_CVAR 5 | ||
770 | #define CSQUOTE_CWORD_CENDQUOTE_CSQUOTE 6 | ||
771 | #define CSPCL_CWORD_CWORD_CLP 7 | ||
772 | #define CSPCL_CWORD_CWORD_CRP 8 | ||
773 | #define CBACK_CBACK_CCTL_CBACK 9 | ||
774 | #define CBQUOTE_CBQUOTE_CWORD_CBQUOTE 10 | ||
775 | #define CENDVAR_CENDVAR_CWORD_CENDVAR 11 | ||
776 | #define CENDFILE_CENDFILE_CENDFILE_CENDFILE 12 | ||
777 | #define CWORD_CWORD_CWORD_CWORD 13 | ||
778 | #define CCTL_CCTL_CCTL_CCTL 14 | ||
779 | |||
780 | static const char syntax_index_table[258] = { | ||
781 | /* BASESYNTAX_DQSYNTAX_SQSYNTAX_ARISYNTAX */ | ||
782 | /* 0 -130 PEOF */ CENDFILE_CENDFILE_CENDFILE_CENDFILE, | ||
783 | /* 1 -129 PEOA */ CSPCL_CIGN_CIGN_CIGN, | ||
784 | /* 2 -128 0xff */ CWORD_CWORD_CWORD_CWORD, | ||
785 | /* 3 -127 */ CCTL_CCTL_CCTL_CCTL, /* CTLQUOTEMARK */ | ||
786 | /* 4 -126 */ CCTL_CCTL_CCTL_CCTL, | ||
787 | /* 5 -125 */ CCTL_CCTL_CCTL_CCTL, | ||
788 | /* 6 -124 */ CCTL_CCTL_CCTL_CCTL, | ||
789 | /* 7 -123 */ CCTL_CCTL_CCTL_CCTL, | ||
790 | /* 8 -122 */ CCTL_CCTL_CCTL_CCTL, | ||
791 | /* 9 -121 */ CCTL_CCTL_CCTL_CCTL, | ||
792 | /* 10 -120 */ CCTL_CCTL_CCTL_CCTL, /* CTLESC */ | ||
793 | /* 11 -119 */ CWORD_CWORD_CWORD_CWORD, | ||
794 | /* 12 -118 */ CWORD_CWORD_CWORD_CWORD, | ||
795 | /* 13 -117 */ CWORD_CWORD_CWORD_CWORD, | ||
796 | /* 14 -116 */ CWORD_CWORD_CWORD_CWORD, | ||
797 | /* 15 -115 */ CWORD_CWORD_CWORD_CWORD, | ||
798 | /* 16 -114 */ CWORD_CWORD_CWORD_CWORD, | ||
799 | /* 17 -113 */ CWORD_CWORD_CWORD_CWORD, | ||
800 | /* 18 -112 */ CWORD_CWORD_CWORD_CWORD, | ||
801 | /* 19 -111 */ CWORD_CWORD_CWORD_CWORD, | ||
802 | /* 20 -110 */ CWORD_CWORD_CWORD_CWORD, | ||
803 | /* 21 -109 */ CWORD_CWORD_CWORD_CWORD, | ||
804 | /* 22 -108 */ CWORD_CWORD_CWORD_CWORD, | ||
805 | /* 23 -107 */ CWORD_CWORD_CWORD_CWORD, | ||
806 | /* 24 -106 */ CWORD_CWORD_CWORD_CWORD, | ||
807 | /* 25 -105 */ CWORD_CWORD_CWORD_CWORD, | ||
808 | /* 26 -104 */ CWORD_CWORD_CWORD_CWORD, | ||
809 | /* 27 -103 */ CWORD_CWORD_CWORD_CWORD, | ||
810 | /* 28 -102 */ CWORD_CWORD_CWORD_CWORD, | ||
811 | /* 29 -101 */ CWORD_CWORD_CWORD_CWORD, | ||
812 | /* 30 -100 */ CWORD_CWORD_CWORD_CWORD, | ||
813 | /* 31 -99 */ CWORD_CWORD_CWORD_CWORD, | ||
814 | /* 32 -98 */ CWORD_CWORD_CWORD_CWORD, | ||
815 | /* 33 -97 */ CWORD_CWORD_CWORD_CWORD, | ||
816 | /* 34 -96 */ CWORD_CWORD_CWORD_CWORD, | ||
817 | /* 35 -95 */ CWORD_CWORD_CWORD_CWORD, | ||
818 | /* 36 -94 */ CWORD_CWORD_CWORD_CWORD, | ||
819 | /* 37 -93 */ CWORD_CWORD_CWORD_CWORD, | ||
820 | /* 38 -92 */ CWORD_CWORD_CWORD_CWORD, | ||
821 | /* 39 -91 */ CWORD_CWORD_CWORD_CWORD, | ||
822 | /* 40 -90 */ CWORD_CWORD_CWORD_CWORD, | ||
823 | /* 41 -89 */ CWORD_CWORD_CWORD_CWORD, | ||
824 | /* 42 -88 */ CWORD_CWORD_CWORD_CWORD, | ||
825 | /* 43 -87 */ CWORD_CWORD_CWORD_CWORD, | ||
826 | /* 44 -86 */ CWORD_CWORD_CWORD_CWORD, | ||
827 | /* 45 -85 */ CWORD_CWORD_CWORD_CWORD, | ||
828 | /* 46 -84 */ CWORD_CWORD_CWORD_CWORD, | ||
829 | /* 47 -83 */ CWORD_CWORD_CWORD_CWORD, | ||
830 | /* 48 -82 */ CWORD_CWORD_CWORD_CWORD, | ||
831 | /* 49 -81 */ CWORD_CWORD_CWORD_CWORD, | ||
832 | /* 50 -80 */ CWORD_CWORD_CWORD_CWORD, | ||
833 | /* 51 -79 */ CWORD_CWORD_CWORD_CWORD, | ||
834 | /* 52 -78 */ CWORD_CWORD_CWORD_CWORD, | ||
835 | /* 53 -77 */ CWORD_CWORD_CWORD_CWORD, | ||
836 | /* 54 -76 */ CWORD_CWORD_CWORD_CWORD, | ||
837 | /* 55 -75 */ CWORD_CWORD_CWORD_CWORD, | ||
838 | /* 56 -74 */ CWORD_CWORD_CWORD_CWORD, | ||
839 | /* 57 -73 */ CWORD_CWORD_CWORD_CWORD, | ||
840 | /* 58 -72 */ CWORD_CWORD_CWORD_CWORD, | ||
841 | /* 59 -71 */ CWORD_CWORD_CWORD_CWORD, | ||
842 | /* 60 -70 */ CWORD_CWORD_CWORD_CWORD, | ||
843 | /* 61 -69 */ CWORD_CWORD_CWORD_CWORD, | ||
844 | /* 62 -68 */ CWORD_CWORD_CWORD_CWORD, | ||
845 | /* 63 -67 */ CWORD_CWORD_CWORD_CWORD, | ||
846 | /* 64 -66 */ CWORD_CWORD_CWORD_CWORD, | ||
847 | /* 65 -65 */ CWORD_CWORD_CWORD_CWORD, | ||
848 | /* 66 -64 */ CWORD_CWORD_CWORD_CWORD, | ||
849 | /* 67 -63 */ CWORD_CWORD_CWORD_CWORD, | ||
850 | /* 68 -62 */ CWORD_CWORD_CWORD_CWORD, | ||
851 | /* 69 -61 */ CWORD_CWORD_CWORD_CWORD, | ||
852 | /* 70 -60 */ CWORD_CWORD_CWORD_CWORD, | ||
853 | /* 71 -59 */ CWORD_CWORD_CWORD_CWORD, | ||
854 | /* 72 -58 */ CWORD_CWORD_CWORD_CWORD, | ||
855 | /* 73 -57 */ CWORD_CWORD_CWORD_CWORD, | ||
856 | /* 74 -56 */ CWORD_CWORD_CWORD_CWORD, | ||
857 | /* 75 -55 */ CWORD_CWORD_CWORD_CWORD, | ||
858 | /* 76 -54 */ CWORD_CWORD_CWORD_CWORD, | ||
859 | /* 77 -53 */ CWORD_CWORD_CWORD_CWORD, | ||
860 | /* 78 -52 */ CWORD_CWORD_CWORD_CWORD, | ||
861 | /* 79 -51 */ CWORD_CWORD_CWORD_CWORD, | ||
862 | /* 80 -50 */ CWORD_CWORD_CWORD_CWORD, | ||
863 | /* 81 -49 */ CWORD_CWORD_CWORD_CWORD, | ||
864 | /* 82 -48 */ CWORD_CWORD_CWORD_CWORD, | ||
865 | /* 83 -47 */ CWORD_CWORD_CWORD_CWORD, | ||
866 | /* 84 -46 */ CWORD_CWORD_CWORD_CWORD, | ||
867 | /* 85 -45 */ CWORD_CWORD_CWORD_CWORD, | ||
868 | /* 86 -44 */ CWORD_CWORD_CWORD_CWORD, | ||
869 | /* 87 -43 */ CWORD_CWORD_CWORD_CWORD, | ||
870 | /* 88 -42 */ CWORD_CWORD_CWORD_CWORD, | ||
871 | /* 89 -41 */ CWORD_CWORD_CWORD_CWORD, | ||
872 | /* 90 -40 */ CWORD_CWORD_CWORD_CWORD, | ||
873 | /* 91 -39 */ CWORD_CWORD_CWORD_CWORD, | ||
874 | /* 92 -38 */ CWORD_CWORD_CWORD_CWORD, | ||
875 | /* 93 -37 */ CWORD_CWORD_CWORD_CWORD, | ||
876 | /* 94 -36 */ CWORD_CWORD_CWORD_CWORD, | ||
877 | /* 95 -35 */ CWORD_CWORD_CWORD_CWORD, | ||
878 | /* 96 -34 */ CWORD_CWORD_CWORD_CWORD, | ||
879 | /* 97 -33 */ CWORD_CWORD_CWORD_CWORD, | ||
880 | /* 98 -32 */ CWORD_CWORD_CWORD_CWORD, | ||
881 | /* 99 -31 */ CWORD_CWORD_CWORD_CWORD, | ||
882 | /* 100 -30 */ CWORD_CWORD_CWORD_CWORD, | ||
883 | /* 101 -29 */ CWORD_CWORD_CWORD_CWORD, | ||
884 | /* 102 -28 */ CWORD_CWORD_CWORD_CWORD, | ||
885 | /* 103 -27 */ CWORD_CWORD_CWORD_CWORD, | ||
886 | /* 104 -26 */ CWORD_CWORD_CWORD_CWORD, | ||
887 | /* 105 -25 */ CWORD_CWORD_CWORD_CWORD, | ||
888 | /* 106 -24 */ CWORD_CWORD_CWORD_CWORD, | ||
889 | /* 107 -23 */ CWORD_CWORD_CWORD_CWORD, | ||
890 | /* 108 -22 */ CWORD_CWORD_CWORD_CWORD, | ||
891 | /* 109 -21 */ CWORD_CWORD_CWORD_CWORD, | ||
892 | /* 110 -20 */ CWORD_CWORD_CWORD_CWORD, | ||
893 | /* 111 -19 */ CWORD_CWORD_CWORD_CWORD, | ||
894 | /* 112 -18 */ CWORD_CWORD_CWORD_CWORD, | ||
895 | /* 113 -17 */ CWORD_CWORD_CWORD_CWORD, | ||
896 | /* 114 -16 */ CWORD_CWORD_CWORD_CWORD, | ||
897 | /* 115 -15 */ CWORD_CWORD_CWORD_CWORD, | ||
898 | /* 116 -14 */ CWORD_CWORD_CWORD_CWORD, | ||
899 | /* 117 -13 */ CWORD_CWORD_CWORD_CWORD, | ||
900 | /* 118 -12 */ CWORD_CWORD_CWORD_CWORD, | ||
901 | /* 119 -11 */ CWORD_CWORD_CWORD_CWORD, | ||
902 | /* 120 -10 */ CWORD_CWORD_CWORD_CWORD, | ||
903 | /* 121 -9 */ CWORD_CWORD_CWORD_CWORD, | ||
904 | /* 122 -8 */ CWORD_CWORD_CWORD_CWORD, | ||
905 | /* 123 -7 */ CWORD_CWORD_CWORD_CWORD, | ||
906 | /* 124 -6 */ CWORD_CWORD_CWORD_CWORD, | ||
907 | /* 125 -5 */ CWORD_CWORD_CWORD_CWORD, | ||
908 | /* 126 -4 */ CWORD_CWORD_CWORD_CWORD, | ||
909 | /* 127 -3 */ CWORD_CWORD_CWORD_CWORD, | ||
910 | /* 128 -2 */ CWORD_CWORD_CWORD_CWORD, | ||
911 | /* 129 -1 */ CWORD_CWORD_CWORD_CWORD, | ||
912 | /* 130 0 */ CWORD_CWORD_CWORD_CWORD, | ||
913 | /* 131 1 */ CWORD_CWORD_CWORD_CWORD, | ||
914 | /* 132 2 */ CWORD_CWORD_CWORD_CWORD, | ||
915 | /* 133 3 */ CWORD_CWORD_CWORD_CWORD, | ||
916 | /* 134 4 */ CWORD_CWORD_CWORD_CWORD, | ||
917 | /* 135 5 */ CWORD_CWORD_CWORD_CWORD, | ||
918 | /* 136 6 */ CWORD_CWORD_CWORD_CWORD, | ||
919 | /* 137 7 */ CWORD_CWORD_CWORD_CWORD, | ||
920 | /* 138 8 */ CWORD_CWORD_CWORD_CWORD, | ||
921 | /* 139 9 "\t" */ CSPCL_CWORD_CWORD_CWORD, | ||
922 | /* 140 10 "\n" */ CNL_CNL_CNL_CNL, | ||
923 | /* 141 11 */ CWORD_CWORD_CWORD_CWORD, | ||
924 | /* 142 12 */ CWORD_CWORD_CWORD_CWORD, | ||
925 | /* 143 13 */ CWORD_CWORD_CWORD_CWORD, | ||
926 | /* 144 14 */ CWORD_CWORD_CWORD_CWORD, | ||
927 | /* 145 15 */ CWORD_CWORD_CWORD_CWORD, | ||
928 | /* 146 16 */ CWORD_CWORD_CWORD_CWORD, | ||
929 | /* 147 17 */ CWORD_CWORD_CWORD_CWORD, | ||
930 | /* 148 18 */ CWORD_CWORD_CWORD_CWORD, | ||
931 | /* 149 19 */ CWORD_CWORD_CWORD_CWORD, | ||
932 | /* 150 20 */ CWORD_CWORD_CWORD_CWORD, | ||
933 | /* 151 21 */ CWORD_CWORD_CWORD_CWORD, | ||
934 | /* 152 22 */ CWORD_CWORD_CWORD_CWORD, | ||
935 | /* 153 23 */ CWORD_CWORD_CWORD_CWORD, | ||
936 | /* 154 24 */ CWORD_CWORD_CWORD_CWORD, | ||
937 | /* 155 25 */ CWORD_CWORD_CWORD_CWORD, | ||
938 | /* 156 26 */ CWORD_CWORD_CWORD_CWORD, | ||
939 | /* 157 27 */ CWORD_CWORD_CWORD_CWORD, | ||
940 | /* 158 28 */ CWORD_CWORD_CWORD_CWORD, | ||
941 | /* 159 29 */ CWORD_CWORD_CWORD_CWORD, | ||
942 | /* 160 30 */ CWORD_CWORD_CWORD_CWORD, | ||
943 | /* 161 31 */ CWORD_CWORD_CWORD_CWORD, | ||
944 | /* 162 32 " " */ CSPCL_CWORD_CWORD_CWORD, | ||
945 | /* 163 33 "!" */ CWORD_CCTL_CCTL_CWORD, | ||
946 | /* 164 34 """ */ CDQUOTE_CENDQUOTE_CWORD_CDQUOTE, | ||
947 | /* 165 35 "#" */ CWORD_CWORD_CWORD_CWORD, | ||
948 | /* 166 36 "$" */ CVAR_CVAR_CWORD_CVAR, | ||
949 | /* 167 37 "%" */ CWORD_CWORD_CWORD_CWORD, | ||
950 | /* 168 38 "&" */ CSPCL_CWORD_CWORD_CWORD, | ||
951 | /* 169 39 "'" */ CSQUOTE_CWORD_CENDQUOTE_CSQUOTE, | ||
952 | /* 170 40 "(" */ CSPCL_CWORD_CWORD_CLP, | ||
953 | /* 171 41 ")" */ CSPCL_CWORD_CWORD_CRP, | ||
954 | /* 172 42 "*" */ CWORD_CCTL_CCTL_CWORD, | ||
955 | /* 173 43 "+" */ CWORD_CWORD_CWORD_CWORD, | ||
956 | /* 174 44 "," */ CWORD_CWORD_CWORD_CWORD, | ||
957 | /* 175 45 "-" */ CWORD_CCTL_CCTL_CWORD, | ||
958 | /* 176 46 "." */ CWORD_CWORD_CWORD_CWORD, | ||
959 | /* 177 47 "/" */ CWORD_CCTL_CCTL_CWORD, | ||
960 | /* 178 48 "0" */ CWORD_CWORD_CWORD_CWORD, | ||
961 | /* 179 49 "1" */ CWORD_CWORD_CWORD_CWORD, | ||
962 | /* 180 50 "2" */ CWORD_CWORD_CWORD_CWORD, | ||
963 | /* 181 51 "3" */ CWORD_CWORD_CWORD_CWORD, | ||
964 | /* 182 52 "4" */ CWORD_CWORD_CWORD_CWORD, | ||
965 | /* 183 53 "5" */ CWORD_CWORD_CWORD_CWORD, | ||
966 | /* 184 54 "6" */ CWORD_CWORD_CWORD_CWORD, | ||
967 | /* 185 55 "7" */ CWORD_CWORD_CWORD_CWORD, | ||
968 | /* 186 56 "8" */ CWORD_CWORD_CWORD_CWORD, | ||
969 | /* 187 57 "9" */ CWORD_CWORD_CWORD_CWORD, | ||
970 | /* 188 58 ":" */ CWORD_CCTL_CCTL_CWORD, | ||
971 | /* 189 59 ";" */ CSPCL_CWORD_CWORD_CWORD, | ||
972 | /* 190 60 "<" */ CSPCL_CWORD_CWORD_CWORD, | ||
973 | /* 191 61 "=" */ CWORD_CCTL_CCTL_CWORD, | ||
974 | /* 192 62 ">" */ CSPCL_CWORD_CWORD_CWORD, | ||
975 | /* 193 63 "?" */ CWORD_CCTL_CCTL_CWORD, | ||
976 | /* 194 64 "@" */ CWORD_CWORD_CWORD_CWORD, | ||
977 | /* 195 65 "A" */ CWORD_CWORD_CWORD_CWORD, | ||
978 | /* 196 66 "B" */ CWORD_CWORD_CWORD_CWORD, | ||
979 | /* 197 67 "C" */ CWORD_CWORD_CWORD_CWORD, | ||
980 | /* 198 68 "D" */ CWORD_CWORD_CWORD_CWORD, | ||
981 | /* 199 69 "E" */ CWORD_CWORD_CWORD_CWORD, | ||
982 | /* 200 70 "F" */ CWORD_CWORD_CWORD_CWORD, | ||
983 | /* 201 71 "G" */ CWORD_CWORD_CWORD_CWORD, | ||
984 | /* 202 72 "H" */ CWORD_CWORD_CWORD_CWORD, | ||
985 | /* 203 73 "I" */ CWORD_CWORD_CWORD_CWORD, | ||
986 | /* 204 74 "J" */ CWORD_CWORD_CWORD_CWORD, | ||
987 | /* 205 75 "K" */ CWORD_CWORD_CWORD_CWORD, | ||
988 | /* 206 76 "L" */ CWORD_CWORD_CWORD_CWORD, | ||
989 | /* 207 77 "M" */ CWORD_CWORD_CWORD_CWORD, | ||
990 | /* 208 78 "N" */ CWORD_CWORD_CWORD_CWORD, | ||
991 | /* 209 79 "O" */ CWORD_CWORD_CWORD_CWORD, | ||
992 | /* 210 80 "P" */ CWORD_CWORD_CWORD_CWORD, | ||
993 | /* 211 81 "Q" */ CWORD_CWORD_CWORD_CWORD, | ||
994 | /* 212 82 "R" */ CWORD_CWORD_CWORD_CWORD, | ||
995 | /* 213 83 "S" */ CWORD_CWORD_CWORD_CWORD, | ||
996 | /* 214 84 "T" */ CWORD_CWORD_CWORD_CWORD, | ||
997 | /* 215 85 "U" */ CWORD_CWORD_CWORD_CWORD, | ||
998 | /* 216 86 "V" */ CWORD_CWORD_CWORD_CWORD, | ||
999 | /* 217 87 "W" */ CWORD_CWORD_CWORD_CWORD, | ||
1000 | /* 218 88 "X" */ CWORD_CWORD_CWORD_CWORD, | ||
1001 | /* 219 89 "Y" */ CWORD_CWORD_CWORD_CWORD, | ||
1002 | /* 220 90 "Z" */ CWORD_CWORD_CWORD_CWORD, | ||
1003 | /* 221 91 "[" */ CWORD_CCTL_CCTL_CWORD, | ||
1004 | /* 222 92 "\" */ CBACK_CBACK_CCTL_CBACK, | ||
1005 | /* 223 93 "]" */ CWORD_CCTL_CCTL_CWORD, | ||
1006 | /* 224 94 "^" */ CWORD_CWORD_CWORD_CWORD, | ||
1007 | /* 225 95 "_" */ CWORD_CWORD_CWORD_CWORD, | ||
1008 | /* 226 96 "`" */ CBQUOTE_CBQUOTE_CWORD_CBQUOTE, | ||
1009 | /* 227 97 "a" */ CWORD_CWORD_CWORD_CWORD, | ||
1010 | /* 228 98 "b" */ CWORD_CWORD_CWORD_CWORD, | ||
1011 | /* 229 99 "c" */ CWORD_CWORD_CWORD_CWORD, | ||
1012 | /* 230 100 "d" */ CWORD_CWORD_CWORD_CWORD, | ||
1013 | /* 231 101 "e" */ CWORD_CWORD_CWORD_CWORD, | ||
1014 | /* 232 102 "f" */ CWORD_CWORD_CWORD_CWORD, | ||
1015 | /* 233 103 "g" */ CWORD_CWORD_CWORD_CWORD, | ||
1016 | /* 234 104 "h" */ CWORD_CWORD_CWORD_CWORD, | ||
1017 | /* 235 105 "i" */ CWORD_CWORD_CWORD_CWORD, | ||
1018 | /* 236 106 "j" */ CWORD_CWORD_CWORD_CWORD, | ||
1019 | /* 237 107 "k" */ CWORD_CWORD_CWORD_CWORD, | ||
1020 | /* 238 108 "l" */ CWORD_CWORD_CWORD_CWORD, | ||
1021 | /* 239 109 "m" */ CWORD_CWORD_CWORD_CWORD, | ||
1022 | /* 240 110 "n" */ CWORD_CWORD_CWORD_CWORD, | ||
1023 | /* 241 111 "o" */ CWORD_CWORD_CWORD_CWORD, | ||
1024 | /* 242 112 "p" */ CWORD_CWORD_CWORD_CWORD, | ||
1025 | /* 243 113 "q" */ CWORD_CWORD_CWORD_CWORD, | ||
1026 | /* 244 114 "r" */ CWORD_CWORD_CWORD_CWORD, | ||
1027 | /* 245 115 "s" */ CWORD_CWORD_CWORD_CWORD, | ||
1028 | /* 246 116 "t" */ CWORD_CWORD_CWORD_CWORD, | ||
1029 | /* 247 117 "u" */ CWORD_CWORD_CWORD_CWORD, | ||
1030 | /* 248 118 "v" */ CWORD_CWORD_CWORD_CWORD, | ||
1031 | /* 249 119 "w" */ CWORD_CWORD_CWORD_CWORD, | ||
1032 | /* 250 120 "x" */ CWORD_CWORD_CWORD_CWORD, | ||
1033 | /* 251 121 "y" */ CWORD_CWORD_CWORD_CWORD, | ||
1034 | /* 252 122 "z" */ CWORD_CWORD_CWORD_CWORD, | ||
1035 | /* 253 123 "{" */ CWORD_CWORD_CWORD_CWORD, | ||
1036 | /* 254 124 "|" */ CSPCL_CWORD_CWORD_CWORD, | ||
1037 | /* 255 125 "}" */ CENDVAR_CENDVAR_CWORD_CENDVAR, | ||
1038 | /* 256 126 "~" */ CWORD_CCTL_CCTL_CWORD, | ||
1039 | /* 257 127 */ CWORD_CWORD_CWORD_CWORD, | ||
1110 | }; | 1040 | }; |
1111 | 1041 | ||
1042 | #endif /* USE_SIT_FUNCTION */ | ||
1043 | |||
1044 | |||
1045 | /* first char is indicating which tokens mark the end of a list */ | ||
1046 | static const char *const tokname_array[] = { | ||
1047 | "\1end of file", | ||
1048 | "\0newline", | ||
1049 | "\0redirection", | ||
1050 | "\0word", | ||
1051 | "\0assignment", | ||
1052 | "\0;", | ||
1053 | "\0&", | ||
1054 | "\0&&", | ||
1055 | "\0||", | ||
1056 | "\0|", | ||
1057 | "\0(", | ||
1058 | "\1)", | ||
1059 | "\1;;", | ||
1060 | "\1`", | ||
1112 | #define KWDOFFSET 14 | 1061 | #define KWDOFFSET 14 |
1113 | 1062 | /* the following are keywords */ | |
1114 | static const char *const parsekwd[] = { | 1063 | "\0!", |
1115 | "!", | 1064 | "\0case", |
1116 | "case", | 1065 | "\1do", |
1117 | "do", | 1066 | "\1done", |
1118 | "done", | 1067 | "\1elif", |
1119 | "elif", | 1068 | "\1else", |
1120 | "else", | 1069 | "\1esac", |
1121 | "esac", | 1070 | "\1fi", |
1122 | "fi", | 1071 | "\0for", |
1123 | "for", | 1072 | "\0if", |
1124 | "if", | 1073 | "\0in", |
1125 | "in", | 1074 | "\1then", |
1126 | "then", | 1075 | "\0until", |
1127 | "until", | 1076 | "\0while", |
1128 | "while", | 1077 | "\0{", |
1129 | "{", | 1078 | "\1}", |
1130 | "}" | ||
1131 | }; | 1079 | }; |
1132 | 1080 | ||
1081 | static const char *tokname(int tok) | ||
1082 | { | ||
1083 | static char buf[16]; | ||
1084 | |||
1085 | if(tok>=TSEMI) | ||
1086 | buf[0] = '"'; | ||
1087 | sprintf(buf+(tok>=TSEMI), "%s%c", | ||
1088 | tokname_array[tok]+1, (tok>=TSEMI ? '"' : 0)); | ||
1089 | return buf; | ||
1090 | } | ||
1133 | 1091 | ||
1134 | static int plinno = 1; /* input line number */ | 1092 | static int plinno = 1; /* input line number */ |
1135 | 1093 | ||
@@ -1562,8 +1520,8 @@ __lookupalias(const char *name) { | |||
1562 | 1520 | ||
1563 | #ifdef ASH_MATH_SUPPORT | 1521 | #ifdef ASH_MATH_SUPPORT |
1564 | /* The generated file arith.c has been replaced with a custom hand | 1522 | /* The generated file arith.c has been replaced with a custom hand |
1565 | * written implementation written by Aaron Lehmann <aaronl@vitelus.com>. | 1523 | * written implementation written by Aaron Lehmann <aaronl@vitelus.com>. |
1566 | * This is now part of libbb, so that it can be used by all the shells | 1524 | * This is now part of libbb, so that it can be used by all the shells |
1567 | * in busybox. */ | 1525 | * in busybox. */ |
1568 | #define ARITH_NUM 257 | 1526 | #define ARITH_NUM 257 |
1569 | #define ARITH_LPAREN 258 | 1527 | #define ARITH_LPAREN 258 |
@@ -1744,7 +1702,7 @@ static const struct builtincmd builtincmds[] = { | |||
1744 | }; | 1702 | }; |
1745 | #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) ) | 1703 | #define NUMBUILTINS (sizeof (builtincmds) / sizeof (struct builtincmd) ) |
1746 | 1704 | ||
1747 | static const struct builtincmd *DOTCMD = &builtincmds[0]; | 1705 | #define DOTCMD &builtincmds[0] |
1748 | static struct builtincmd *BLTINCMD; | 1706 | static struct builtincmd *BLTINCMD; |
1749 | static struct builtincmd *EXECCMD; | 1707 | static struct builtincmd *EXECCMD; |
1750 | static struct builtincmd *EVALCMD; | 1708 | static struct builtincmd *EVALCMD; |
@@ -2165,7 +2123,7 @@ exverror(int cond, const char *msg, va_list ap) | |||
2165 | } | 2123 | } |
2166 | 2124 | ||
2167 | 2125 | ||
2168 | static void | 2126 | static void |
2169 | error(const char *msg, ...) | 2127 | error(const char *msg, ...) |
2170 | { | 2128 | { |
2171 | va_list ap; | 2129 | va_list ap; |
@@ -3690,7 +3648,7 @@ padvance(const char **path, const char *name) | |||
3690 | static int | 3648 | static int |
3691 | pstrcmp(const void *a, const void *b) | 3649 | pstrcmp(const void *a, const void *b) |
3692 | { | 3650 | { |
3693 | return strcmp((const char *) a, *(const char *const *) b); | 3651 | return strcmp((const char *) a, (*(const char *const *) b) + 1); |
3694 | } | 3652 | } |
3695 | 3653 | ||
3696 | /* | 3654 | /* |
@@ -3700,8 +3658,9 @@ pstrcmp(const void *a, const void *b) | |||
3700 | static const char *const * | 3658 | static const char *const * |
3701 | findkwd(const char *s) | 3659 | findkwd(const char *s) |
3702 | { | 3660 | { |
3703 | return bsearch(s, parsekwd, sizeof(parsekwd) / sizeof(const char *), | 3661 | return bsearch(s, tokname_array + KWDOFFSET, |
3704 | sizeof(const char *), pstrcmp); | 3662 | (sizeof(tokname_array)/sizeof(const char *)) - KWDOFFSET, |
3663 | sizeof(const char *), pstrcmp); | ||
3705 | } | 3664 | } |
3706 | 3665 | ||
3707 | 3666 | ||
@@ -4228,7 +4187,7 @@ delete_cmd_entry() { | |||
4228 | 4187 | ||
4229 | 4188 | ||
4230 | 4189 | ||
4231 | static const short nodesize[26] = { | 4190 | static const unsigned char nodesize[26] = { |
4232 | ALIGN(sizeof (struct nbinary)), | 4191 | ALIGN(sizeof (struct nbinary)), |
4233 | ALIGN(sizeof (struct ncmd)), | 4192 | ALIGN(sizeof (struct ncmd)), |
4234 | ALIGN(sizeof (struct npipe)), | 4193 | ALIGN(sizeof (struct npipe)), |
@@ -4412,7 +4371,7 @@ static char *exptilde (char *, int); | |||
4412 | static void expbackq (union node *, int, int); | 4371 | static void expbackq (union node *, int, int); |
4413 | static int subevalvar (char *, char *, int, int, int, int, int); | 4372 | static int subevalvar (char *, char *, int, int, int, int, int); |
4414 | static int varisset (char *, int); | 4373 | static int varisset (char *, int); |
4415 | static void strtodest (const char *, const char *, int); | 4374 | static void strtodest (const char *, int, int); |
4416 | static void varvalue (char *, int, int); | 4375 | static void varvalue (char *, int, int); |
4417 | static void recordregion (int, int, int); | 4376 | static void recordregion (int, int, int); |
4418 | static void removerecordregions (int); | 4377 | static void removerecordregions (int); |
@@ -4916,7 +4875,7 @@ expbackq(cmd, quoted, flag) | |||
4916 | struct nodelist *volatile saveargbackq; | 4875 | struct nodelist *volatile saveargbackq; |
4917 | char lastc; | 4876 | char lastc; |
4918 | int startloc = dest - stackblock(); | 4877 | int startloc = dest - stackblock(); |
4919 | char const *syntax = quoted? DQSYNTAX : BASESYNTAX; | 4878 | int syntax = quoted ? DQSYNTAX : BASESYNTAX; |
4920 | volatile int saveherefd; | 4879 | volatile int saveherefd; |
4921 | int quotes = flag & (EXP_FULL | EXP_CASE); | 4880 | int quotes = flag & (EXP_FULL | EXP_CASE); |
4922 | struct jmploc jmploc; | 4881 | struct jmploc jmploc; |
@@ -4973,7 +4932,7 @@ err1: | |||
4973 | } | 4932 | } |
4974 | lastc = *p++; | 4933 | lastc = *p++; |
4975 | if (lastc != '\0') { | 4934 | if (lastc != '\0') { |
4976 | if (quotes && syntax[(int)lastc] == CCTL) | 4935 | if (quotes && SIT(lastc, syntax) == CCTL) |
4977 | STPUTC(CTLESC, dest); | 4936 | STPUTC(CTLESC, dest); |
4978 | STPUTC(lastc, dest); | 4937 | STPUTC(lastc, dest); |
4979 | } | 4938 | } |
@@ -5174,13 +5133,10 @@ varisset(name, nulok) | |||
5174 | */ | 5133 | */ |
5175 | 5134 | ||
5176 | static void | 5135 | static void |
5177 | strtodest(p, syntax, quotes) | 5136 | strtodest(const char *p, int syntax, int quotes) |
5178 | const char *p; | ||
5179 | const char *syntax; | ||
5180 | int quotes; | ||
5181 | { | 5137 | { |
5182 | while (*p) { | 5138 | while (*p) { |
5183 | if (quotes && syntax[(int) *p] == CCTL) | 5139 | if (quotes && SIT(*p,syntax) == CCTL) |
5184 | STPUTC(CTLESC, expdest); | 5140 | STPUTC(CTLESC, expdest); |
5185 | STPUTC(*p++, expdest); | 5141 | STPUTC(*p++, expdest); |
5186 | } | 5142 | } |
@@ -5191,10 +5147,7 @@ strtodest(p, syntax, quotes) | |||
5191 | */ | 5147 | */ |
5192 | 5148 | ||
5193 | static void | 5149 | static void |
5194 | varvalue(name, quoted, flags) | 5150 | varvalue(char *name, int quoted, int flags) |
5195 | char *name; | ||
5196 | int quoted; | ||
5197 | int flags; | ||
5198 | { | 5151 | { |
5199 | int num; | 5152 | int num; |
5200 | char *p; | 5153 | char *p; |
@@ -5202,7 +5155,7 @@ varvalue(name, quoted, flags) | |||
5202 | int sep; | 5155 | int sep; |
5203 | int sepq = 0; | 5156 | int sepq = 0; |
5204 | char **ap; | 5157 | char **ap; |
5205 | char const *syntax; | 5158 | int syntax; |
5206 | int allow_split = flags & EXP_FULL; | 5159 | int allow_split = flags & EXP_FULL; |
5207 | int quotes = flags & (EXP_FULL | EXP_CASE); | 5160 | int quotes = flags & (EXP_FULL | EXP_CASE); |
5208 | 5161 | ||
@@ -5237,7 +5190,7 @@ numvar: | |||
5237 | case '*': | 5190 | case '*': |
5238 | sep = ifsset() ? ifsval()[0] : ' '; | 5191 | sep = ifsset() ? ifsval()[0] : ' '; |
5239 | if (quotes) { | 5192 | if (quotes) { |
5240 | sepq = syntax[(int) sep] == CCTL; | 5193 | sepq = SIT(sep,syntax) == CCTL; |
5241 | } | 5194 | } |
5242 | param: | 5195 | param: |
5243 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { | 5196 | for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { |
@@ -5572,7 +5525,7 @@ expmeta(enddir, name) | |||
5572 | break; | 5525 | break; |
5573 | } | 5526 | } |
5574 | } | 5527 | } |
5575 | } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) { | 5528 | } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) { |
5576 | metaflag = 1; | 5529 | metaflag = 1; |
5577 | } else if (*p == '\0') | 5530 | } else if (*p == '\0') |
5578 | break; | 5531 | break; |
@@ -7341,10 +7294,219 @@ cmdputs(const char *s) | |||
7341 | cmdnextc = q; | 7294 | cmdnextc = q; |
7342 | } | 7295 | } |
7343 | 7296 | ||
7297 | //#define CMDTXT_TABLE | ||
7298 | #ifdef CMDTXT_TABLE | ||
7299 | /* | ||
7300 | * To collect a lot of redundant code in cmdtxt() case statements, we | ||
7301 | * implement a mini language here. Each type of node struct has an | ||
7302 | * associated instruction sequence that operates on its members via | ||
7303 | * their offsets. The instruction are pack in unsigned chars with | ||
7304 | * format IIDDDDDE where the bits are | ||
7305 | * I : part of the instruction opcode, which are | ||
7306 | * 00 : member is a pointer to another node -- process it recursively | ||
7307 | * 40 : member is a pointer to a char string -- output it | ||
7308 | * 80 : output the string whose index is stored in the data field | ||
7309 | * CC : flag signaling that this case needs external processing | ||
7310 | * D : data - either the (shifted) index of a fixed string to output or | ||
7311 | * the actual offset of the member to operate on in the struct | ||
7312 | * (since we assume bit 0 is set, the offset is not shifted) | ||
7313 | * E : flag signaling end of instruction sequence | ||
7314 | * | ||
7315 | * WARNING: In order to handle larger offsets for 64bit archs, this code | ||
7316 | * assumes that no offset can be an odd number and stores the | ||
7317 | * end-of-instructions flag in bit 0. | ||
7318 | */ | ||
7319 | |||
7320 | #define CMDTXT_NOMORE 0x01 /* NOTE: no offset should be odd */ | ||
7321 | #define CMDTXT_CHARPTR 0x40 | ||
7322 | #define CMDTXT_STRING 0x80 | ||
7323 | #define CMDTXT_SPECIAL 0xC0 | ||
7324 | #define CMDTXT_OFFSETMASK 0x3E | ||
7325 | |||
7326 | static const char * const cmdtxt_strings[] = { | ||
7327 | /* 0 1 2 3 4 5 6 7 */ | ||
7328 | "; ", "(", ")", " && ", " || ", "if ", "; then ", "...", | ||
7329 | /* 8 9 10 11 12 13 */ | ||
7330 | "while ", "; do ", "; done", "until ", "for ", " in ...", | ||
7331 | /* 14 15 16 17 */ | ||
7332 | "case ", "???", "() ...", "<<..." | ||
7333 | }; | ||
7334 | |||
7335 | static const char * const redir_strings[] = { | ||
7336 | ">", "<", "<>", ">>", ">|", ">&", "<&" | ||
7337 | }; | ||
7338 | |||
7339 | static const unsigned char cmdtxt_ops[] = { | ||
7340 | #define CMDTXT_NSEMI 0 | ||
7341 | offsetof(union node, nbinary.ch1), | ||
7342 | 0|CMDTXT_STRING, | ||
7343 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | ||
7344 | #define CMDTXT_NCMD (CMDTXT_NSEMI + 3) | ||
7345 | #define CMDTXT_NPIPE (CMDTXT_NCMD) | ||
7346 | #define CMDTXT_NCASE (CMDTXT_NCMD) | ||
7347 | #define CMDTXT_NTO (CMDTXT_NCMD) | ||
7348 | #define CMDTXT_NFROM (CMDTXT_NCMD) | ||
7349 | #define CMDTXT_NFROMTO (CMDTXT_NCMD) | ||
7350 | #define CMDTXT_NAPPEND (CMDTXT_NCMD) | ||
7351 | #define CMDTXT_NTOOV (CMDTXT_NCMD) | ||
7352 | #define CMDTXT_NTOFD (CMDTXT_NCMD) | ||
7353 | #define CMDTXT_NFROMFD (CMDTXT_NCMD) | ||
7354 | CMDTXT_SPECIAL, | ||
7355 | #define CMDTXT_NREDIR (CMDTXT_NPIPE + 1) | ||
7356 | #define CMDTXT_NBACKGND (CMDTXT_NREDIR) | ||
7357 | offsetof(union node, nredir.n)|CMDTXT_NOMORE, | ||
7358 | #define CMDTXT_NSUBSHELL (CMDTXT_NBACKGND + 1) | ||
7359 | (1*2)|CMDTXT_STRING, | ||
7360 | offsetof(union node, nredir.n), | ||
7361 | (2*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7362 | #define CMDTXT_NAND (CMDTXT_NSUBSHELL + 3) | ||
7363 | offsetof(union node, nbinary.ch1), | ||
7364 | (3*2)|CMDTXT_STRING, | ||
7365 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | ||
7366 | #define CMDTXT_NOR (CMDTXT_NAND + 3) | ||
7367 | offsetof(union node, nbinary.ch1), | ||
7368 | (4*2)|CMDTXT_STRING, | ||
7369 | offsetof(union node, nbinary.ch2)|CMDTXT_NOMORE, | ||
7370 | #define CMDTXT_NIF (CMDTXT_NOR + 3) | ||
7371 | (5*2)|CMDTXT_STRING, | ||
7372 | offsetof(union node, nif.test), | ||
7373 | (6*2)|CMDTXT_STRING, | ||
7374 | offsetof(union node, nif.ifpart), | ||
7375 | (7*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7376 | #define CMDTXT_NWHILE (CMDTXT_NIF + 5) | ||
7377 | (8*2)|CMDTXT_STRING, | ||
7378 | offsetof(union node, nbinary.ch1), | ||
7379 | (9*2)|CMDTXT_STRING, | ||
7380 | offsetof(union node, nbinary.ch2), | ||
7381 | (10*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7382 | #define CMDTXT_NUNTIL (CMDTXT_NWHILE + 5) | ||
7383 | (11*2)|CMDTXT_STRING, | ||
7384 | offsetof(union node, nbinary.ch1), | ||
7385 | (9*2)|CMDTXT_STRING, | ||
7386 | offsetof(union node, nbinary.ch2), | ||
7387 | (10*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7388 | #define CMDTXT_NFOR (CMDTXT_NUNTIL + 5) | ||
7389 | (12*2)|CMDTXT_STRING, | ||
7390 | offsetof(union node, nfor.var)|CMDTXT_CHARPTR, | ||
7391 | (13*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7392 | #define CMDTXT_NCLIST (CMDTXT_NFOR + 3) /* TODO: IS THIS CORRECT??? */ | ||
7393 | #define CMDTXT_NNOT (CMDTXT_NCLIST) /* TODO: IS THIS CORRECT??? */ | ||
7394 | (15*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7395 | #define CMDTXT_NDEFUN (CMDTXT_NCLIST + 1) | ||
7396 | offsetof(union node, narg.text)|CMDTXT_CHARPTR, | ||
7397 | (16*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7398 | #define CMDTXT_NARG (CMDTXT_NDEFUN + 2) | ||
7399 | offsetof(union node, narg.text)|CMDTXT_CHARPTR|CMDTXT_NOMORE, | ||
7400 | #define CMDTXT_NHERE (CMDTXT_NARG + 1) | ||
7401 | #define CMDTXT_NXHERE (CMDTXT_NHERE) | ||
7402 | (17*2)|CMDTXT_STRING|CMDTXT_NOMORE, | ||
7403 | }; | ||
7404 | |||
7405 | #if CMDTXT_NXHERE != 36 | ||
7406 | #error CMDTXT_NXHERE | ||
7407 | #endif | ||
7408 | |||
7409 | static const unsigned char cmdtxt_ops_index[26] = { | ||
7410 | CMDTXT_NSEMI, | ||
7411 | CMDTXT_NCMD, | ||
7412 | CMDTXT_NPIPE, | ||
7413 | CMDTXT_NREDIR, | ||
7414 | CMDTXT_NBACKGND, | ||
7415 | CMDTXT_NSUBSHELL, | ||
7416 | CMDTXT_NAND, | ||
7417 | CMDTXT_NOR, | ||
7418 | CMDTXT_NIF, | ||
7419 | CMDTXT_NWHILE, | ||
7420 | CMDTXT_NUNTIL, | ||
7421 | CMDTXT_NFOR, | ||
7422 | CMDTXT_NCASE, | ||
7423 | CMDTXT_NCLIST, | ||
7424 | CMDTXT_NDEFUN, | ||
7425 | CMDTXT_NARG, | ||
7426 | CMDTXT_NTO, | ||
7427 | CMDTXT_NFROM, | ||
7428 | CMDTXT_NFROMTO, | ||
7429 | CMDTXT_NAPPEND, | ||
7430 | CMDTXT_NTOOV, | ||
7431 | CMDTXT_NTOFD, | ||
7432 | CMDTXT_NFROMFD, | ||
7433 | CMDTXT_NHERE, | ||
7434 | CMDTXT_NXHERE, | ||
7435 | CMDTXT_NNOT, | ||
7436 | }; | ||
7344 | 7437 | ||
7345 | static void | 7438 | static void |
7346 | cmdtxt(const union node *n) | 7439 | cmdtxt(const union node *n) |
7347 | { | 7440 | { |
7441 | const char *p; | ||
7442 | |||
7443 | if (n == NULL) | ||
7444 | return; | ||
7445 | |||
7446 | p = cmdtxt_ops + (int) cmdtxt_ops_index[n->type]; | ||
7447 | if ((*p & CMDTXT_SPECIAL) != CMDTXT_SPECIAL) { /* normal case */ | ||
7448 | do { | ||
7449 | if (*p & CMDTXT_STRING) { /* output fixed string */ | ||
7450 | cmdputs(cmdtxt_strings[((int)(*p & CMDTXT_OFFSETMASK) >> 1)]); | ||
7451 | } else if (*p & CMDTXT_CHARPTR) { /* output dynamic string */ | ||
7452 | cmdputs(((const char *) n) + ((int)(*p & CMDTXT_OFFSETMASK))); | ||
7453 | } else { /* output field */ | ||
7454 | cmdtxt((const union node *) | ||
7455 | (((const char *) n) + ((int)(*p & CMDTXT_OFFSETMASK)))); | ||
7456 | } | ||
7457 | } while (!(*p++ & CMDTXT_NOMORE)); | ||
7458 | } else if (n->type == NCMD) { | ||
7459 | union node *np; | ||
7460 | for (np = n->ncmd.args ; np ; np = np->narg.next) { | ||
7461 | cmdtxt(np); | ||
7462 | if (np->narg.next) | ||
7463 | cmdputs(spcstr); | ||
7464 | } | ||
7465 | for (np = n->ncmd.redirect ; np ; np = np->nfile.next) { | ||
7466 | cmdputs(spcstr); | ||
7467 | cmdtxt(np); | ||
7468 | } | ||
7469 | } else if (n->type == NPIPE) { | ||
7470 | struct nodelist *lp; | ||
7471 | for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { | ||
7472 | cmdtxt(lp->n); | ||
7473 | if (lp->next) | ||
7474 | cmdputs(" | "); | ||
7475 | } | ||
7476 | } else if (n->type == NCASE) { | ||
7477 | cmdputs(cmdtxt_strings[14]); | ||
7478 | cmdputs(n->ncase.expr->narg.text); | ||
7479 | cmdputs(cmdtxt_strings[13]); | ||
7480 | } else { | ||
7481 | #if (NTO != 16) || (NFROM != 17) || (NFROMTO != 18) || (NAPPEND != 19) || (NTOOV != 20) || (NTOFD != 21) || (NFROMFD != 22) | ||
7482 | #error Assumption violated regarding range and ordering of NTO ... NFROMFD! | ||
7483 | #endif | ||
7484 | char s[2]; | ||
7485 | |||
7486 | #ifdef DEBUG | ||
7487 | assert((n->type >= NTO) && (n->type <= NFROMFD)); | ||
7488 | #endif | ||
7489 | |||
7490 | p = redir_strings[n->type - NTO]; | ||
7491 | if (n->nfile.fd != ('>' == *p)) { | ||
7492 | s[0] = n->nfile.fd + '0'; | ||
7493 | s[1] = '\0'; | ||
7494 | cmdputs(s); | ||
7495 | } | ||
7496 | cmdputs(p); | ||
7497 | if (n->type >= NTOFD) { | ||
7498 | s[0] = n->ndup.dupfd + '0'; | ||
7499 | s[1] = '\0'; | ||
7500 | cmdputs(s); | ||
7501 | } else { | ||
7502 | cmdtxt(n->nfile.fname); | ||
7503 | } | ||
7504 | } | ||
7505 | } | ||
7506 | #else /* CMDTXT_TABLE */ | ||
7507 | static void | ||
7508 | cmdtxt(const union node *n) | ||
7509 | { | ||
7348 | union node *np; | 7510 | union node *np; |
7349 | struct nodelist *lp; | 7511 | struct nodelist *lp; |
7350 | const char *p; | 7512 | const char *p; |
@@ -7469,7 +7631,7 @@ redir: | |||
7469 | break; | 7631 | break; |
7470 | } | 7632 | } |
7471 | } | 7633 | } |
7472 | 7634 | #endif | |
7473 | 7635 | ||
7474 | static char * | 7636 | static char * |
7475 | commandtext(const union node *n) | 7637 | commandtext(const union node *n) |
@@ -7602,27 +7764,17 @@ ash_main(argc, argv) | |||
7602 | * exception EXSHELLPROC to clean up before executing | 7764 | * exception EXSHELLPROC to clean up before executing |
7603 | * the shell procedure. | 7765 | * the shell procedure. |
7604 | */ | 7766 | */ |
7605 | switch (exception) { | 7767 | if (exception == EXSHELLPROC) { |
7606 | case EXSHELLPROC: | ||
7607 | rootpid = getpid(); | 7768 | rootpid = getpid(); |
7608 | rootshell = 1; | 7769 | rootshell = 1; |
7609 | minusc = NULL; | 7770 | minusc = NULL; |
7610 | state = 3; | 7771 | state = 3; |
7611 | break; | 7772 | } else { |
7612 | 7773 | if (exception == EXEXEC) { | |
7613 | case EXEXEC: | 7774 | exitstatus = exerrno; |
7614 | exitstatus = exerrno; | 7775 | } else if (exception == EXERROR) { |
7615 | break; | 7776 | exitstatus = 2; |
7616 | 7777 | } | |
7617 | case EXERROR: | ||
7618 | exitstatus = 2; | ||
7619 | break; | ||
7620 | |||
7621 | default: | ||
7622 | break; | ||
7623 | } | ||
7624 | |||
7625 | if (exception != EXSHELLPROC) { | ||
7626 | if (state == 0 || iflag == 0 || ! rootshell) | 7778 | if (state == 0 || iflag == 0 || ! rootshell) |
7627 | exitshell(exitstatus); | 7779 | exitshell(exitstatus); |
7628 | } | 7780 | } |
@@ -7673,14 +7825,14 @@ state2: | |||
7673 | state3: | 7825 | state3: |
7674 | state = 4; | 7826 | state = 4; |
7675 | if (sflag == 0 || minusc) { | 7827 | if (sflag == 0 || minusc) { |
7676 | static int sigs[] = { | 7828 | static const char sigs[] = { |
7677 | SIGINT, SIGQUIT, SIGHUP, | 7829 | SIGINT, SIGQUIT, SIGHUP, |
7678 | #ifdef SIGTSTP | 7830 | #ifdef SIGTSTP |
7679 | SIGTSTP, | 7831 | SIGTSTP, |
7680 | #endif | 7832 | #endif |
7681 | SIGPIPE | 7833 | SIGPIPE |
7682 | }; | 7834 | }; |
7683 | #define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0])) | 7835 | #define SIGSSIZE ((sizeof(sigs)/sizeof(sigs[0])) - 1) /* trailing nul */ |
7684 | int i; | 7836 | int i; |
7685 | 7837 | ||
7686 | for (i = 0; i < SIGSSIZE; i++) | 7838 | for (i = 0; i < SIGSSIZE; i++) |
@@ -7764,8 +7916,8 @@ read_profile(name) | |||
7764 | const char *name; | 7916 | const char *name; |
7765 | { | 7917 | { |
7766 | int fd; | 7918 | int fd; |
7767 | int xflag_set = 0; | 7919 | int xflag_save; |
7768 | int vflag_set = 0; | 7920 | int vflag_save; |
7769 | 7921 | ||
7770 | INTOFF; | 7922 | INTOFF; |
7771 | if ((fd = open(name, O_RDONLY)) >= 0) | 7923 | if ((fd = open(name, O_RDONLY)) >= 0) |
@@ -7774,19 +7926,15 @@ read_profile(name) | |||
7774 | if (fd < 0) | 7926 | if (fd < 0) |
7775 | return; | 7927 | return; |
7776 | /* -q turns off -x and -v just when executing init files */ | 7928 | /* -q turns off -x and -v just when executing init files */ |
7929 | /* Note: Might do a little redundant work, but reduces code size. */ | ||
7930 | xflag_save = xflag; | ||
7931 | vflag_save = vflag; | ||
7777 | if (qflag) { | 7932 | if (qflag) { |
7778 | if (xflag) | 7933 | vflag = xflag = 0; |
7779 | xflag = 0, xflag_set = 1; | ||
7780 | if (vflag) | ||
7781 | vflag = 0, vflag_set = 1; | ||
7782 | } | 7934 | } |
7783 | cmdloop(0); | 7935 | cmdloop(0); |
7784 | if (qflag) { | 7936 | xflag = xflag_save; |
7785 | if (xflag_set) | 7937 | vflag = vflag_save; |
7786 | xflag = 1; | ||
7787 | if (vflag_set) | ||
7788 | vflag = 1; | ||
7789 | } | ||
7790 | popfile(); | 7938 | popfile(); |
7791 | } | 7939 | } |
7792 | 7940 | ||
@@ -8089,11 +8237,6 @@ ungrabstackstr(char *s, char *p) | |||
8089 | 8237 | ||
8090 | #undef rflag | 8238 | #undef rflag |
8091 | 8239 | ||
8092 | //#ifdef __GLIBC__ | ||
8093 | static mode_t getmode(const void *, mode_t); | ||
8094 | static void *setmode(const char *); | ||
8095 | //#endif | ||
8096 | |||
8097 | #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1 | 8240 | #if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1 |
8098 | typedef long rlim_t; | 8241 | typedef long rlim_t; |
8099 | #endif | 8242 | #endif |
@@ -8108,9 +8251,7 @@ typedef long rlim_t; | |||
8108 | */ | 8251 | */ |
8109 | 8252 | ||
8110 | static int | 8253 | static int |
8111 | readcmd(argc, argv) | 8254 | readcmd(int argc, char **argv) |
8112 | int argc; | ||
8113 | char **argv; | ||
8114 | { | 8255 | { |
8115 | char **ap; | 8256 | char **ap; |
8116 | int backslash; | 8257 | int backslash; |
@@ -8132,7 +8273,7 @@ readcmd(argc, argv) | |||
8132 | rflag = 1; | 8273 | rflag = 1; |
8133 | } | 8274 | } |
8134 | if (prompt && isatty(0)) { | 8275 | if (prompt && isatty(0)) { |
8135 | putprompt(prompt); | 8276 | out2str(prompt); /* read without cmdedit */ |
8136 | flushall(); | 8277 | flushall(); |
8137 | } | 8278 | } |
8138 | if (*(ap = argptr) == NULL) | 8279 | if (*(ap = argptr) == NULL) |
@@ -8199,8 +8340,16 @@ umaskcmd(argc, argv) | |||
8199 | int argc; | 8340 | int argc; |
8200 | char **argv; | 8341 | char **argv; |
8201 | { | 8342 | { |
8343 | static const char permuser[3] = "ugo"; | ||
8344 | static const char permmode[3] = "rwx"; | ||
8345 | static const short int permmask[] = { | ||
8346 | S_IRUSR, S_IWUSR, S_IXUSR, | ||
8347 | S_IRGRP, S_IWGRP, S_IXGRP, | ||
8348 | S_IROTH, S_IWOTH, S_IXOTH | ||
8349 | }; | ||
8350 | |||
8202 | char *ap; | 8351 | char *ap; |
8203 | int mask; | 8352 | mode_t mask; |
8204 | int i; | 8353 | int i; |
8205 | int symbolic_mode = 0; | 8354 | int symbolic_mode = 0; |
8206 | 8355 | ||
@@ -8215,36 +8364,21 @@ umaskcmd(argc, argv) | |||
8215 | 8364 | ||
8216 | if ((ap = *argptr) == NULL) { | 8365 | if ((ap = *argptr) == NULL) { |
8217 | if (symbolic_mode) { | 8366 | if (symbolic_mode) { |
8218 | char u[4], g[4], o[4]; | 8367 | char buf[18]; |
8219 | 8368 | char *p = buf; | |
8220 | i = 0; | 8369 | for (i=0 ; i<3 ; i++) { |
8221 | if ((mask & S_IRUSR) == 0) | 8370 | int j; |
8222 | u[i++] = 'r'; | 8371 | *p++ = permuser[i]; |
8223 | if ((mask & S_IWUSR) == 0) | 8372 | *p++ = '='; |
8224 | u[i++] = 'w'; | 8373 | for (j=0 ; j<3 ; j++) { |
8225 | if ((mask & S_IXUSR) == 0) | 8374 | if ((mask & permmask[3*i+j]) == 0) { |
8226 | u[i++] = 'x'; | 8375 | *p++ = permmode[j]; |
8227 | u[i] = '\0'; | 8376 | } |
8228 | 8377 | } | |
8229 | i = 0; | 8378 | *p++ = ','; |
8230 | if ((mask & S_IRGRP) == 0) | 8379 | } |
8231 | g[i++] = 'r'; | 8380 | *--p = 0; |
8232 | if ((mask & S_IWGRP) == 0) | 8381 | puts(buf); |
8233 | g[i++] = 'w'; | ||
8234 | if ((mask & S_IXGRP) == 0) | ||
8235 | g[i++] = 'x'; | ||
8236 | g[i] = '\0'; | ||
8237 | |||
8238 | i = 0; | ||
8239 | if ((mask & S_IROTH) == 0) | ||
8240 | o[i++] = 'r'; | ||
8241 | if ((mask & S_IWOTH) == 0) | ||
8242 | o[i++] = 'w'; | ||
8243 | if ((mask & S_IXOTH) == 0) | ||
8244 | o[i++] = 'x'; | ||
8245 | o[i] = '\0'; | ||
8246 | |||
8247 | printf("u=%s,g=%s,o=%s\n", u, g, o); | ||
8248 | } else { | 8382 | } else { |
8249 | printf("%.4o\n", mask); | 8383 | printf("%.4o\n", mask); |
8250 | } | 8384 | } |
@@ -8258,17 +8392,10 @@ umaskcmd(argc, argv) | |||
8258 | } while (*++ap != '\0'); | 8392 | } while (*++ap != '\0'); |
8259 | umask(mask); | 8393 | umask(mask); |
8260 | } else { | 8394 | } else { |
8261 | void *set; | 8395 | mask = ~mask & 0777; |
8262 | 8396 | if (parse_mode(ap, &mask) == FALSE) { | |
8263 | INTOFF; | ||
8264 | if ((set = setmode(ap)) != 0) { | ||
8265 | mask = getmode(set, ~mask & 0777); | ||
8266 | ckfree(set); | ||
8267 | } | ||
8268 | INTON; | ||
8269 | if (!set) | ||
8270 | error("Illegal mode: %s", ap); | 8397 | error("Illegal mode: %s", ap); |
8271 | 8398 | } | |
8272 | umask(~mask & 0777); | 8399 | umask(~mask & 0777); |
8273 | } | 8400 | } |
8274 | } | 8401 | } |
@@ -8287,46 +8414,45 @@ umaskcmd(argc, argv) | |||
8287 | 8414 | ||
8288 | struct limits { | 8415 | struct limits { |
8289 | const char *name; | 8416 | const char *name; |
8290 | int cmd; | 8417 | short cmd; |
8291 | int factor; /* multiply by to get rlim_{cur,max} values */ | 8418 | short factor; /* multiply by to get rlim_{cur,max} values */ |
8292 | char option; | ||
8293 | }; | 8419 | }; |
8294 | 8420 | ||
8295 | static const struct limits limits[] = { | 8421 | static const struct limits limits[] = { |
8296 | #ifdef RLIMIT_CPU | 8422 | #ifdef RLIMIT_CPU |
8297 | { "time(seconds)", RLIMIT_CPU, 1, 't' }, | 8423 | { "time(seconds)", RLIMIT_CPU, 1 }, |
8298 | #endif | 8424 | #endif |
8299 | #ifdef RLIMIT_FSIZE | 8425 | #ifdef RLIMIT_FSIZE |
8300 | { "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, | 8426 | { "file(blocks)", RLIMIT_FSIZE, 512 }, |
8301 | #endif | 8427 | #endif |
8302 | #ifdef RLIMIT_DATA | 8428 | #ifdef RLIMIT_DATA |
8303 | { "data(kbytes)", RLIMIT_DATA, 1024, 'd' }, | 8429 | { "data(kbytes)", RLIMIT_DATA, 1024 }, |
8304 | #endif | 8430 | #endif |
8305 | #ifdef RLIMIT_STACK | 8431 | #ifdef RLIMIT_STACK |
8306 | { "stack(kbytes)", RLIMIT_STACK, 1024, 's' }, | 8432 | { "stack(kbytes)", RLIMIT_STACK, 1024 }, |
8307 | #endif | 8433 | #endif |
8308 | #ifdef RLIMIT_CORE | 8434 | #ifdef RLIMIT_CORE |
8309 | { "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, | 8435 | { "coredump(blocks)", RLIMIT_CORE, 512 }, |
8310 | #endif | 8436 | #endif |
8311 | #ifdef RLIMIT_RSS | 8437 | #ifdef RLIMIT_RSS |
8312 | { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' }, | 8438 | { "memory(kbytes)", RLIMIT_RSS, 1024 }, |
8313 | #endif | 8439 | #endif |
8314 | #ifdef RLIMIT_MEMLOCK | 8440 | #ifdef RLIMIT_MEMLOCK |
8315 | { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' }, | 8441 | { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024 }, |
8316 | #endif | 8442 | #endif |
8317 | #ifdef RLIMIT_NPROC | 8443 | #ifdef RLIMIT_NPROC |
8318 | { "process(processes)", RLIMIT_NPROC, 1, 'p' }, | 8444 | { "process(processes)", RLIMIT_NPROC, 1 }, |
8319 | #endif | 8445 | #endif |
8320 | #ifdef RLIMIT_NOFILE | 8446 | #ifdef RLIMIT_NOFILE |
8321 | { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, | 8447 | { "nofiles(descriptors)", RLIMIT_NOFILE, 1 }, |
8322 | #endif | 8448 | #endif |
8323 | #ifdef RLIMIT_VMEM | 8449 | #ifdef RLIMIT_VMEM |
8324 | { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' }, | 8450 | { "vmemory(kbytes)", RLIMIT_VMEM, 1024 }, |
8325 | #endif | 8451 | #endif |
8326 | #ifdef RLIMIT_SWAP | 8452 | #ifdef RLIMIT_SWAP |
8327 | { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' }, | 8453 | { "swap(kbytes)", RLIMIT_SWAP, 1024 }, |
8328 | #endif | 8454 | #endif |
8329 | { (char *) 0, 0, 0, '\0' } | 8455 | { NULL, 0, 0 } |
8330 | }; | 8456 | }; |
8331 | 8457 | ||
8332 | static int | 8458 | static int |
@@ -8334,6 +8460,7 @@ ulimitcmd(argc, argv) | |||
8334 | int argc; | 8460 | int argc; |
8335 | char **argv; | 8461 | char **argv; |
8336 | { | 8462 | { |
8463 | static const char unlimited_string[] = "unlimited"; | ||
8337 | int c; | 8464 | int c; |
8338 | rlim_t val = 0; | 8465 | rlim_t val = 0; |
8339 | enum { SOFT = 0x1, HARD = 0x2 } | 8466 | enum { SOFT = 0x1, HARD = 0x2 } |
@@ -8344,25 +8471,59 @@ ulimitcmd(argc, argv) | |||
8344 | struct rlimit limit; | 8471 | struct rlimit limit; |
8345 | 8472 | ||
8346 | what = 'f'; | 8473 | what = 'f'; |
8347 | while ((optc = nextopt("HSatfdsmcnpl")) != '\0') | 8474 | |
8348 | switch (optc) { | 8475 | while ((optc = nextopt("HSa" |
8349 | case 'H': | 8476 | #ifdef RLIMIT_CPU |
8477 | "t" | ||
8478 | #endif | ||
8479 | #ifdef RLIMIT_FSIZE | ||
8480 | "f" | ||
8481 | #endif | ||
8482 | #ifdef RLIMIT_DATA | ||
8483 | "d" | ||
8484 | #endif | ||
8485 | #ifdef RLIMIT_STACK | ||
8486 | "s" | ||
8487 | #endif | ||
8488 | #ifdef RLIMIT_CORE | ||
8489 | "c" | ||
8490 | #endif | ||
8491 | #ifdef RLIMIT_RSS | ||
8492 | "m" | ||
8493 | #endif | ||
8494 | #ifdef RLIMIT_MEMLOCK | ||
8495 | "l" | ||
8496 | #endif | ||
8497 | #ifdef RLIMIT_NPROC | ||
8498 | "p" | ||
8499 | #endif | ||
8500 | #ifdef RLIMIT_NOFILE | ||
8501 | "n" | ||
8502 | #endif | ||
8503 | #ifdef RLIMIT_VMEM | ||
8504 | "v" | ||
8505 | #endif | ||
8506 | #ifdef RLIMIT_SWAP | ||
8507 | "w" | ||
8508 | #endif | ||
8509 | )) != '\0') { | ||
8510 | if (optc == 'H') { | ||
8350 | how = HARD; | 8511 | how = HARD; |
8351 | break; | 8512 | } else if (optc == 'S') { |
8352 | case 'S': | ||
8353 | how = SOFT; | 8513 | how = SOFT; |
8354 | break; | 8514 | } else if (optc == 'a') { |
8355 | case 'a': | ||
8356 | all = 1; | 8515 | all = 1; |
8357 | break; | 8516 | } else { |
8358 | default: | ||
8359 | what = optc; | 8517 | what = optc; |
8360 | } | 8518 | } |
8519 | } | ||
8361 | 8520 | ||
8362 | for (l = limits; l->name && l->option != what; l++) | 8521 | for (l = limits; l->name; l++) { |
8363 | ; | 8522 | if(l->name[0] == what) |
8364 | if (!l->name) | 8523 | break; |
8365 | error("internal error (%c)", what); | 8524 | if(l->name[1]=='w' && what=='w') |
8525 | break; | ||
8526 | } | ||
8366 | 8527 | ||
8367 | set = *argptr ? 1 : 0; | 8528 | set = *argptr ? 1 : 0; |
8368 | if (set) { | 8529 | if (set) { |
@@ -8370,7 +8531,7 @@ ulimitcmd(argc, argv) | |||
8370 | 8531 | ||
8371 | if (all || argptr[1]) | 8532 | if (all || argptr[1]) |
8372 | error("too many arguments"); | 8533 | error("too many arguments"); |
8373 | if (strcmp(p, "unlimited") == 0) | 8534 | if (strcmp(p, unlimited_string) == 0) |
8374 | val = RLIM_INFINITY; | 8535 | val = RLIM_INFINITY; |
8375 | else { | 8536 | else { |
8376 | val = (rlim_t) 0; | 8537 | val = (rlim_t) 0; |
@@ -8386,48 +8547,42 @@ ulimitcmd(argc, argv) | |||
8386 | val *= l->factor; | 8547 | val *= l->factor; |
8387 | } | 8548 | } |
8388 | } | 8549 | } |
8550 | |||
8389 | if (all) { | 8551 | if (all) { |
8390 | for (l = limits; l->name; l++) { | 8552 | for (l = limits; l->name; l++) { |
8553 | printf("%-20s ", l->name); | ||
8391 | getrlimit(l->cmd, &limit); | 8554 | getrlimit(l->cmd, &limit); |
8555 | OUTPUT_LIMIT: | ||
8392 | if (how & SOFT) | 8556 | if (how & SOFT) |
8393 | val = limit.rlim_cur; | 8557 | val = limit.rlim_cur; |
8394 | else if (how & HARD) | 8558 | else if (how & HARD) |
8395 | val = limit.rlim_max; | 8559 | val = limit.rlim_max; |
8396 | 8560 | ||
8397 | printf("%-20s ", l->name); | ||
8398 | if (val == RLIM_INFINITY) | 8561 | if (val == RLIM_INFINITY) |
8399 | printf("unlimited\n"); | 8562 | puts(unlimited_string); |
8400 | else | 8563 | else |
8401 | { | 8564 | { |
8402 | val /= l->factor; | 8565 | val /= l->factor; |
8403 | printf("%lld\n", (long long) val); | 8566 | printf("%lld\n", (long long) val); |
8404 | } | 8567 | } |
8568 | if (!all) { | ||
8569 | break; | ||
8570 | } | ||
8405 | } | 8571 | } |
8406 | return 0; | 8572 | return 0; |
8407 | } | 8573 | } |
8408 | 8574 | ||
8409 | getrlimit(l->cmd, &limit); | 8575 | if (!set) { |
8410 | if (set) { | 8576 | goto OUTPUT_LIMIT; |
8411 | if (how & HARD) | ||
8412 | limit.rlim_max = val; | ||
8413 | if (how & SOFT) | ||
8414 | limit.rlim_cur = val; | ||
8415 | if (setrlimit(l->cmd, &limit) < 0) | ||
8416 | error("error setting limit (%m)"); | ||
8417 | } else { | ||
8418 | if (how & SOFT) | ||
8419 | val = limit.rlim_cur; | ||
8420 | else if (how & HARD) | ||
8421 | val = limit.rlim_max; | ||
8422 | |||
8423 | if (val == RLIM_INFINITY) | ||
8424 | printf("unlimited\n"); | ||
8425 | else | ||
8426 | { | ||
8427 | val /= l->factor; | ||
8428 | printf("%lld\n", (long long) val); | ||
8429 | } | ||
8430 | } | 8577 | } |
8578 | |||
8579 | getrlimit(l->cmd, &limit); | ||
8580 | if (how & HARD) | ||
8581 | limit.rlim_max = val; | ||
8582 | if (how & SOFT) | ||
8583 | limit.rlim_cur = val; | ||
8584 | if (setrlimit(l->cmd, &limit) < 0) | ||
8585 | error("error setting limit (%m)"); | ||
8431 | return 0; | 8586 | return 0; |
8432 | } | 8587 | } |
8433 | /* | 8588 | /* |
@@ -8499,16 +8654,7 @@ single_quote(const char *s) { | |||
8499 | len2 = strspn(s + len1, "'"); | 8654 | len2 = strspn(s + len1, "'"); |
8500 | 8655 | ||
8501 | len1p = len1 ? len1 + 2 : len1; | 8656 | len1p = len1 ? len1 + 2 : len1; |
8502 | switch (len2) { | 8657 | len2p = len2 + ((len2 < 2) ? len2 : 2); |
8503 | case 0: | ||
8504 | len2p = 0; | ||
8505 | break; | ||
8506 | case 1: | ||
8507 | len2p = 2; | ||
8508 | break; | ||
8509 | default: | ||
8510 | len2p = len2 + 2; | ||
8511 | } | ||
8512 | 8658 | ||
8513 | CHECKSTRSPACE(len1p + len2p + 1, p); | 8659 | CHECKSTRSPACE(len1p + len2p + 1, p); |
8514 | 8660 | ||
@@ -8520,20 +8666,16 @@ single_quote(const char *s) { | |||
8520 | s += len1; | 8666 | s += len1; |
8521 | } | 8667 | } |
8522 | 8668 | ||
8523 | switch (len2) { | 8669 | if (len2 > 1) { |
8524 | case 0: | ||
8525 | break; | ||
8526 | case 1: | ||
8527 | *q++ = '\\'; | ||
8528 | *q = '\''; | ||
8529 | s++; | ||
8530 | break; | ||
8531 | default: | ||
8532 | *q = '"'; | 8670 | *q = '"'; |
8533 | q += 1 + len2; | 8671 | q += 1 + len2; |
8534 | memcpy(q + 1, s, len2); | 8672 | memcpy(q + 1, s, len2); |
8535 | *q = '"'; | 8673 | *q = '"'; |
8536 | s += len2; | 8674 | s += len2; |
8675 | } else if (len2 == 1) { | ||
8676 | *q++ = '\\'; | ||
8677 | *q = '\''; | ||
8678 | s++; | ||
8537 | } | 8679 | } |
8538 | 8680 | ||
8539 | STADJUST(len1p + len2p, p); | 8681 | STADJUST(len1p + len2p, p); |
@@ -8565,182 +8707,357 @@ static void sizenodelist (const struct nodelist *); | |||
8565 | static struct nodelist *copynodelist (const struct nodelist *); | 8707 | static struct nodelist *copynodelist (const struct nodelist *); |
8566 | static char *nodesavestr (const char *); | 8708 | static char *nodesavestr (const char *); |
8567 | 8709 | ||
8568 | static void | 8710 | //#define CALCSIZE_TABLE |
8569 | calcsize(const union node *n) | 8711 | //#define COPYNODE_TABLE |
8712 | #if defined(CALCSIZE_TABLE) || defined(COPYNODE_TABLE) | ||
8713 | /* | ||
8714 | * To collect a lot of redundant code in case statements for copynode() | ||
8715 | * and calcsize(), we implement a mini language here. Each type of node | ||
8716 | * struct has an associated instruction sequence that operates on its | ||
8717 | * members via their offsets. The instruction are pack in unsigned chars | ||
8718 | * with format IIDDDDDE where the bits are | ||
8719 | * I : part of the instruction opcode, which are | ||
8720 | * 00 : member is a pointer to another node | ||
8721 | * 40 : member is an integer | ||
8722 | * 80 : member is a pointer to a nodelist | ||
8723 | * CC : member is a pointer to a char string | ||
8724 | * D : data - the actual offset of the member to operate on in the struct | ||
8725 | * (since we assume bit 0 is set, it is not shifted) | ||
8726 | * E : flag signaling end of instruction sequence | ||
8727 | * | ||
8728 | * WARNING: In order to handle larger offsets for 64bit archs, this code | ||
8729 | * assumes that no offset can be an odd number and stores the | ||
8730 | * end-of-instructions flag in bit 0. | ||
8731 | */ | ||
8732 | |||
8733 | #define NODE_INTEGER 0x40 | ||
8734 | #define NODE_NODELIST 0x80 | ||
8735 | #define NODE_CHARPTR 0xC0 | ||
8736 | #define NODE_NOMORE 0x01 /* Note: no offset should be odd (aligned)*/ | ||
8737 | #define NODE_MBRMASK 0xC0 | ||
8738 | #define NODE_OFFSETMASK 0x3E | ||
8739 | |||
8740 | static const unsigned char copynode_ops[35] = { | ||
8741 | #define COPYNODE_OPS0 0 | ||
8742 | offsetof(union node, nbinary.ch2), | ||
8743 | offsetof(union node, nbinary.ch1)|NODE_NOMORE, | ||
8744 | #define COPYNODE_OPS1 (COPYNODE_OPS0 + 2) | ||
8745 | offsetof(union node, ncmd.redirect), | ||
8746 | offsetof(union node, ncmd.args), | ||
8747 | offsetof(union node, ncmd.assign), | ||
8748 | offsetof(union node, ncmd.backgnd)|NODE_INTEGER|NODE_NOMORE, | ||
8749 | #define COPYNODE_OPS2 (COPYNODE_OPS1 + 4) | ||
8750 | offsetof(union node, npipe.cmdlist)|NODE_NODELIST, | ||
8751 | offsetof(union node, npipe.backgnd)|NODE_INTEGER|NODE_NOMORE, | ||
8752 | #define COPYNODE_OPS3 (COPYNODE_OPS2 + 2) | ||
8753 | offsetof(union node, nredir.redirect), | ||
8754 | offsetof(union node, nredir.n)|NODE_NOMORE, | ||
8755 | #define COPYNODE_OPS4 (COPYNODE_OPS3 + 2) | ||
8756 | offsetof(union node, nif.elsepart), | ||
8757 | offsetof(union node, nif.ifpart), | ||
8758 | offsetof(union node, nif.test)|NODE_NOMORE, | ||
8759 | #define COPYNODE_OPS5 (COPYNODE_OPS4 + 3) | ||
8760 | offsetof(union node, nfor.var)|NODE_CHARPTR, | ||
8761 | offsetof(union node, nfor.body), | ||
8762 | offsetof(union node, nfor.args)|NODE_NOMORE, | ||
8763 | #define COPYNODE_OPS6 (COPYNODE_OPS5 + 3) | ||
8764 | offsetof(union node, ncase.cases), | ||
8765 | offsetof(union node, ncase.expr)|NODE_NOMORE, | ||
8766 | #define COPYNODE_OPS7 (COPYNODE_OPS6 + 2) | ||
8767 | offsetof(union node, nclist.body), | ||
8768 | offsetof(union node, nclist.pattern), | ||
8769 | offsetof(union node, nclist.next)|NODE_NOMORE, | ||
8770 | #define COPYNODE_OPS8 (COPYNODE_OPS7 + 3) | ||
8771 | offsetof(union node, narg.backquote)|NODE_NODELIST, | ||
8772 | offsetof(union node, narg.text)|NODE_CHARPTR, | ||
8773 | offsetof(union node, narg.next)|NODE_NOMORE, | ||
8774 | #define COPYNODE_OPS9 (COPYNODE_OPS8 + 3) | ||
8775 | offsetof(union node, nfile.fname), | ||
8776 | offsetof(union node, nfile.fd)|NODE_INTEGER, | ||
8777 | offsetof(union node, nfile.next)|NODE_NOMORE, | ||
8778 | #define COPYNODE_OPS10 (COPYNODE_OPS9 + 3) | ||
8779 | offsetof(union node, ndup.vname), | ||
8780 | offsetof(union node, ndup.dupfd)|NODE_INTEGER, | ||
8781 | offsetof(union node, ndup.fd)|NODE_INTEGER, | ||
8782 | offsetof(union node, ndup.next)|NODE_NOMORE, | ||
8783 | #define COPYNODE_OPS11 (COPYNODE_OPS10 + 4) | ||
8784 | offsetof(union node, nhere.doc), | ||
8785 | offsetof(union node, nhere.fd)|NODE_INTEGER, | ||
8786 | offsetof(union node, nhere.next)|NODE_NOMORE, | ||
8787 | #define COPYNODE_OPS12 (COPYNODE_OPS11 + 3) | ||
8788 | offsetof(union node, nnot.com)|NODE_NOMORE, | ||
8789 | }; | ||
8790 | |||
8791 | #if COPYNODE_OPS12 != 34 | ||
8792 | #error COPYNODE_OPS12 is incorrect | ||
8793 | #endif | ||
8794 | |||
8795 | static const unsigned char copynode_ops_index[26] = { | ||
8796 | COPYNODE_OPS0, /* NSEMI */ | ||
8797 | COPYNODE_OPS1, /* NCMD */ | ||
8798 | COPYNODE_OPS2, /* NPIPE */ | ||
8799 | COPYNODE_OPS3, /* NREDIR */ | ||
8800 | COPYNODE_OPS3, /* NBACKGND */ | ||
8801 | COPYNODE_OPS3, /* NSUBSHELL */ | ||
8802 | COPYNODE_OPS0, /* NAND */ | ||
8803 | COPYNODE_OPS0, /* NOR */ | ||
8804 | COPYNODE_OPS4, /* NIF */ | ||
8805 | COPYNODE_OPS0, /* NWHILE */ | ||
8806 | COPYNODE_OPS0, /* NUNTIL */ | ||
8807 | COPYNODE_OPS5, /* NFOR */ | ||
8808 | COPYNODE_OPS6, /* NCASE */ | ||
8809 | COPYNODE_OPS7, /* NCLIST */ | ||
8810 | COPYNODE_OPS8, /* NDEFUN */ | ||
8811 | COPYNODE_OPS8, /* NARG */ | ||
8812 | COPYNODE_OPS9, /* NTO */ | ||
8813 | COPYNODE_OPS9, /* NFROM */ | ||
8814 | COPYNODE_OPS9, /* NFROMTO */ | ||
8815 | COPYNODE_OPS9, /* NAPPEND */ | ||
8816 | COPYNODE_OPS9, /* NTOOV */ | ||
8817 | COPYNODE_OPS10, /* NTOFD */ | ||
8818 | COPYNODE_OPS10, /* NFROMFD */ | ||
8819 | COPYNODE_OPS11, /* NHERE */ | ||
8820 | COPYNODE_OPS11, /* NXHERE */ | ||
8821 | COPYNODE_OPS12, /* NNOT */ | ||
8822 | }; | ||
8823 | |||
8824 | #if NODE_CHARPTR != NODE_MBRMASK | ||
8825 | #error NODE_CHARPTR != NODE_MBRMASK!!! | ||
8826 | #endif | ||
8827 | #endif /* defined(CALCSIZE_TABLE) || defined(COPYNODE_TABLE) */ | ||
8828 | |||
8829 | #ifdef COPYNODE_TABLE | ||
8830 | static union node * | ||
8831 | copynode(const union node *n) | ||
8570 | { | 8832 | { |
8833 | union node *new; | ||
8834 | const unsigned char *p; | ||
8835 | |||
8571 | if (n == NULL) | 8836 | if (n == NULL) |
8572 | return; | 8837 | return NULL; |
8573 | funcblocksize += nodesize[n->type]; | 8838 | new = funcblock; |
8839 | new->type = n->type; | ||
8840 | funcblock = (char *) funcblock + (int) nodesize[n->type]; | ||
8841 | p = copynode_ops + (int) copynode_ops_index[n->type]; | ||
8842 | do { | ||
8843 | char *nn = ((char *) new) + ((int)(*p & NODE_OFFSETMASK)); | ||
8844 | const char *no = ((const char *) n) + ((int)(*p & NODE_OFFSETMASK)); | ||
8845 | |||
8846 | if (!(*p & NODE_MBRMASK)) { /* standard node */ | ||
8847 | (union node *) nn = copynode((const union node *) no); | ||
8848 | } else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */ | ||
8849 | nn = nodesavestr(no); | ||
8850 | } else if (*p & NODE_NODELIST) { /* nodelist */ | ||
8851 | (struct nodelist *) nn | ||
8852 | = copynodelist((const struct nodelist *) no); | ||
8853 | } else { /* integer */ | ||
8854 | *((int *) nn) = *((int *) no); | ||
8855 | } | ||
8856 | } while (!(*p++ & NODE_NOMORE)); | ||
8857 | return new; | ||
8858 | } | ||
8859 | #else /* COPYNODE_TABLE */ | ||
8860 | static union node * | ||
8861 | copynode(const union node *n) | ||
8862 | { | ||
8863 | union node *new; | ||
8864 | |||
8865 | if (n == NULL) | ||
8866 | return NULL; | ||
8867 | new = funcblock; | ||
8868 | funcblock = (char *) funcblock + nodesize[n->type]; | ||
8574 | switch (n->type) { | 8869 | switch (n->type) { |
8575 | case NSEMI: | 8870 | case NSEMI: |
8576 | case NAND: | 8871 | case NAND: |
8577 | case NOR: | 8872 | case NOR: |
8578 | case NWHILE: | 8873 | case NWHILE: |
8579 | case NUNTIL: | 8874 | case NUNTIL: |
8580 | calcsize(n->nbinary.ch2); | 8875 | new->nbinary.ch2 = copynode(n->nbinary.ch2); |
8581 | calcsize(n->nbinary.ch1); | 8876 | new->nbinary.ch1 = copynode(n->nbinary.ch1); |
8582 | break; | 8877 | break; |
8583 | case NCMD: | 8878 | case NCMD: |
8584 | calcsize(n->ncmd.redirect); | 8879 | new->ncmd.redirect = copynode(n->ncmd.redirect); |
8585 | calcsize(n->ncmd.args); | 8880 | new->ncmd.args = copynode(n->ncmd.args); |
8586 | calcsize(n->ncmd.assign); | 8881 | new->ncmd.assign = copynode(n->ncmd.assign); |
8882 | new->ncmd.backgnd = n->ncmd.backgnd; | ||
8587 | break; | 8883 | break; |
8588 | case NPIPE: | 8884 | case NPIPE: |
8589 | sizenodelist(n->npipe.cmdlist); | 8885 | new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); |
8886 | new->npipe.backgnd = n->npipe.backgnd; | ||
8590 | break; | 8887 | break; |
8591 | case NREDIR: | 8888 | case NREDIR: |
8592 | case NBACKGND: | 8889 | case NBACKGND: |
8593 | case NSUBSHELL: | 8890 | case NSUBSHELL: |
8594 | calcsize(n->nredir.redirect); | 8891 | new->nredir.redirect = copynode(n->nredir.redirect); |
8595 | calcsize(n->nredir.n); | 8892 | new->nredir.n = copynode(n->nredir.n); |
8596 | break; | 8893 | break; |
8597 | case NIF: | 8894 | case NIF: |
8598 | calcsize(n->nif.elsepart); | 8895 | new->nif.elsepart = copynode(n->nif.elsepart); |
8599 | calcsize(n->nif.ifpart); | 8896 | new->nif.ifpart = copynode(n->nif.ifpart); |
8600 | calcsize(n->nif.test); | 8897 | new->nif.test = copynode(n->nif.test); |
8601 | break; | 8898 | break; |
8602 | case NFOR: | 8899 | case NFOR: |
8603 | funcstringsize += strlen(n->nfor.var) + 1; | 8900 | new->nfor.var = nodesavestr(n->nfor.var); |
8604 | calcsize(n->nfor.body); | 8901 | new->nfor.body = copynode(n->nfor.body); |
8605 | calcsize(n->nfor.args); | 8902 | new->nfor.args = copynode(n->nfor.args); |
8606 | break; | 8903 | break; |
8607 | case NCASE: | 8904 | case NCASE: |
8608 | calcsize(n->ncase.cases); | 8905 | new->ncase.cases = copynode(n->ncase.cases); |
8609 | calcsize(n->ncase.expr); | 8906 | new->ncase.expr = copynode(n->ncase.expr); |
8610 | break; | 8907 | break; |
8611 | case NCLIST: | 8908 | case NCLIST: |
8612 | calcsize(n->nclist.body); | 8909 | new->nclist.body = copynode(n->nclist.body); |
8613 | calcsize(n->nclist.pattern); | 8910 | new->nclist.pattern = copynode(n->nclist.pattern); |
8614 | calcsize(n->nclist.next); | 8911 | new->nclist.next = copynode(n->nclist.next); |
8615 | break; | 8912 | break; |
8616 | case NDEFUN: | 8913 | case NDEFUN: |
8617 | case NARG: | 8914 | case NARG: |
8618 | sizenodelist(n->narg.backquote); | 8915 | new->narg.backquote = copynodelist(n->narg.backquote); |
8619 | funcstringsize += strlen(n->narg.text) + 1; | 8916 | new->narg.text = nodesavestr(n->narg.text); |
8620 | calcsize(n->narg.next); | 8917 | new->narg.next = copynode(n->narg.next); |
8621 | break; | 8918 | break; |
8622 | case NTO: | 8919 | case NTO: |
8623 | case NFROM: | 8920 | case NFROM: |
8624 | case NFROMTO: | 8921 | case NFROMTO: |
8625 | case NAPPEND: | 8922 | case NAPPEND: |
8626 | case NTOOV: | 8923 | case NTOOV: |
8627 | calcsize(n->nfile.fname); | 8924 | new->nfile.fname = copynode(n->nfile.fname); |
8628 | calcsize(n->nfile.next); | 8925 | new->nfile.fd = n->nfile.fd; |
8926 | new->nfile.next = copynode(n->nfile.next); | ||
8629 | break; | 8927 | break; |
8630 | case NTOFD: | 8928 | case NTOFD: |
8631 | case NFROMFD: | 8929 | case NFROMFD: |
8632 | calcsize(n->ndup.vname); | 8930 | new->ndup.vname = copynode(n->ndup.vname); |
8633 | calcsize(n->ndup.next); | 8931 | new->ndup.dupfd = n->ndup.dupfd; |
8932 | new->ndup.fd = n->ndup.fd; | ||
8933 | new->ndup.next = copynode(n->ndup.next); | ||
8634 | break; | 8934 | break; |
8635 | case NHERE: | 8935 | case NHERE: |
8636 | case NXHERE: | 8936 | case NXHERE: |
8637 | calcsize(n->nhere.doc); | 8937 | new->nhere.doc = copynode(n->nhere.doc); |
8638 | calcsize(n->nhere.next); | 8938 | new->nhere.fd = n->nhere.fd; |
8939 | new->nhere.next = copynode(n->nhere.next); | ||
8639 | break; | 8940 | break; |
8640 | case NNOT: | 8941 | case NNOT: |
8641 | calcsize(n->nnot.com); | 8942 | new->nnot.com = copynode(n->nnot.com); |
8642 | break; | 8943 | break; |
8643 | }; | 8944 | }; |
8945 | new->type = n->type; | ||
8946 | return new; | ||
8644 | } | 8947 | } |
8948 | #endif /* COPYNODE_TABLE */ | ||
8645 | 8949 | ||
8950 | #ifdef CALCSIZE_TABLE | ||
8646 | static void | 8951 | static void |
8647 | sizenodelist(const struct nodelist *lp) | 8952 | calcsize(const union node *n) |
8648 | { | 8953 | { |
8649 | while (lp) { | 8954 | const unsigned char *p; |
8650 | funcblocksize += ALIGN(sizeof(struct nodelist)); | ||
8651 | calcsize(lp->n); | ||
8652 | lp = lp->next; | ||
8653 | } | ||
8654 | } | ||
8655 | |||
8656 | 8955 | ||
8657 | static union node * | 8956 | if (n == NULL) |
8658 | copynode(const union node *n) | 8957 | return; |
8958 | funcblocksize += (int) nodesize[n->type]; | ||
8959 | |||
8960 | p = copynode_ops + (int) copynode_ops_index[n->type]; | ||
8961 | do { | ||
8962 | const char *no = ((const char *) n) + ((int)(*p & NODE_OFFSETMASK)); | ||
8963 | |||
8964 | if (!(*p & NODE_MBRMASK)) { /* standard node */ | ||
8965 | calcsize((const union node *) no); | ||
8966 | } else if ((*p & NODE_MBRMASK) == NODE_CHARPTR) { /* string */ | ||
8967 | funcstringsize += strlen(no) + 1; | ||
8968 | } else if (*p & NODE_NODELIST) { /* nodelist */ | ||
8969 | sizenodelist((const struct nodelist *) no); | ||
8970 | } | ||
8971 | } while (!(*p++ & NODE_NOMORE)); | ||
8972 | } | ||
8973 | #else /* CALCSIZE_TABLE */ | ||
8974 | static void | ||
8975 | calcsize(const union node *n) | ||
8659 | { | 8976 | { |
8660 | union node *new; | ||
8661 | |||
8662 | if (n == NULL) | 8977 | if (n == NULL) |
8663 | return NULL; | 8978 | return; |
8664 | new = funcblock; | 8979 | funcblocksize += nodesize[n->type]; |
8665 | funcblock = (char *) funcblock + nodesize[n->type]; | ||
8666 | switch (n->type) { | 8980 | switch (n->type) { |
8667 | case NSEMI: | 8981 | case NSEMI: |
8668 | case NAND: | 8982 | case NAND: |
8669 | case NOR: | 8983 | case NOR: |
8670 | case NWHILE: | 8984 | case NWHILE: |
8671 | case NUNTIL: | 8985 | case NUNTIL: |
8672 | new->nbinary.ch2 = copynode(n->nbinary.ch2); | 8986 | calcsize(n->nbinary.ch2); |
8673 | new->nbinary.ch1 = copynode(n->nbinary.ch1); | 8987 | calcsize(n->nbinary.ch1); |
8674 | break; | 8988 | break; |
8675 | case NCMD: | 8989 | case NCMD: |
8676 | new->ncmd.redirect = copynode(n->ncmd.redirect); | 8990 | calcsize(n->ncmd.redirect); |
8677 | new->ncmd.args = copynode(n->ncmd.args); | 8991 | calcsize(n->ncmd.args); |
8678 | new->ncmd.assign = copynode(n->ncmd.assign); | 8992 | calcsize(n->ncmd.assign); |
8679 | new->ncmd.backgnd = n->ncmd.backgnd; | ||
8680 | break; | 8993 | break; |
8681 | case NPIPE: | 8994 | case NPIPE: |
8682 | new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); | 8995 | sizenodelist(n->npipe.cmdlist); |
8683 | new->npipe.backgnd = n->npipe.backgnd; | ||
8684 | break; | 8996 | break; |
8685 | case NREDIR: | 8997 | case NREDIR: |
8686 | case NBACKGND: | 8998 | case NBACKGND: |
8687 | case NSUBSHELL: | 8999 | case NSUBSHELL: |
8688 | new->nredir.redirect = copynode(n->nredir.redirect); | 9000 | calcsize(n->nredir.redirect); |
8689 | new->nredir.n = copynode(n->nredir.n); | 9001 | calcsize(n->nredir.n); |
8690 | break; | 9002 | break; |
8691 | case NIF: | 9003 | case NIF: |
8692 | new->nif.elsepart = copynode(n->nif.elsepart); | 9004 | calcsize(n->nif.elsepart); |
8693 | new->nif.ifpart = copynode(n->nif.ifpart); | 9005 | calcsize(n->nif.ifpart); |
8694 | new->nif.test = copynode(n->nif.test); | 9006 | calcsize(n->nif.test); |
8695 | break; | 9007 | break; |
8696 | case NFOR: | 9008 | case NFOR: |
8697 | new->nfor.var = nodesavestr(n->nfor.var); | 9009 | funcstringsize += strlen(n->nfor.var) + 1; |
8698 | new->nfor.body = copynode(n->nfor.body); | 9010 | calcsize(n->nfor.body); |
8699 | new->nfor.args = copynode(n->nfor.args); | 9011 | calcsize(n->nfor.args); |
8700 | break; | 9012 | break; |
8701 | case NCASE: | 9013 | case NCASE: |
8702 | new->ncase.cases = copynode(n->ncase.cases); | 9014 | calcsize(n->ncase.cases); |
8703 | new->ncase.expr = copynode(n->ncase.expr); | 9015 | calcsize(n->ncase.expr); |
8704 | break; | 9016 | break; |
8705 | case NCLIST: | 9017 | case NCLIST: |
8706 | new->nclist.body = copynode(n->nclist.body); | 9018 | calcsize(n->nclist.body); |
8707 | new->nclist.pattern = copynode(n->nclist.pattern); | 9019 | calcsize(n->nclist.pattern); |
8708 | new->nclist.next = copynode(n->nclist.next); | 9020 | calcsize(n->nclist.next); |
8709 | break; | 9021 | break; |
8710 | case NDEFUN: | 9022 | case NDEFUN: |
8711 | case NARG: | 9023 | case NARG: |
8712 | new->narg.backquote = copynodelist(n->narg.backquote); | 9024 | sizenodelist(n->narg.backquote); |
8713 | new->narg.text = nodesavestr(n->narg.text); | 9025 | funcstringsize += strlen(n->narg.text) + 1; |
8714 | new->narg.next = copynode(n->narg.next); | 9026 | calcsize(n->narg.next); |
8715 | break; | 9027 | break; |
8716 | case NTO: | 9028 | case NTO: |
8717 | case NFROM: | 9029 | case NFROM: |
8718 | case NFROMTO: | 9030 | case NFROMTO: |
8719 | case NAPPEND: | 9031 | case NAPPEND: |
8720 | case NTOOV: | 9032 | case NTOOV: |
8721 | new->nfile.fname = copynode(n->nfile.fname); | 9033 | calcsize(n->nfile.fname); |
8722 | new->nfile.fd = n->nfile.fd; | 9034 | calcsize(n->nfile.next); |
8723 | new->nfile.next = copynode(n->nfile.next); | ||
8724 | break; | 9035 | break; |
8725 | case NTOFD: | 9036 | case NTOFD: |
8726 | case NFROMFD: | 9037 | case NFROMFD: |
8727 | new->ndup.vname = copynode(n->ndup.vname); | 9038 | calcsize(n->ndup.vname); |
8728 | new->ndup.dupfd = n->ndup.dupfd; | 9039 | calcsize(n->ndup.next); |
8729 | new->ndup.fd = n->ndup.fd; | ||
8730 | new->ndup.next = copynode(n->ndup.next); | ||
8731 | break; | 9040 | break; |
8732 | case NHERE: | 9041 | case NHERE: |
8733 | case NXHERE: | 9042 | case NXHERE: |
8734 | new->nhere.doc = copynode(n->nhere.doc); | 9043 | calcsize(n->nhere.doc); |
8735 | new->nhere.fd = n->nhere.fd; | 9044 | calcsize(n->nhere.next); |
8736 | new->nhere.next = copynode(n->nhere.next); | ||
8737 | break; | 9045 | break; |
8738 | case NNOT: | 9046 | case NNOT: |
8739 | new->nnot.com = copynode(n->nnot.com); | 9047 | calcsize(n->nnot.com); |
8740 | break; | 9048 | break; |
8741 | }; | 9049 | }; |
8742 | new->type = n->type; | 9050 | } |
8743 | return new; | 9051 | #endif /* CALCSIZE_TABLE */ |
9052 | |||
9053 | static void | ||
9054 | sizenodelist(const struct nodelist *lp) | ||
9055 | { | ||
9056 | while (lp) { | ||
9057 | funcblocksize += ALIGN(sizeof(struct nodelist)); | ||
9058 | calcsize(lp->n); | ||
9059 | lp = lp->next; | ||
9060 | } | ||
8744 | } | 9061 | } |
8745 | 9062 | ||
8746 | 9063 | ||
@@ -9346,10 +9663,10 @@ static union node *command (void); | |||
9346 | static union node *simplecmd (void); | 9663 | static union node *simplecmd (void); |
9347 | static void parsefname (void); | 9664 | static void parsefname (void); |
9348 | static void parseheredoc (void); | 9665 | static void parseheredoc (void); |
9349 | static int peektoken (void); | 9666 | static char peektoken (void); |
9350 | static int readtoken (void); | 9667 | static int readtoken (void); |
9351 | static int xxreadtoken (void); | 9668 | static int xxreadtoken (void); |
9352 | static int readtoken1 (int, char const *, char *, int); | 9669 | static int readtoken1 (int, int, const char *, int); |
9353 | static int noexpand (char *); | 9670 | static int noexpand (char *); |
9354 | static void synexpect (int) __attribute__((noreturn)); | 9671 | static void synexpect (int) __attribute__((noreturn)); |
9355 | static void synerror (const char *) __attribute__((noreturn)); | 9672 | static void synerror (const char *) __attribute__((noreturn)); |
@@ -9391,7 +9708,7 @@ list(nlflag) | |||
9391 | int tok; | 9708 | int tok; |
9392 | 9709 | ||
9393 | checkkwd = 2; | 9710 | checkkwd = 2; |
9394 | if (nlflag == 0 && tokendlist[peektoken()]) | 9711 | if (nlflag == 0 && peektoken()) |
9395 | return NULL; | 9712 | return NULL; |
9396 | n1 = NULL; | 9713 | n1 = NULL; |
9397 | for (;;) { | 9714 | for (;;) { |
@@ -9434,7 +9751,7 @@ list(nlflag) | |||
9434 | tokpushback++; | 9751 | tokpushback++; |
9435 | } | 9752 | } |
9436 | checkkwd = 2; | 9753 | checkkwd = 2; |
9437 | if (tokendlist[peektoken()]) | 9754 | if (peektoken()) |
9438 | return n1; | 9755 | return n1; |
9439 | break; | 9756 | break; |
9440 | case TEOF: | 9757 | case TEOF: |
@@ -9572,7 +9889,7 @@ command() { | |||
9572 | n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; | 9889 | n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; |
9573 | n1->nbinary.ch1 = list(0); | 9890 | n1->nbinary.ch1 = list(0); |
9574 | if ((got=readtoken()) != TDO) { | 9891 | if ((got=readtoken()) != TDO) { |
9575 | TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); | 9892 | TRACE(("expecting DO got %s %s\n", tokname(got), got == TWORD ? wordtext : "")); |
9576 | synexpect(TDO); | 9893 | synexpect(TDO); |
9577 | } | 9894 | } |
9578 | n1->nbinary.ch2 = list(0); | 9895 | n1->nbinary.ch2 = list(0); |
@@ -9901,13 +10218,13 @@ parseheredoc() { | |||
9901 | } | 10218 | } |
9902 | } | 10219 | } |
9903 | 10220 | ||
9904 | static int | 10221 | static char |
9905 | peektoken() { | 10222 | peektoken() { |
9906 | int t; | 10223 | int t; |
9907 | 10224 | ||
9908 | t = readtoken(); | 10225 | t = readtoken(); |
9909 | tokpushback++; | 10226 | tokpushback++; |
9910 | return (t); | 10227 | return tokname_array[t][0]; |
9911 | } | 10228 | } |
9912 | 10229 | ||
9913 | static int | 10230 | static int |
@@ -9954,8 +10271,8 @@ top: | |||
9954 | const char *const *pp; | 10271 | const char *const *pp; |
9955 | 10272 | ||
9956 | if ((pp = findkwd(wordtext))) { | 10273 | if ((pp = findkwd(wordtext))) { |
9957 | lasttoken = t = pp - parsekwd + KWDOFFSET; | 10274 | lasttoken = t = pp - tokname_array; |
9958 | TRACE(("keyword %s recognized\n", tokname[t])); | 10275 | TRACE(("keyword %s recognized\n", tokname(t))); |
9959 | goto out; | 10276 | goto out; |
9960 | } | 10277 | } |
9961 | } | 10278 | } |
@@ -9983,9 +10300,9 @@ top: | |||
9983 | out: | 10300 | out: |
9984 | #ifdef DEBUG | 10301 | #ifdef DEBUG |
9985 | if (!alreadyseen) | 10302 | if (!alreadyseen) |
9986 | TRACE(("token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : "")); | 10303 | TRACE(("token %s %s\n", tokname(t), t == TWORD || t == TASSIGN ? wordtext : "")); |
9987 | else | 10304 | else |
9988 | TRACE(("reread token %s %s\n", tokname[t], t == TWORD || t == TASSIGN ? wordtext : "")); | 10305 | TRACE(("reread token %s %s\n", tokname(t), t == TWORD || t == TASSIGN ? wordtext : "")); |
9989 | #endif | 10306 | #endif |
9990 | return (t); | 10307 | return (t); |
9991 | } | 10308 | } |
@@ -10103,12 +10420,8 @@ breakloop: | |||
10103 | #define PARSEARITH() {goto parsearith; parsearith_return:;} | 10420 | #define PARSEARITH() {goto parsearith; parsearith_return:;} |
10104 | 10421 | ||
10105 | static int | 10422 | static int |
10106 | readtoken1(firstc, syntax, eofmark, striptabs) | 10423 | readtoken1(int firstc, int syntax, const char *eofmark, int striptabs) |
10107 | int firstc; | 10424 | { |
10108 | char const *syntax; | ||
10109 | char *eofmark; | ||
10110 | int striptabs; | ||
10111 | { | ||
10112 | int c = firstc; | 10425 | int c = firstc; |
10113 | char *out; | 10426 | char *out; |
10114 | int len; | 10427 | int len; |
@@ -10121,7 +10434,7 @@ readtoken1(firstc, syntax, eofmark, striptabs) | |||
10121 | int parenlevel; /* levels of parens in arithmetic */ | 10434 | int parenlevel; /* levels of parens in arithmetic */ |
10122 | int dqvarnest; /* levels of variables expansion within double quotes */ | 10435 | int dqvarnest; /* levels of variables expansion within double quotes */ |
10123 | int oldstyle; | 10436 | int oldstyle; |
10124 | char const *prevsyntax; /* syntax before arithmetic */ | 10437 | int prevsyntax; /* syntax before arithmetic */ |
10125 | #if __GNUC__ | 10438 | #if __GNUC__ |
10126 | /* Avoid longjmp clobbering */ | 10439 | /* Avoid longjmp clobbering */ |
10127 | (void) &out; | 10440 | (void) &out; |
@@ -10152,7 +10465,7 @@ readtoken1(firstc, syntax, eofmark, striptabs) | |||
10152 | CHECKEND(); /* set c to PEOF if at end of here document */ | 10465 | CHECKEND(); /* set c to PEOF if at end of here document */ |
10153 | for (;;) { /* until end of line or end of word */ | 10466 | for (;;) { /* until end of line or end of word */ |
10154 | CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ | 10467 | CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ |
10155 | switch(syntax[c]) { | 10468 | switch(SIT(c,syntax)) { |
10156 | case CNL: /* '\n' */ | 10469 | case CNL: /* '\n' */ |
10157 | if (syntax == BASESYNTAX) | 10470 | if (syntax == BASESYNTAX) |
10158 | goto endword; /* exit outer loop */ | 10471 | goto endword; /* exit outer loop */ |
@@ -10187,7 +10500,7 @@ readtoken1(firstc, syntax, eofmark, striptabs) | |||
10187 | if (dblquote && c != '\\' && c != '`' && c != '$' | 10500 | if (dblquote && c != '\\' && c != '`' && c != '$' |
10188 | && (c != '"' || eofmark != NULL)) | 10501 | && (c != '"' || eofmark != NULL)) |
10189 | USTPUTC('\\', out); | 10502 | USTPUTC('\\', out); |
10190 | if (SQSYNTAX[c] == CCTL) | 10503 | if (SIT(c,SQSYNTAX) == CCTL) |
10191 | USTPUTC(CTLESC, out); | 10504 | USTPUTC(CTLESC, out); |
10192 | else if (eofmark == NULL) | 10505 | else if (eofmark == NULL) |
10193 | USTPUTC(CTLQUOTEMARK, out); | 10506 | USTPUTC(CTLQUOTEMARK, out); |
@@ -10338,7 +10651,7 @@ checkend: { | |||
10338 | } | 10651 | } |
10339 | if (c == *eofmark) { | 10652 | if (c == *eofmark) { |
10340 | if (pfgets(line, sizeof line) != NULL) { | 10653 | if (pfgets(line, sizeof line) != NULL) { |
10341 | char *p, *q; | 10654 | const char *p, *q; |
10342 | 10655 | ||
10343 | p = line; | 10656 | p = line; |
10344 | for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); | 10657 | for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); |
@@ -10728,7 +11041,7 @@ noexpand(text) | |||
10728 | continue; | 11041 | continue; |
10729 | if (c == CTLESC) | 11042 | if (c == CTLESC) |
10730 | p++; | 11043 | p++; |
10731 | else if (BASESYNTAX[(int)c] == CCTL) | 11044 | else if (SIT(c,BASESYNTAX) == CCTL) |
10732 | return 0; | 11045 | return 0; |
10733 | } | 11046 | } |
10734 | return 1; | 11047 | return 1; |
@@ -10767,13 +11080,11 @@ synexpect(token) | |||
10767 | int token; | 11080 | int token; |
10768 | { | 11081 | { |
10769 | char msg[64]; | 11082 | char msg[64]; |
11083 | int l; | ||
10770 | 11084 | ||
10771 | if (token >= 0) { | 11085 | l = sprintf(msg, "%s unexpected", tokname(lasttoken)); |
10772 | snprintf(msg, 64, "%s unexpected (expecting %s)", | 11086 | if (token >= 0) |
10773 | tokname[lasttoken], tokname[token]); | 11087 | sprintf(msg+l, " (expecting %s)", tokname(token)); |
10774 | } else { | ||
10775 | snprintf(msg, 64, "%s unexpected", tokname[lasttoken]); | ||
10776 | } | ||
10777 | synerror(msg); | 11088 | synerror(msg); |
10778 | /* NOTREACHED */ | 11089 | /* NOTREACHED */ |
10779 | } | 11090 | } |
@@ -11162,435 +11473,6 @@ dup_as_newfd(from, to) | |||
11162 | return newfd; | 11473 | return newfd; |
11163 | } | 11474 | } |
11164 | 11475 | ||
11165 | /*#ifdef __weak_alias | ||
11166 | __weak_alias(getmode,_getmode) | ||
11167 | __weak_alias(setmode,_setmode) | ||
11168 | #endif*/ | ||
11169 | |||
11170 | #ifndef S_ISTXT | ||
11171 | #if defined(__GLIBC__) && __GLIBC__ >= 2 | ||
11172 | #define S_ISTXT __S_ISVTX | ||
11173 | #else | ||
11174 | #define S_ISTXT S_ISVTX | ||
11175 | #endif | ||
11176 | #endif | ||
11177 | |||
11178 | #define SET_LEN 6 /* initial # of bitcmd struct to malloc */ | ||
11179 | #define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */ | ||
11180 | |||
11181 | typedef struct bitcmd { | ||
11182 | char cmd; | ||
11183 | char cmd2; | ||
11184 | mode_t bits; | ||
11185 | } BITCMD; | ||
11186 | |||
11187 | #define CMD2_CLR 0x01 | ||
11188 | #define CMD2_SET 0x02 | ||
11189 | #define CMD2_GBITS 0x04 | ||
11190 | #define CMD2_OBITS 0x08 | ||
11191 | #define CMD2_UBITS 0x10 | ||
11192 | |||
11193 | static BITCMD *addcmd (BITCMD *, int, int, int, u_int); | ||
11194 | static void compress_mode (BITCMD *); | ||
11195 | #ifdef SETMODE_DEBUG | ||
11196 | static void dumpmode (BITCMD *); | ||
11197 | #endif | ||
11198 | |||
11199 | /* | ||
11200 | * Given the old mode and an array of bitcmd structures, apply the operations | ||
11201 | * described in the bitcmd structures to the old mode, and return the new mode. | ||
11202 | * Note that there is no '=' command; a strict assignment is just a '-' (clear | ||
11203 | * bits) followed by a '+' (set bits). | ||
11204 | */ | ||
11205 | static mode_t | ||
11206 | getmode(bbox, omode) | ||
11207 | const void *bbox; | ||
11208 | mode_t omode; | ||
11209 | { | ||
11210 | const BITCMD *set; | ||
11211 | mode_t clrval, newmode, value; | ||
11212 | |||
11213 | _DIAGASSERT(bbox != NULL); | ||
11214 | |||
11215 | set = (const BITCMD *)bbox; | ||
11216 | newmode = omode; | ||
11217 | for (value = 0;; set++) | ||
11218 | switch(set->cmd) { | ||
11219 | /* | ||
11220 | * When copying the user, group or other bits around, we "know" | ||
11221 | * where the bits are in the mode so that we can do shifts to | ||
11222 | * copy them around. If we don't use shifts, it gets real | ||
11223 | * grundgy with lots of single bit checks and bit sets. | ||
11224 | */ | ||
11225 | case 'u': | ||
11226 | value = (newmode & S_IRWXU) >> 6; | ||
11227 | goto common; | ||
11228 | |||
11229 | case 'g': | ||
11230 | value = (newmode & S_IRWXG) >> 3; | ||
11231 | goto common; | ||
11232 | |||
11233 | case 'o': | ||
11234 | value = newmode & S_IRWXO; | ||
11235 | common: if (set->cmd2 & CMD2_CLR) { | ||
11236 | clrval = | ||
11237 | (set->cmd2 & CMD2_SET) ? S_IRWXO : value; | ||
11238 | if (set->cmd2 & CMD2_UBITS) | ||
11239 | newmode &= ~((clrval<<6) & set->bits); | ||
11240 | if (set->cmd2 & CMD2_GBITS) | ||
11241 | newmode &= ~((clrval<<3) & set->bits); | ||
11242 | if (set->cmd2 & CMD2_OBITS) | ||
11243 | newmode &= ~(clrval & set->bits); | ||
11244 | } | ||
11245 | if (set->cmd2 & CMD2_SET) { | ||
11246 | if (set->cmd2 & CMD2_UBITS) | ||
11247 | newmode |= (value<<6) & set->bits; | ||
11248 | if (set->cmd2 & CMD2_GBITS) | ||
11249 | newmode |= (value<<3) & set->bits; | ||
11250 | if (set->cmd2 & CMD2_OBITS) | ||
11251 | newmode |= value & set->bits; | ||
11252 | } | ||
11253 | break; | ||
11254 | |||
11255 | case '+': | ||
11256 | newmode |= set->bits; | ||
11257 | break; | ||
11258 | |||
11259 | case '-': | ||
11260 | newmode &= ~set->bits; | ||
11261 | break; | ||
11262 | |||
11263 | case 'X': | ||
11264 | if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH)) | ||
11265 | newmode |= set->bits; | ||
11266 | break; | ||
11267 | |||
11268 | case '\0': | ||
11269 | default: | ||
11270 | #ifdef SETMODE_DEBUG | ||
11271 | (void)printf("getmode:%04o -> %04o\n", omode, newmode); | ||
11272 | #endif | ||
11273 | return (newmode); | ||
11274 | } | ||
11275 | } | ||
11276 | |||
11277 | #define ADDCMD(a, b, c, d) do { \ | ||
11278 | if (set >= endset) { \ | ||
11279 | BITCMD *newset; \ | ||
11280 | setlen += SET_LEN_INCR; \ | ||
11281 | newset = realloc(saveset, sizeof(BITCMD) * setlen); \ | ||
11282 | if (newset == NULL) { \ | ||
11283 | free(saveset); \ | ||
11284 | return (NULL); \ | ||
11285 | } \ | ||
11286 | set = newset + (set - saveset); \ | ||
11287 | saveset = newset; \ | ||
11288 | endset = newset + (setlen - 2); \ | ||
11289 | } \ | ||
11290 | set = addcmd(set, (a), (b), (c), (d)); \ | ||
11291 | } while (/*CONSTCOND*/0) | ||
11292 | |||
11293 | #define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) | ||
11294 | |||
11295 | static void * | ||
11296 | setmode(p) | ||
11297 | const char *p; | ||
11298 | { | ||
11299 | int perm, who; | ||
11300 | char op, *ep; | ||
11301 | BITCMD *set, *saveset, *endset; | ||
11302 | sigset_t mysigset, sigoset; | ||
11303 | mode_t mask; | ||
11304 | int equalopdone = 0; /* pacify gcc */ | ||
11305 | int permXbits, setlen; | ||
11306 | |||
11307 | if (!*p) | ||
11308 | return (NULL); | ||
11309 | |||
11310 | /* | ||
11311 | * Get a copy of the mask for the permissions that are mask relative. | ||
11312 | * Flip the bits, we want what's not set. Since it's possible that | ||
11313 | * the caller is opening files inside a signal handler, protect them | ||
11314 | * as best we can. | ||
11315 | */ | ||
11316 | sigfillset(&mysigset); | ||
11317 | (void)sigprocmask(SIG_BLOCK, &mysigset, &sigoset); | ||
11318 | (void)umask(mask = umask(0)); | ||
11319 | mask = ~mask; | ||
11320 | (void)sigprocmask(SIG_SETMASK, &sigoset, NULL); | ||
11321 | |||
11322 | setlen = SET_LEN + 2; | ||
11323 | |||
11324 | if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL) | ||
11325 | return (NULL); | ||
11326 | saveset = set; | ||
11327 | endset = set + (setlen - 2); | ||
11328 | |||
11329 | /* | ||
11330 | * If an absolute number, get it and return; disallow non-octal digits | ||
11331 | * or illegal bits. | ||
11332 | */ | ||
11333 | if (is_digit((unsigned char)*p)) { | ||
11334 | perm = (mode_t)strtol(p, &ep, 8); | ||
11335 | if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) { | ||
11336 | free(saveset); | ||
11337 | return (NULL); | ||
11338 | } | ||
11339 | ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); | ||
11340 | set->cmd = 0; | ||
11341 | return (saveset); | ||
11342 | } | ||
11343 | |||
11344 | /* | ||
11345 | * Build list of structures to set/clear/copy bits as described by | ||
11346 | * each clause of the symbolic mode. | ||
11347 | */ | ||
11348 | for (;;) { | ||
11349 | /* First, find out which bits might be modified. */ | ||
11350 | for (who = 0;; ++p) { | ||
11351 | switch (*p) { | ||
11352 | case 'a': | ||
11353 | who |= STANDARD_BITS; | ||
11354 | break; | ||
11355 | case 'u': | ||
11356 | who |= S_ISUID|S_IRWXU; | ||
11357 | break; | ||
11358 | case 'g': | ||
11359 | who |= S_ISGID|S_IRWXG; | ||
11360 | break; | ||
11361 | case 'o': | ||
11362 | who |= S_IRWXO; | ||
11363 | break; | ||
11364 | default: | ||
11365 | goto getop; | ||
11366 | } | ||
11367 | } | ||
11368 | |||
11369 | getop: if ((op = *p++) != '+' && op != '-' && op != '=') { | ||
11370 | free(saveset); | ||
11371 | return (NULL); | ||
11372 | } | ||
11373 | if (op == '=') | ||
11374 | equalopdone = 0; | ||
11375 | |||
11376 | who &= ~S_ISTXT; | ||
11377 | for (perm = 0, permXbits = 0;; ++p) { | ||
11378 | switch (*p) { | ||
11379 | case 'r': | ||
11380 | perm |= S_IRUSR|S_IRGRP|S_IROTH; | ||
11381 | break; | ||
11382 | case 's': | ||
11383 | /* | ||
11384 | * If specific bits where requested and | ||
11385 | * only "other" bits ignore set-id. | ||
11386 | */ | ||
11387 | if (who == 0 || (who & ~S_IRWXO)) | ||
11388 | perm |= S_ISUID|S_ISGID; | ||
11389 | break; | ||
11390 | case 't': | ||
11391 | /* | ||
11392 | * If specific bits where requested and | ||
11393 | * only "other" bits ignore set-id. | ||
11394 | */ | ||
11395 | if (who == 0 || (who & ~S_IRWXO)) { | ||
11396 | who |= S_ISTXT; | ||
11397 | perm |= S_ISTXT; | ||
11398 | } | ||
11399 | break; | ||
11400 | case 'w': | ||
11401 | perm |= S_IWUSR|S_IWGRP|S_IWOTH; | ||
11402 | break; | ||
11403 | case 'X': | ||
11404 | permXbits = S_IXUSR|S_IXGRP|S_IXOTH; | ||
11405 | break; | ||
11406 | case 'x': | ||
11407 | perm |= S_IXUSR|S_IXGRP|S_IXOTH; | ||
11408 | break; | ||
11409 | case 'u': | ||
11410 | case 'g': | ||
11411 | case 'o': | ||
11412 | /* | ||
11413 | * When ever we hit 'u', 'g', or 'o', we have | ||
11414 | * to flush out any partial mode that we have, | ||
11415 | * and then do the copying of the mode bits. | ||
11416 | */ | ||
11417 | if (perm) { | ||
11418 | ADDCMD(op, who, perm, mask); | ||
11419 | perm = 0; | ||
11420 | } | ||
11421 | if (op == '=') | ||
11422 | equalopdone = 1; | ||
11423 | if (op == '+' && permXbits) { | ||
11424 | ADDCMD('X', who, permXbits, mask); | ||
11425 | permXbits = 0; | ||
11426 | } | ||
11427 | ADDCMD(*p, who, op, mask); | ||
11428 | break; | ||
11429 | |||
11430 | default: | ||
11431 | /* | ||
11432 | * Add any permissions that we haven't already | ||
11433 | * done. | ||
11434 | */ | ||
11435 | if (perm || (op == '=' && !equalopdone)) { | ||
11436 | if (op == '=') | ||
11437 | equalopdone = 1; | ||
11438 | ADDCMD(op, who, perm, mask); | ||
11439 | perm = 0; | ||
11440 | } | ||
11441 | if (permXbits) { | ||
11442 | ADDCMD('X', who, permXbits, mask); | ||
11443 | permXbits = 0; | ||
11444 | } | ||
11445 | goto apply; | ||
11446 | } | ||
11447 | } | ||
11448 | |||
11449 | apply: if (!*p) | ||
11450 | break; | ||
11451 | if (*p != ',') | ||
11452 | goto getop; | ||
11453 | ++p; | ||
11454 | } | ||
11455 | set->cmd = 0; | ||
11456 | #ifdef SETMODE_DEBUG | ||
11457 | (void)printf("Before compress_mode()\n"); | ||
11458 | dumpmode(saveset); | ||
11459 | #endif | ||
11460 | compress_mode(saveset); | ||
11461 | #ifdef SETMODE_DEBUG | ||
11462 | (void)printf("After compress_mode()\n"); | ||
11463 | dumpmode(saveset); | ||
11464 | #endif | ||
11465 | return (saveset); | ||
11466 | } | ||
11467 | |||
11468 | static BITCMD * | ||
11469 | addcmd(set, op, who, oparg, mask) | ||
11470 | BITCMD *set; | ||
11471 | int oparg, who; | ||
11472 | int op; | ||
11473 | u_int mask; | ||
11474 | { | ||
11475 | |||
11476 | _DIAGASSERT(set != NULL); | ||
11477 | |||
11478 | switch (op) { | ||
11479 | case '=': | ||
11480 | set->cmd = '-'; | ||
11481 | set->bits = who ? who : STANDARD_BITS; | ||
11482 | set++; | ||
11483 | |||
11484 | op = '+'; | ||
11485 | /* FALLTHROUGH */ | ||
11486 | case '+': | ||
11487 | case '-': | ||
11488 | case 'X': | ||
11489 | set->cmd = op; | ||
11490 | set->bits = (who ? who : mask) & oparg; | ||
11491 | break; | ||
11492 | |||
11493 | case 'u': | ||
11494 | case 'g': | ||
11495 | case 'o': | ||
11496 | set->cmd = op; | ||
11497 | if (who) { | ||
11498 | set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) | | ||
11499 | ((who & S_IRGRP) ? CMD2_GBITS : 0) | | ||
11500 | ((who & S_IROTH) ? CMD2_OBITS : 0); | ||
11501 | set->bits = (mode_t)~0; | ||
11502 | } else { | ||
11503 | set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS; | ||
11504 | set->bits = mask; | ||
11505 | } | ||
11506 | |||
11507 | if (oparg == '+') | ||
11508 | set->cmd2 |= CMD2_SET; | ||
11509 | else if (oparg == '-') | ||
11510 | set->cmd2 |= CMD2_CLR; | ||
11511 | else if (oparg == '=') | ||
11512 | set->cmd2 |= CMD2_SET|CMD2_CLR; | ||
11513 | break; | ||
11514 | } | ||
11515 | return (set + 1); | ||
11516 | } | ||
11517 | |||
11518 | #ifdef SETMODE_DEBUG | ||
11519 | static void | ||
11520 | dumpmode(set) | ||
11521 | BITCMD *set; | ||
11522 | { | ||
11523 | |||
11524 | _DIAGASSERT(set != NULL); | ||
11525 | |||
11526 | for (; set->cmd; ++set) | ||
11527 | (void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", | ||
11528 | set->cmd, set->bits, set->cmd2 ? " cmd2:" : "", | ||
11529 | set->cmd2 & CMD2_CLR ? " CLR" : "", | ||
11530 | set->cmd2 & CMD2_SET ? " SET" : "", | ||
11531 | set->cmd2 & CMD2_UBITS ? " UBITS" : "", | ||
11532 | set->cmd2 & CMD2_GBITS ? " GBITS" : "", | ||
11533 | set->cmd2 & CMD2_OBITS ? " OBITS" : ""); | ||
11534 | } | ||
11535 | #endif | ||
11536 | |||
11537 | /* | ||
11538 | * Given an array of bitcmd structures, compress by compacting consecutive | ||
11539 | * '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u', | ||
11540 | * 'g' and 'o' commands continue to be separate. They could probably be | ||
11541 | * compacted, but it's not worth the effort. | ||
11542 | */ | ||
11543 | static void | ||
11544 | compress_mode(set) | ||
11545 | BITCMD *set; | ||
11546 | { | ||
11547 | BITCMD *nset; | ||
11548 | int setbits, clrbits, Xbits, op; | ||
11549 | |||
11550 | _DIAGASSERT(set != NULL); | ||
11551 | |||
11552 | for (nset = set;;) { | ||
11553 | /* Copy over any 'u', 'g' and 'o' commands. */ | ||
11554 | while ((op = nset->cmd) != '+' && op != '-' && op != 'X') { | ||
11555 | *set++ = *nset++; | ||
11556 | if (!op) | ||
11557 | return; | ||
11558 | } | ||
11559 | |||
11560 | for (setbits = clrbits = Xbits = 0;; nset++) { | ||
11561 | if ((op = nset->cmd) == '-') { | ||
11562 | clrbits |= nset->bits; | ||
11563 | setbits &= ~nset->bits; | ||
11564 | Xbits &= ~nset->bits; | ||
11565 | } else if (op == '+') { | ||
11566 | setbits |= nset->bits; | ||
11567 | clrbits &= ~nset->bits; | ||
11568 | Xbits &= ~nset->bits; | ||
11569 | } else if (op == 'X') | ||
11570 | Xbits |= nset->bits & ~setbits; | ||
11571 | else | ||
11572 | break; | ||
11573 | } | ||
11574 | if (clrbits) { | ||
11575 | set->cmd = '-'; | ||
11576 | set->cmd2 = 0; | ||
11577 | set->bits = clrbits; | ||
11578 | set++; | ||
11579 | } | ||
11580 | if (setbits) { | ||
11581 | set->cmd = '+'; | ||
11582 | set->cmd2 = 0; | ||
11583 | set->bits = setbits; | ||
11584 | set++; | ||
11585 | } | ||
11586 | if (Xbits) { | ||
11587 | set->cmd = 'X'; | ||
11588 | set->cmd2 = 0; | ||
11589 | set->bits = Xbits; | ||
11590 | set++; | ||
11591 | } | ||
11592 | } | ||
11593 | } | ||
11594 | #ifdef DEBUG | 11476 | #ifdef DEBUG |
11595 | static void shtree (union node *, int, char *, FILE*); | 11477 | static void shtree (union node *, int, char *, FILE*); |
11596 | static void shcmd (union node *, FILE *); | 11478 | static void shcmd (union node *, FILE *); |
@@ -11683,6 +11565,16 @@ shcmd(cmd, fp) | |||
11683 | for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { | 11565 | for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { |
11684 | if (! first) | 11566 | if (! first) |
11685 | putchar(' '); | 11567 | putchar(' '); |
11568 | #if 1 | ||
11569 | s = "*error*"; | ||
11570 | dftfd = 0; | ||
11571 | if ((np->nfile.type <= NFROMFD) && (np->nfile.type >= NTO)) { | ||
11572 | s = redir_strings[np->nfile.type - NTO]; | ||
11573 | if (*s == '>') { | ||
11574 | dftfd = 1; | ||
11575 | } | ||
11576 | } | ||
11577 | #else | ||
11686 | switch (np->nfile.type) { | 11578 | switch (np->nfile.type) { |
11687 | case NTO: s = ">"; dftfd = 1; break; | 11579 | case NTO: s = ">"; dftfd = 1; break; |
11688 | case NAPPEND: s = ">>"; dftfd = 1; break; | 11580 | case NAPPEND: s = ">>"; dftfd = 1; break; |
@@ -11693,6 +11585,7 @@ shcmd(cmd, fp) | |||
11693 | case NFROMTO: s = "<>"; dftfd = 0; break; | 11585 | case NFROMTO: s = "<>"; dftfd = 0; break; |
11694 | default: s = "*error*"; dftfd = 0; break; | 11586 | default: s = "*error*"; dftfd = 0; break; |
11695 | } | 11587 | } |
11588 | #endif | ||
11696 | if (np->nfile.fd != dftfd) | 11589 | if (np->nfile.fd != dftfd) |
11697 | fprintf(fp, "%d", np->nfile.fd); | 11590 | fprintf(fp, "%d", np->nfile.fd); |
11698 | fputs(s, fp); | 11591 | fputs(s, fp); |
@@ -12094,16 +11987,8 @@ setsignal(int signo) | |||
12094 | } | 11987 | } |
12095 | if (*t == S_HARD_IGN || *t == action) | 11988 | if (*t == S_HARD_IGN || *t == action) |
12096 | return; | 11989 | return; |
12097 | switch (action) { | 11990 | act.sa_handler = ((action == S_CATCH) ? onsig |
12098 | case S_CATCH: | 11991 | : ((action == S_IGN) ? SIG_IGN : SIG_DFL)); |
12099 | act.sa_handler = onsig; | ||
12100 | break; | ||
12101 | case S_IGN: | ||
12102 | act.sa_handler = SIG_IGN; | ||
12103 | break; | ||
12104 | default: | ||
12105 | act.sa_handler = SIG_DFL; | ||
12106 | } | ||
12107 | *t = action; | 11992 | *t = action; |
12108 | act.sa_flags = 0; | 11993 | act.sa_flags = 0; |
12109 | sigemptyset(&act.sa_mask); | 11994 | sigemptyset(&act.sa_mask); |
@@ -12785,7 +12670,7 @@ findvar(struct var **vpp, const char *name) | |||
12785 | /* | 12670 | /* |
12786 | * Copyright (c) 1999 Herbert Xu <herbert@debian.org> | 12671 | * Copyright (c) 1999 Herbert Xu <herbert@debian.org> |
12787 | * This file contains code for the times builtin. | 12672 | * This file contains code for the times builtin. |
12788 | * $Id: ash.c,v 1.19 2001/08/10 18:42:04 andersen Exp $ | 12673 | * $Id: ash.c,v 1.20 2001/08/10 19:36:07 mjn3 Exp $ |
12789 | */ | 12674 | */ |
12790 | static int timescmd (int argc, char **argv) | 12675 | static int timescmd (int argc, char **argv) |
12791 | { | 12676 | { |