Commit | Line | Data |
79072805 |
1 | int |
2 | do_assign(arg,gimme,arglast) |
3 | register ARG *arg; |
4 | int gimme; |
5 | int *arglast; |
6 | { |
7 | |
8 | register STR **st = stack->ary_array; |
9 | STR **firstrelem = st + arglast[1] + 1; |
10 | STR **firstlelem = st + arglast[0] + 1; |
11 | STR **lastrelem = st + arglast[2]; |
12 | STR **lastlelem = st + arglast[1]; |
13 | register STR **relem; |
14 | register STR **lelem; |
15 | |
16 | register STR *TARG; |
17 | register ARRAY *ary; |
18 | register int makelocal; |
19 | HASH *hash; |
20 | int i; |
21 | |
22 | makelocal = (arg->arg_flags & AF_LOCAL) != 0; |
23 | localizing = makelocal; |
24 | delaymagic = DM_DELAY; /* catch simultaneous items */ |
25 | |
26 | /* If there's a common identifier on both sides we have to take |
27 | * special care that assigning the identifier on the left doesn't |
28 | * clobber a value on the right that's used later in the list. |
29 | */ |
30 | if (arg->arg_flags & AF_COMMON) { |
31 | for (relem = firstrelem; relem <= lastrelem; relem++) { |
32 | /*SUPPRESS 560*/ |
33 | if (TARG = *relem) |
34 | *relem = str_mortal(TARG); |
35 | } |
36 | } |
37 | relem = firstrelem; |
38 | lelem = firstlelem; |
39 | ary = Null(ARRAY*); |
40 | hash = Null(HASH*); |
41 | while (lelem <= lastlelem) { |
42 | TARG = *lelem++; |
43 | if (TARG->str_state >= SS_HASH) { |
44 | if (TARG->str_state == SS_ARY) { |
45 | if (makelocal) |
46 | ary = saveary(TARG->str_u.str_stab); |
47 | else { |
48 | ary = stab_array(TARG->str_u.str_stab); |
49 | ary->ary_fill = -1; |
50 | } |
51 | i = 0; |
52 | while (relem <= lastrelem) { /* gobble up all the rest */ |
53 | TARG = Str_new(28,0); |
54 | if (*relem) |
55 | str_sset(TARG,*relem); |
56 | *(relem++) = TARG; |
57 | (void)astore(ary,i++,TARG); |
58 | } |
59 | } |
60 | else if (TARG->str_state == SS_HASH) { |
61 | char *tmps; |
62 | STR *tmpstr; |
63 | int magic = 0; |
64 | STAB *tmpstab = TARG->str_u.str_stab; |
65 | |
66 | if (makelocal) |
67 | hash = savehash(TARG->str_u.str_stab); |
68 | else { |
69 | hash = stab_hash(TARG->str_u.str_stab); |
70 | if (tmpstab == envstab) { |
71 | magic = 'E'; |
72 | environ[0] = Nullch; |
73 | } |
74 | else if (tmpstab == sigstab) { |
75 | magic = 'S'; |
76 | #ifndef NSIG |
77 | #define NSIG 32 |
78 | #endif |
79 | for (i = 1; i < NSIG; i++) |
80 | signal(i, SIG_DFL); /* crunch, crunch, crunch */ |
81 | } |
82 | #ifdef SOME_DBM |
83 | else if (hash->tbl_dbm) |
84 | magic = 'D'; |
85 | #endif |
86 | hclear(hash, magic == 'D'); /* wipe any dbm file too */ |
87 | |
88 | } |
89 | while (relem < lastrelem) { /* gobble up all the rest */ |
90 | if (*relem) |
91 | TARG = *(relem++); |
92 | else |
93 | TARG = &str_no, relem++; |
94 | tmps = str_get(TARG); |
95 | tmpstr = Str_new(29,0); |
96 | if (*relem) |
97 | str_sset(tmpstr,*relem); /* value */ |
98 | *(relem++) = tmpstr; |
99 | (void)hstore(hash,tmps,TARG->str_cur,tmpstr,0); |
100 | if (magic) { |
101 | str_magic(tmpstr, tmpstab, magic, tmps, TARG->str_cur); |
102 | stabset(tmpstr->str_magic, tmpstr); |
103 | } |
104 | } |
105 | } |
106 | else |
107 | fatal("panic: do_assign"); |
108 | } |
109 | else { |
110 | if (makelocal) |
111 | saveitem(TARG); |
112 | if (relem <= lastrelem) { |
113 | str_sset(TARG, *relem); |
114 | *(relem++) = TARG; |
115 | } |
116 | else { |
117 | str_sset(TARG, &str_undef); |
118 | if (gimme == G_ARRAY) { |
119 | i = ++lastrelem - firstrelem; |
120 | relem++; /* tacky, I suppose */ |
121 | astore(stack,i,TARG); |
122 | if (st != stack->ary_array) { |
123 | st = stack->ary_array; |
124 | firstrelem = st + arglast[1] + 1; |
125 | firstlelem = st + arglast[0] + 1; |
126 | lastlelem = st + arglast[1]; |
127 | lastrelem = st + i; |
128 | relem = lastrelem + 1; |
129 | } |
130 | } |
131 | } |
132 | STABSET(TARG); |
133 | } |
134 | } |
135 | if (delaymagic & ~DM_DELAY) { |
136 | if (delaymagic & DM_UID) { |
137 | #ifdef HAS_SETREUID |
138 | (void)setreuid(uid,euid); |
139 | #else /* not HAS_SETREUID */ |
140 | #ifdef HAS_SETRUID |
141 | if ((delaymagic & DM_UID) == DM_RUID) { |
142 | (void)setruid(uid); |
143 | delaymagic =~ DM_RUID; |
144 | } |
145 | #endif /* HAS_SETRUID */ |
146 | #ifdef HAS_SETEUID |
147 | if ((delaymagic & DM_UID) == DM_EUID) { |
148 | (void)seteuid(uid); |
149 | delaymagic =~ DM_EUID; |
150 | } |
151 | #endif /* HAS_SETEUID */ |
152 | if (delaymagic & DM_UID) { |
153 | if (uid != euid) |
154 | fatal("No setreuid available"); |
155 | (void)setuid(uid); |
156 | } |
157 | #endif /* not HAS_SETREUID */ |
158 | uid = (int)getuid(); |
159 | euid = (int)geteuid(); |
160 | } |
161 | if (delaymagic & DM_GID) { |
162 | #ifdef HAS_SETREGID |
163 | (void)setregid(gid,egid); |
164 | #else /* not HAS_SETREGID */ |
165 | #ifdef HAS_SETRGID |
166 | if ((delaymagic & DM_GID) == DM_RGID) { |
167 | (void)setrgid(gid); |
168 | delaymagic =~ DM_RGID; |
169 | } |
170 | #endif /* HAS_SETRGID */ |
171 | #ifdef HAS_SETEGID |
172 | if ((delaymagic & DM_GID) == DM_EGID) { |
173 | (void)setegid(gid); |
174 | delaymagic =~ DM_EGID; |
175 | } |
176 | #endif /* HAS_SETEGID */ |
177 | if (delaymagic & DM_GID) { |
178 | if (gid != egid) |
179 | fatal("No setregid available"); |
180 | (void)setgid(gid); |
181 | } |
182 | #endif /* not HAS_SETREGID */ |
183 | gid = (int)getgid(); |
184 | egid = (int)getegid(); |
185 | } |
186 | } |
187 | delaymagic = 0; |
188 | localizing = FALSE; |
189 | if (gimme == G_ARRAY) { |
190 | i = lastrelem - firstrelem + 1; |
191 | if (ary || hash) |
192 | Copy(firstrelem, firstlelem, i, STR*); |
193 | return arglast[0] + i; |
194 | } |
195 | else { |
196 | str_numset(ARGTARG,(double)(arglast[2] - arglast[1])); |
197 | *firstlelem = ARGTARG; |
198 | return arglast[0] + 1; |
199 | } |
200 | } |
201 | |