Blame


1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 1d2c3c39 2014-04-19 rsc #include <bio.h>
4 b3994ec5 2003-12-11 devnull #include <draw.h>
5 b3994ec5 2003-12-11 devnull #include <thread.h>
6 b3994ec5 2003-12-11 devnull #include <cursor.h>
7 b3994ec5 2003-12-11 devnull #include <mouse.h>
8 b3994ec5 2003-12-11 devnull #include <keyboard.h>
9 b3994ec5 2003-12-11 devnull #include <frame.h>
10 b3994ec5 2003-12-11 devnull #include <fcall.h>
11 b3994ec5 2003-12-11 devnull #include <plumb.h>
12 67dbeee5 2017-10-10 rsc #include <libsec.h>
13 05636f83 2005-01-04 devnull #include <9pclient.h>
14 b3994ec5 2003-12-11 devnull #include "dat.h"
15 b3994ec5 2003-12-11 devnull #include "fns.h"
16 b3994ec5 2003-12-11 devnull
17 b3994ec5 2003-12-11 devnull Buffer snarfbuf;
18 9952c0eb 2007-06-15 devnull
19 9952c0eb 2007-06-15 devnull /*
20 9952c0eb 2007-06-15 devnull * These functions get called as:
21 9952c0eb 2007-06-15 devnull *
22 9952c0eb 2007-06-15 devnull * fn(et, t, argt, flag1, flag1, flag2, s, n);
23 9952c0eb 2007-06-15 devnull *
24 9952c0eb 2007-06-15 devnull * Where the arguments are:
25 9952c0eb 2007-06-15 devnull *
26 9952c0eb 2007-06-15 devnull * et: the Text* in which the executing event (click) occurred
27 9952c0eb 2007-06-15 devnull * t: the Text* containing the current selection (Edit, Cut, Snarf, Paste)
28 9952c0eb 2007-06-15 devnull * argt: the Text* containing the argument for a 2-1 click.
29 9952c0eb 2007-06-15 devnull * e->flag1: from Exectab entry
30 9952c0eb 2007-06-15 devnull * e->flag2: from Exectab entry
31 9952c0eb 2007-06-15 devnull * s: the command line remainder (e.g., "x" if executing "Dump x")
32 9952c0eb 2007-06-15 devnull * n: length of s (s is *not* NUL-terminated)
33 9952c0eb 2007-06-15 devnull */
34 b3994ec5 2003-12-11 devnull
35 6dd68c9a 2005-01-23 devnull void doabort(Text*, Text*, Text*, int, int, Rune*, int);
36 b3994ec5 2003-12-11 devnull void del(Text*, Text*, Text*, int, int, Rune*, int);
37 b3994ec5 2003-12-11 devnull void delcol(Text*, Text*, Text*, int, int, Rune*, int);
38 62c14158 2004-04-08 devnull void dotfiles(Text*, Text*, Text*, int, int, Rune*, int);
39 b3994ec5 2003-12-11 devnull void dump(Text*, Text*, Text*, int, int, Rune*, int);
40 b3994ec5 2003-12-11 devnull void edit(Text*, Text*, Text*, int, int, Rune*, int);
41 b3994ec5 2003-12-11 devnull void xexit(Text*, Text*, Text*, int, int, Rune*, int);
42 b3994ec5 2003-12-11 devnull void fontx(Text*, Text*, Text*, int, int, Rune*, int);
43 b3994ec5 2003-12-11 devnull void get(Text*, Text*, Text*, int, int, Rune*, int);
44 b3994ec5 2003-12-11 devnull void id(Text*, Text*, Text*, int, int, Rune*, int);
45 b3994ec5 2003-12-11 devnull void incl(Text*, Text*, Text*, int, int, Rune*, int);
46 8ad51794 2004-03-25 devnull void indent(Text*, Text*, Text*, int, int, Rune*, int);
47 b3994ec5 2003-12-11 devnull void xkill(Text*, Text*, Text*, int, int, Rune*, int);
48 b3994ec5 2003-12-11 devnull void local(Text*, Text*, Text*, int, int, Rune*, int);
49 b3994ec5 2003-12-11 devnull void look(Text*, Text*, Text*, int, int, Rune*, int);
50 b3994ec5 2003-12-11 devnull void newcol(Text*, Text*, Text*, int, int, Rune*, int);
51 b3994ec5 2003-12-11 devnull void paste(Text*, Text*, Text*, int, int, Rune*, int);
52 b3994ec5 2003-12-11 devnull void put(Text*, Text*, Text*, int, int, Rune*, int);
53 b3994ec5 2003-12-11 devnull void putall(Text*, Text*, Text*, int, int, Rune*, int);
54 b3994ec5 2003-12-11 devnull void sendx(Text*, Text*, Text*, int, int, Rune*, int);
55 b3994ec5 2003-12-11 devnull void sort(Text*, Text*, Text*, int, int, Rune*, int);
56 b3994ec5 2003-12-11 devnull void tab(Text*, Text*, Text*, int, int, Rune*, int);
57 b3994ec5 2003-12-11 devnull void zeroxx(Text*, Text*, Text*, int, int, Rune*, int);
58 b3994ec5 2003-12-11 devnull
59 b3994ec5 2003-12-11 devnull typedef struct Exectab Exectab;
60 b3994ec5 2003-12-11 devnull struct Exectab
61 b3994ec5 2003-12-11 devnull {
62 b3994ec5 2003-12-11 devnull Rune *name;
63 b3994ec5 2003-12-11 devnull void (*fn)(Text*, Text*, Text*, int, int, Rune*, int);
64 b3994ec5 2003-12-11 devnull int mark;
65 b3994ec5 2003-12-11 devnull int flag1;
66 b3994ec5 2003-12-11 devnull int flag2;
67 b3994ec5 2003-12-11 devnull };
68 b3994ec5 2003-12-11 devnull
69 6dd68c9a 2005-01-23 devnull static Rune LAbort[] = { 'A', 'b', 'o', 'r', 't', 0 };
70 b3994ec5 2003-12-11 devnull static Rune LCut[] = { 'C', 'u', 't', 0 };
71 b3994ec5 2003-12-11 devnull static Rune LDel[] = { 'D', 'e', 'l', 0 };
72 b3994ec5 2003-12-11 devnull static Rune LDelcol[] = { 'D', 'e', 'l', 'c', 'o', 'l', 0 };
73 b3994ec5 2003-12-11 devnull static Rune LDelete[] = { 'D', 'e', 'l', 'e', 't', 'e', 0 };
74 b3994ec5 2003-12-11 devnull static Rune LDump[] = { 'D', 'u', 'm', 'p', 0 };
75 b3994ec5 2003-12-11 devnull static Rune LEdit[] = { 'E', 'd', 'i', 't', 0 };
76 b3994ec5 2003-12-11 devnull static Rune LExit[] = { 'E', 'x', 'i', 't', 0 };
77 b3994ec5 2003-12-11 devnull static Rune LFont[] = { 'F', 'o', 'n', 't', 0 };
78 b3994ec5 2003-12-11 devnull static Rune LGet[] = { 'G', 'e', 't', 0 };
79 b3994ec5 2003-12-11 devnull static Rune LID[] = { 'I', 'D', 0 };
80 b3994ec5 2003-12-11 devnull static Rune LIncl[] = { 'I', 'n', 'c', 'l', 0 };
81 8ad51794 2004-03-25 devnull static Rune LIndent[] = { 'I', 'n', 'd', 'e', 'n', 't', 0 };
82 b3994ec5 2003-12-11 devnull static Rune LKill[] = { 'K', 'i', 'l', 'l', 0 };
83 b3994ec5 2003-12-11 devnull static Rune LLoad[] = { 'L', 'o', 'a', 'd', 0 };
84 b3994ec5 2003-12-11 devnull static Rune LLocal[] = { 'L', 'o', 'c', 'a', 'l', 0 };
85 b3994ec5 2003-12-11 devnull static Rune LLook[] = { 'L', 'o', 'o', 'k', 0 };
86 b3994ec5 2003-12-11 devnull static Rune LNew[] = { 'N', 'e', 'w', 0 };
87 b3994ec5 2003-12-11 devnull static Rune LNewcol[] = { 'N', 'e', 'w', 'c', 'o', 'l', 0 };
88 b3994ec5 2003-12-11 devnull static Rune LPaste[] = { 'P', 'a', 's', 't', 'e', 0 };
89 b3994ec5 2003-12-11 devnull static Rune LPut[] = { 'P', 'u', 't', 0 };
90 b3994ec5 2003-12-11 devnull static Rune LPutall[] = { 'P', 'u', 't', 'a', 'l', 'l', 0 };
91 b3994ec5 2003-12-11 devnull static Rune LRedo[] = { 'R', 'e', 'd', 'o', 0 };
92 b3994ec5 2003-12-11 devnull static Rune LSend[] = { 'S', 'e', 'n', 'd', 0 };
93 b3994ec5 2003-12-11 devnull static Rune LSnarf[] = { 'S', 'n', 'a', 'r', 'f', 0 };
94 b3994ec5 2003-12-11 devnull static Rune LSort[] = { 'S', 'o', 'r', 't', 0 };
95 b3994ec5 2003-12-11 devnull static Rune LTab[] = { 'T', 'a', 'b', 0 };
96 b3994ec5 2003-12-11 devnull static Rune LUndo[] = { 'U', 'n', 'd', 'o', 0 };
97 b3994ec5 2003-12-11 devnull static Rune LZerox[] = { 'Z', 'e', 'r', 'o', 'x', 0 };
98 b3994ec5 2003-12-11 devnull
99 b3994ec5 2003-12-11 devnull Exectab exectab[] = {
100 6dd68c9a 2005-01-23 devnull { LAbort, doabort, FALSE, XXX, XXX, },
101 b3994ec5 2003-12-11 devnull { LCut, cut, TRUE, TRUE, TRUE },
102 b3994ec5 2003-12-11 devnull { LDel, del, FALSE, FALSE, XXX },
103 6dd68c9a 2005-01-23 devnull { LDelcol, delcol, FALSE, XXX, XXX },
104 6dd68c9a 2005-01-23 devnull { LDelete, del, FALSE, TRUE, XXX },
105 6dd68c9a 2005-01-23 devnull { LDump, dump, FALSE, TRUE, XXX },
106 b3994ec5 2003-12-11 devnull { LEdit, edit, FALSE, XXX, XXX },
107 6dd68c9a 2005-01-23 devnull { LExit, xexit, FALSE, XXX, XXX },
108 b3994ec5 2003-12-11 devnull { LFont, fontx, FALSE, XXX, XXX },
109 b3994ec5 2003-12-11 devnull { LGet, get, FALSE, TRUE, XXX },
110 b3994ec5 2003-12-11 devnull { LID, id, FALSE, XXX, XXX },
111 b3994ec5 2003-12-11 devnull { LIncl, incl, FALSE, XXX, XXX },
112 8ad51794 2004-03-25 devnull { LIndent, indent, FALSE, XXX, XXX },
113 b3994ec5 2003-12-11 devnull { LKill, xkill, FALSE, XXX, XXX },
114 b3994ec5 2003-12-11 devnull { LLoad, dump, FALSE, FALSE, XXX },
115 b3994ec5 2003-12-11 devnull { LLocal, local, FALSE, XXX, XXX },
116 b3994ec5 2003-12-11 devnull { LLook, look, FALSE, XXX, XXX },
117 b3994ec5 2003-12-11 devnull { LNew, new, FALSE, XXX, XXX },
118 b3994ec5 2003-12-11 devnull { LNewcol, newcol, FALSE, XXX, XXX },
119 b3994ec5 2003-12-11 devnull { LPaste, paste, TRUE, TRUE, XXX },
120 b3994ec5 2003-12-11 devnull { LPut, put, FALSE, XXX, XXX },
121 b3994ec5 2003-12-11 devnull { LPutall, putall, FALSE, XXX, XXX },
122 b3994ec5 2003-12-11 devnull { LRedo, undo, FALSE, FALSE, XXX },
123 b3994ec5 2003-12-11 devnull { LSend, sendx, TRUE, XXX, XXX },
124 b3994ec5 2003-12-11 devnull { LSnarf, cut, FALSE, TRUE, FALSE },
125 b3994ec5 2003-12-11 devnull { LSort, sort, FALSE, XXX, XXX },
126 b3994ec5 2003-12-11 devnull { LTab, tab, FALSE, XXX, XXX },
127 b3994ec5 2003-12-11 devnull { LUndo, undo, FALSE, TRUE, XXX },
128 6dd68c9a 2005-01-23 devnull { LZerox, zeroxx, FALSE, XXX, XXX },
129 cbeb0b26 2006-04-01 devnull { nil, 0, 0, 0, 0 }
130 b3994ec5 2003-12-11 devnull };
131 b3994ec5 2003-12-11 devnull
132 b3994ec5 2003-12-11 devnull Exectab*
133 b3994ec5 2003-12-11 devnull lookup(Rune *r, int n)
134 b3994ec5 2003-12-11 devnull {
135 b3994ec5 2003-12-11 devnull Exectab *e;
136 b3994ec5 2003-12-11 devnull int nr;
137 b3994ec5 2003-12-11 devnull
138 b3994ec5 2003-12-11 devnull r = skipbl(r, n, &n);
139 b3994ec5 2003-12-11 devnull if(n == 0)
140 b3994ec5 2003-12-11 devnull return nil;
141 b3994ec5 2003-12-11 devnull findbl(r, n, &nr);
142 b3994ec5 2003-12-11 devnull nr = n-nr;
143 b3994ec5 2003-12-11 devnull for(e=exectab; e->name; e++)
144 b3994ec5 2003-12-11 devnull if(runeeq(r, nr, e->name, runestrlen(e->name)) == TRUE)
145 b3994ec5 2003-12-11 devnull return e;
146 b3994ec5 2003-12-11 devnull return nil;
147 b3994ec5 2003-12-11 devnull }
148 b3994ec5 2003-12-11 devnull
149 b3994ec5 2003-12-11 devnull int
150 b3994ec5 2003-12-11 devnull isexecc(int c)
151 b3994ec5 2003-12-11 devnull {
152 b3994ec5 2003-12-11 devnull if(isfilec(c))
153 b3994ec5 2003-12-11 devnull return 1;
154 b3994ec5 2003-12-11 devnull return c=='<' || c=='|' || c=='>';
155 b3994ec5 2003-12-11 devnull }
156 b3994ec5 2003-12-11 devnull
157 b3994ec5 2003-12-11 devnull void
158 b3994ec5 2003-12-11 devnull execute(Text *t, uint aq0, uint aq1, int external, Text *argt)
159 b3994ec5 2003-12-11 devnull {
160 b3994ec5 2003-12-11 devnull uint q0, q1;
161 b3994ec5 2003-12-11 devnull Rune *r, *s;
162 b3994ec5 2003-12-11 devnull char *b, *a, *aa;
163 b3994ec5 2003-12-11 devnull Exectab *e;
164 b3994ec5 2003-12-11 devnull int c, n, f;
165 b3994ec5 2003-12-11 devnull Runestr dir;
166 b3994ec5 2003-12-11 devnull
167 b3994ec5 2003-12-11 devnull q0 = aq0;
168 b3994ec5 2003-12-11 devnull q1 = aq1;
169 b3994ec5 2003-12-11 devnull if(q1 == q0){ /* expand to find word (actually file name) */
170 b3994ec5 2003-12-11 devnull /* if in selection, choose selection */
171 b3994ec5 2003-12-11 devnull if(t->q1>t->q0 && t->q0<=q0 && q0<=t->q1){
172 b3994ec5 2003-12-11 devnull q0 = t->q0;
173 b3994ec5 2003-12-11 devnull q1 = t->q1;
174 b3994ec5 2003-12-11 devnull }else{
175 b3994ec5 2003-12-11 devnull while(q1<t->file->b.nc && isexecc(c=textreadc(t, q1)) && c!=':')
176 b3994ec5 2003-12-11 devnull q1++;
177 b3994ec5 2003-12-11 devnull while(q0>0 && isexecc(c=textreadc(t, q0-1)) && c!=':')
178 b3994ec5 2003-12-11 devnull q0--;
179 b3994ec5 2003-12-11 devnull if(q1 == q0)
180 b3994ec5 2003-12-11 devnull return;
181 b3994ec5 2003-12-11 devnull }
182 b3994ec5 2003-12-11 devnull }
183 b3994ec5 2003-12-11 devnull r = runemalloc(q1-q0);
184 b3994ec5 2003-12-11 devnull bufread(&t->file->b, q0, r, q1-q0);
185 b3994ec5 2003-12-11 devnull e = lookup(r, q1-q0);
186 b3994ec5 2003-12-11 devnull if(!external && t->w!=nil && t->w->nopen[QWevent]>0){
187 b3994ec5 2003-12-11 devnull f = 0;
188 b3994ec5 2003-12-11 devnull if(e)
189 b3994ec5 2003-12-11 devnull f |= 1;
190 b3994ec5 2003-12-11 devnull if(q0!=aq0 || q1!=aq1){
191 b3994ec5 2003-12-11 devnull bufread(&t->file->b, aq0, r, aq1-aq0);
192 b3994ec5 2003-12-11 devnull f |= 2;
193 b3994ec5 2003-12-11 devnull }
194 b3994ec5 2003-12-11 devnull aa = getbytearg(argt, TRUE, TRUE, &a);
195 31977190 2019-04-20 rsc if(a){
196 b3994ec5 2003-12-11 devnull if(strlen(a) > EVENTSIZE){ /* too big; too bad */
197 7ca1c901 2018-03-27 0intro free(r);
198 b3994ec5 2003-12-11 devnull free(aa);
199 b3994ec5 2003-12-11 devnull free(a);
200 4a18fa68 2009-07-08 mt warning(nil, "argument string too long\n");
201 b3994ec5 2003-12-11 devnull return;
202 b3994ec5 2003-12-11 devnull }
203 b3994ec5 2003-12-11 devnull f |= 8;
204 b3994ec5 2003-12-11 devnull }
205 b3994ec5 2003-12-11 devnull c = 'x';
206 b3994ec5 2003-12-11 devnull if(t->what == Body)
207 b3994ec5 2003-12-11 devnull c = 'X';
208 b3994ec5 2003-12-11 devnull n = aq1-aq0;
209 b3994ec5 2003-12-11 devnull if(n <= EVENTSIZE)
210 b3994ec5 2003-12-11 devnull winevent(t->w, "%c%d %d %d %d %.*S\n", c, aq0, aq1, f, n, n, r);
211 b3994ec5 2003-12-11 devnull else
212 8cf52696 2021-09-28 rsc winevent(t->w, "%c%d %d %d 0 \n", c, aq0, aq1, f);
213 b3994ec5 2003-12-11 devnull if(q0!=aq0 || q1!=aq1){
214 b3994ec5 2003-12-11 devnull n = q1-q0;
215 b3994ec5 2003-12-11 devnull bufread(&t->file->b, q0, r, n);
216 b3994ec5 2003-12-11 devnull if(n <= EVENTSIZE)
217 b3994ec5 2003-12-11 devnull winevent(t->w, "%c%d %d 0 %d %.*S\n", c, q0, q1, n, n, r);
218 b3994ec5 2003-12-11 devnull else
219 8cf52696 2021-09-28 rsc winevent(t->w, "%c%d %d 0 0 \n", c, q0, q1);
220 b3994ec5 2003-12-11 devnull }
221 b3994ec5 2003-12-11 devnull if(a){
222 b3994ec5 2003-12-11 devnull winevent(t->w, "%c0 0 0 %d %s\n", c, utflen(a), a);
223 b3994ec5 2003-12-11 devnull if(aa)
224 b3994ec5 2003-12-11 devnull winevent(t->w, "%c0 0 0 %d %s\n", c, utflen(aa), aa);
225 b3994ec5 2003-12-11 devnull else
226 b3994ec5 2003-12-11 devnull winevent(t->w, "%c0 0 0 0 \n", c);
227 b3994ec5 2003-12-11 devnull }
228 b3994ec5 2003-12-11 devnull free(r);
229 b3994ec5 2003-12-11 devnull free(aa);
230 b3994ec5 2003-12-11 devnull free(a);
231 b3994ec5 2003-12-11 devnull return;
232 b3994ec5 2003-12-11 devnull }
233 b3994ec5 2003-12-11 devnull if(e){
234 b3994ec5 2003-12-11 devnull if(e->mark && seltext!=nil)
235 b3994ec5 2003-12-11 devnull if(seltext->what == Body){
236 b3994ec5 2003-12-11 devnull seq++;
237 b3994ec5 2003-12-11 devnull filemark(seltext->w->body.file);
238 b3994ec5 2003-12-11 devnull }
239 b3994ec5 2003-12-11 devnull s = skipbl(r, q1-q0, &n);
240 b3994ec5 2003-12-11 devnull s = findbl(s, n, &n);
241 b3994ec5 2003-12-11 devnull s = skipbl(s, n, &n);
242 b3994ec5 2003-12-11 devnull (*e->fn)(t, seltext, argt, e->flag1, e->flag2, s, n);
243 b3994ec5 2003-12-11 devnull free(r);
244 b3994ec5 2003-12-11 devnull return;
245 b3994ec5 2003-12-11 devnull }
246 b3994ec5 2003-12-11 devnull
247 b3994ec5 2003-12-11 devnull b = runetobyte(r, q1-q0);
248 b3994ec5 2003-12-11 devnull free(r);
249 b3994ec5 2003-12-11 devnull dir = dirname(t, nil, 0);
250 b3994ec5 2003-12-11 devnull if(dir.nr==1 && dir.r[0]=='.'){ /* sigh */
251 b3994ec5 2003-12-11 devnull free(dir.r);
252 b3994ec5 2003-12-11 devnull dir.r = nil;
253 b3994ec5 2003-12-11 devnull dir.nr = 0;
254 b3994ec5 2003-12-11 devnull }
255 b3994ec5 2003-12-11 devnull aa = getbytearg(argt, TRUE, TRUE, &a);
256 b3994ec5 2003-12-11 devnull if(t->w)
257 b3994ec5 2003-12-11 devnull incref(&t->w->ref);
258 b3994ec5 2003-12-11 devnull run(t->w, b, dir.r, dir.nr, TRUE, aa, a, FALSE);
259 b3994ec5 2003-12-11 devnull }
260 b3994ec5 2003-12-11 devnull
261 b3994ec5 2003-12-11 devnull char*
262 b3994ec5 2003-12-11 devnull printarg(Text *argt, uint q0, uint q1)
263 b3994ec5 2003-12-11 devnull {
264 b3994ec5 2003-12-11 devnull char *buf;
265 b3994ec5 2003-12-11 devnull
266 b3994ec5 2003-12-11 devnull if(argt->what!=Body || argt->file->name==nil)
267 b3994ec5 2003-12-11 devnull return nil;
268 b3994ec5 2003-12-11 devnull buf = emalloc(argt->file->nname+32);
269 b3994ec5 2003-12-11 devnull if(q0 == q1)
270 b3994ec5 2003-12-11 devnull sprint(buf, "%.*S:#%d", argt->file->nname, argt->file->name, q0);
271 b3994ec5 2003-12-11 devnull else
272 b3994ec5 2003-12-11 devnull sprint(buf, "%.*S:#%d,#%d", argt->file->nname, argt->file->name, q0, q1);
273 b3994ec5 2003-12-11 devnull return buf;
274 b3994ec5 2003-12-11 devnull }
275 b3994ec5 2003-12-11 devnull
276 b3994ec5 2003-12-11 devnull char*
277 b3994ec5 2003-12-11 devnull getarg(Text *argt, int doaddr, int dofile, Rune **rp, int *nrp)
278 b3994ec5 2003-12-11 devnull {
279 b3994ec5 2003-12-11 devnull int n;
280 b3994ec5 2003-12-11 devnull Expand e;
281 b3994ec5 2003-12-11 devnull char *a;
282 b3994ec5 2003-12-11 devnull
283 b3994ec5 2003-12-11 devnull *rp = nil;
284 b3994ec5 2003-12-11 devnull *nrp = 0;
285 b3994ec5 2003-12-11 devnull if(argt == nil)
286 b3994ec5 2003-12-11 devnull return nil;
287 b3994ec5 2003-12-11 devnull a = nil;
288 b3994ec5 2003-12-11 devnull textcommit(argt, TRUE);
289 b3994ec5 2003-12-11 devnull if(expand(argt, argt->q0, argt->q1, &e)){
290 b3994ec5 2003-12-11 devnull free(e.bname);
291 b3994ec5 2003-12-11 devnull if(e.nname && dofile){
292 b3994ec5 2003-12-11 devnull e.name = runerealloc(e.name, e.nname+1);
293 b3994ec5 2003-12-11 devnull if(doaddr)
294 b3994ec5 2003-12-11 devnull a = printarg(argt, e.q0, e.q1);
295 b3994ec5 2003-12-11 devnull *rp = e.name;
296 b3994ec5 2003-12-11 devnull *nrp = e.nname;
297 b3994ec5 2003-12-11 devnull return a;
298 b3994ec5 2003-12-11 devnull }
299 b3994ec5 2003-12-11 devnull free(e.name);
300 b3994ec5 2003-12-11 devnull }else{
301 b3994ec5 2003-12-11 devnull e.q0 = argt->q0;
302 b3994ec5 2003-12-11 devnull e.q1 = argt->q1;
303 b3994ec5 2003-12-11 devnull }
304 b3994ec5 2003-12-11 devnull n = e.q1 - e.q0;
305 b3994ec5 2003-12-11 devnull *rp = runemalloc(n+1);
306 b3994ec5 2003-12-11 devnull bufread(&argt->file->b, e.q0, *rp, n);
307 b3994ec5 2003-12-11 devnull if(doaddr)
308 b3994ec5 2003-12-11 devnull a = printarg(argt, e.q0, e.q1);
309 b3994ec5 2003-12-11 devnull *nrp = n;
310 b3994ec5 2003-12-11 devnull return a;
311 b3994ec5 2003-12-11 devnull }
312 b3994ec5 2003-12-11 devnull
313 b3994ec5 2003-12-11 devnull char*
314 b3994ec5 2003-12-11 devnull getbytearg(Text *argt, int doaddr, int dofile, char **bp)
315 b3994ec5 2003-12-11 devnull {
316 b3994ec5 2003-12-11 devnull Rune *r;
317 b3994ec5 2003-12-11 devnull int n;
318 b3994ec5 2003-12-11 devnull char *aa;
319 b3994ec5 2003-12-11 devnull
320 b3994ec5 2003-12-11 devnull *bp = nil;
321 b3994ec5 2003-12-11 devnull aa = getarg(argt, doaddr, dofile, &r, &n);
322 b3994ec5 2003-12-11 devnull if(r == nil)
323 b3994ec5 2003-12-11 devnull return nil;
324 b3994ec5 2003-12-11 devnull *bp = runetobyte(r, n);
325 b3994ec5 2003-12-11 devnull free(r);
326 b3994ec5 2003-12-11 devnull return aa;
327 6dd68c9a 2005-01-23 devnull }
328 6dd68c9a 2005-01-23 devnull
329 6dd68c9a 2005-01-23 devnull void
330 6dd68c9a 2005-01-23 devnull doabort(Text *__0, Text *_0, Text *_1, int _2, int _3, Rune *_4, int _5)
331 6dd68c9a 2005-01-23 devnull {
332 6dd68c9a 2005-01-23 devnull static int n;
333 6dd68c9a 2005-01-23 devnull
334 6dd68c9a 2005-01-23 devnull USED(__0);
335 6dd68c9a 2005-01-23 devnull USED(_0);
336 6dd68c9a 2005-01-23 devnull USED(_1);
337 6dd68c9a 2005-01-23 devnull USED(_2);
338 6dd68c9a 2005-01-23 devnull USED(_3);
339 6dd68c9a 2005-01-23 devnull USED(_4);
340 6dd68c9a 2005-01-23 devnull USED(_5);
341 6dd68c9a 2005-01-23 devnull
342 6dd68c9a 2005-01-23 devnull if(n++ == 0)
343 6dd68c9a 2005-01-23 devnull warning(nil, "executing Abort again will call abort()\n");
344 6dd68c9a 2005-01-23 devnull else
345 6dd68c9a 2005-01-23 devnull abort();
346 b3994ec5 2003-12-11 devnull }
347 b3994ec5 2003-12-11 devnull
348 b3994ec5 2003-12-11 devnull void
349 b3994ec5 2003-12-11 devnull newcol(Text *et, Text *_0, Text *_1, int _2, int _3, Rune *_4, int _5)
350 b3994ec5 2003-12-11 devnull {
351 b3994ec5 2003-12-11 devnull Column *c;
352 4a3fb872 2014-04-30 rsc Window *w;
353 b3994ec5 2003-12-11 devnull
354 b3994ec5 2003-12-11 devnull USED(_0);
355 b3994ec5 2003-12-11 devnull USED(_1);
356 b3994ec5 2003-12-11 devnull USED(_2);
357 b3994ec5 2003-12-11 devnull USED(_3);
358 b3994ec5 2003-12-11 devnull USED(_4);
359 b3994ec5 2003-12-11 devnull USED(_5);
360 b3994ec5 2003-12-11 devnull
361 b3994ec5 2003-12-11 devnull c = rowadd(et->row, nil, -1);
362 4a3fb872 2014-04-30 rsc if(c) {
363 4a3fb872 2014-04-30 rsc w = coladd(c, nil, nil, -1);
364 4a3fb872 2014-04-30 rsc winsettag(w);
365 4a3fb872 2014-04-30 rsc xfidlog(w, "new");
366 4a3fb872 2014-04-30 rsc }
367 b3994ec5 2003-12-11 devnull }
368 b3994ec5 2003-12-11 devnull
369 b3994ec5 2003-12-11 devnull void
370 b3994ec5 2003-12-11 devnull delcol(Text *et, Text *_0, Text *_1, int _2, int _3, Rune *_4, int _5)
371 b3994ec5 2003-12-11 devnull {
372 b3994ec5 2003-12-11 devnull int i;
373 b3994ec5 2003-12-11 devnull Column *c;
374 b3994ec5 2003-12-11 devnull Window *w;
375 b3994ec5 2003-12-11 devnull
376 b3994ec5 2003-12-11 devnull USED(_0);
377 b3994ec5 2003-12-11 devnull USED(_1);
378 b3994ec5 2003-12-11 devnull USED(_2);
379 b3994ec5 2003-12-11 devnull USED(_3);
380 b3994ec5 2003-12-11 devnull USED(_4);
381 b3994ec5 2003-12-11 devnull USED(_5);
382 b3994ec5 2003-12-11 devnull
383 b3994ec5 2003-12-11 devnull c = et->col;
384 b3994ec5 2003-12-11 devnull if(c==nil || colclean(c)==0)
385 b3994ec5 2003-12-11 devnull return;
386 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
387 b3994ec5 2003-12-11 devnull w = c->w[i];
388 012a8a02 2004-10-22 devnull if(w->nopen[QWevent]+w->nopen[QWaddr]+w->nopen[QWdata]+w->nopen[QWxdata] > 0){
389 b3994ec5 2003-12-11 devnull warning(nil, "can't delete column; %.*S is running an external command\n", w->body.file->nname, w->body.file->name);
390 b3994ec5 2003-12-11 devnull return;
391 b3994ec5 2003-12-11 devnull }
392 b3994ec5 2003-12-11 devnull }
393 b3994ec5 2003-12-11 devnull rowclose(et->col->row, et->col, TRUE);
394 b3994ec5 2003-12-11 devnull }
395 b3994ec5 2003-12-11 devnull
396 b3994ec5 2003-12-11 devnull void
397 b3994ec5 2003-12-11 devnull del(Text *et, Text *_0, Text *_1, int flag1, int _2, Rune *_3, int _4)
398 b3994ec5 2003-12-11 devnull {
399 b3994ec5 2003-12-11 devnull USED(_0);
400 b3994ec5 2003-12-11 devnull USED(_1);
401 b3994ec5 2003-12-11 devnull USED(_2);
402 b3994ec5 2003-12-11 devnull USED(_3);
403 b3994ec5 2003-12-11 devnull USED(_4);
404 b3994ec5 2003-12-11 devnull
405 b3994ec5 2003-12-11 devnull if(et->col==nil || et->w == nil)
406 b3994ec5 2003-12-11 devnull return;
407 b3994ec5 2003-12-11 devnull if(flag1 || et->w->body.file->ntext>1 || winclean(et->w, FALSE))
408 b3994ec5 2003-12-11 devnull colclose(et->col, et->w, TRUE);
409 62c14158 2004-04-08 devnull }
410 62c14158 2004-04-08 devnull
411 62c14158 2004-04-08 devnull void
412 b3994ec5 2003-12-11 devnull sort(Text *et, Text *_0, Text *_1, int _2, int _3, Rune *_4, int _5)
413 b3994ec5 2003-12-11 devnull {
414 b3994ec5 2003-12-11 devnull USED(_0);
415 b3994ec5 2003-12-11 devnull USED(_1);
416 b3994ec5 2003-12-11 devnull USED(_2);
417 b3994ec5 2003-12-11 devnull USED(_3);
418 b3994ec5 2003-12-11 devnull USED(_4);
419 b3994ec5 2003-12-11 devnull USED(_5);
420 b3994ec5 2003-12-11 devnull
421 b3994ec5 2003-12-11 devnull if(et->col)
422 b3994ec5 2003-12-11 devnull colsort(et->col);
423 b3994ec5 2003-12-11 devnull }
424 b3994ec5 2003-12-11 devnull
425 b3994ec5 2003-12-11 devnull uint
426 b3994ec5 2003-12-11 devnull seqof(Window *w, int isundo)
427 b3994ec5 2003-12-11 devnull {
428 b3994ec5 2003-12-11 devnull /* if it's undo, see who changed with us */
429 b3994ec5 2003-12-11 devnull if(isundo)
430 b3994ec5 2003-12-11 devnull return w->body.file->seq;
431 b3994ec5 2003-12-11 devnull /* if it's redo, see who we'll be sync'ed up with */
432 b3994ec5 2003-12-11 devnull return fileredoseq(w->body.file);
433 b3994ec5 2003-12-11 devnull }
434 b3994ec5 2003-12-11 devnull
435 b3994ec5 2003-12-11 devnull void
436 b3994ec5 2003-12-11 devnull undo(Text *et, Text *_0, Text *_1, int flag1, int _2, Rune *_3, int _4)
437 b3994ec5 2003-12-11 devnull {
438 b3994ec5 2003-12-11 devnull int i, j;
439 b3994ec5 2003-12-11 devnull Column *c;
440 b3994ec5 2003-12-11 devnull Window *w;
441 b3994ec5 2003-12-11 devnull uint seq;
442 b3994ec5 2003-12-11 devnull
443 b3994ec5 2003-12-11 devnull USED(_0);
444 b3994ec5 2003-12-11 devnull USED(_1);
445 b3994ec5 2003-12-11 devnull USED(_2);
446 b3994ec5 2003-12-11 devnull USED(_3);
447 b3994ec5 2003-12-11 devnull USED(_4);
448 b3994ec5 2003-12-11 devnull
449 b3994ec5 2003-12-11 devnull if(et==nil || et->w== nil)
450 b3994ec5 2003-12-11 devnull return;
451 b3994ec5 2003-12-11 devnull seq = seqof(et->w, flag1);
452 b3994ec5 2003-12-11 devnull if(seq == 0){
453 b3994ec5 2003-12-11 devnull /* nothing to undo */
454 b3994ec5 2003-12-11 devnull return;
455 b3994ec5 2003-12-11 devnull }
456 b3994ec5 2003-12-11 devnull /*
457 b3994ec5 2003-12-11 devnull * Undo the executing window first. Its display will update. other windows
458 b3994ec5 2003-12-11 devnull * in the same file will not call show() and jump to a different location in the file.
459 b3994ec5 2003-12-11 devnull * Simultaneous changes to other files will be chaotic, however.
460 b3994ec5 2003-12-11 devnull */
461 b3994ec5 2003-12-11 devnull winundo(et->w, flag1);
462 b3994ec5 2003-12-11 devnull for(i=0; i<row.ncol; i++){
463 b3994ec5 2003-12-11 devnull c = row.col[i];
464 b3994ec5 2003-12-11 devnull for(j=0; j<c->nw; j++){
465 b3994ec5 2003-12-11 devnull w = c->w[j];
466 b3994ec5 2003-12-11 devnull if(w == et->w)
467 b3994ec5 2003-12-11 devnull continue;
468 b3994ec5 2003-12-11 devnull if(seqof(w, flag1) == seq)
469 b3994ec5 2003-12-11 devnull winundo(w, flag1);
470 b3994ec5 2003-12-11 devnull }
471 b3994ec5 2003-12-11 devnull }
472 b3994ec5 2003-12-11 devnull }
473 b3994ec5 2003-12-11 devnull
474 b3994ec5 2003-12-11 devnull char*
475 b3994ec5 2003-12-11 devnull getname(Text *t, Text *argt, Rune *arg, int narg, int isput)
476 b3994ec5 2003-12-11 devnull {
477 b3994ec5 2003-12-11 devnull char *s;
478 b3994ec5 2003-12-11 devnull Rune *r;
479 b3994ec5 2003-12-11 devnull int i, n, promote;
480 b3994ec5 2003-12-11 devnull Runestr dir;
481 b3994ec5 2003-12-11 devnull
482 b3994ec5 2003-12-11 devnull getarg(argt, FALSE, TRUE, &r, &n);
483 b3994ec5 2003-12-11 devnull promote = FALSE;
484 b3994ec5 2003-12-11 devnull if(r == nil)
485 b3994ec5 2003-12-11 devnull promote = TRUE;
486 b3994ec5 2003-12-11 devnull else if(isput){
487 b3994ec5 2003-12-11 devnull /* if are doing a Put, want to synthesize name even for non-existent file */
488 b3994ec5 2003-12-11 devnull /* best guess is that file name doesn't contain a slash */
489 b3994ec5 2003-12-11 devnull promote = TRUE;
490 b3994ec5 2003-12-11 devnull for(i=0; i<n; i++)
491 b3994ec5 2003-12-11 devnull if(r[i] == '/'){
492 b3994ec5 2003-12-11 devnull promote = FALSE;
493 b3994ec5 2003-12-11 devnull break;
494 b3994ec5 2003-12-11 devnull }
495 b3994ec5 2003-12-11 devnull if(promote){
496 b3994ec5 2003-12-11 devnull t = argt;
497 b3994ec5 2003-12-11 devnull arg = r;
498 b3994ec5 2003-12-11 devnull narg = n;
499 b3994ec5 2003-12-11 devnull }
500 b3994ec5 2003-12-11 devnull }
501 b3994ec5 2003-12-11 devnull if(promote){
502 b3994ec5 2003-12-11 devnull n = narg;
503 b3994ec5 2003-12-11 devnull if(n <= 0){
504 b3994ec5 2003-12-11 devnull s = runetobyte(t->file->name, t->file->nname);
505 b3994ec5 2003-12-11 devnull return s;
506 b3994ec5 2003-12-11 devnull }
507 b3994ec5 2003-12-11 devnull /* prefix with directory name if necessary */
508 b3994ec5 2003-12-11 devnull dir.r = nil;
509 b3994ec5 2003-12-11 devnull dir.nr = 0;
510 b3994ec5 2003-12-11 devnull if(n>0 && arg[0]!='/'){
511 b3994ec5 2003-12-11 devnull dir = dirname(t, nil, 0);
512 5a8e63b2 2004-02-29 devnull if(dir.nr==1 && dir.r[0]=='.'){ /* sigh */
513 b3994ec5 2003-12-11 devnull free(dir.r);
514 b3994ec5 2003-12-11 devnull dir.r = nil;
515 b3994ec5 2003-12-11 devnull dir.nr = 0;
516 b3994ec5 2003-12-11 devnull }
517 b3994ec5 2003-12-11 devnull }
518 b3994ec5 2003-12-11 devnull if(dir.r){
519 b3994ec5 2003-12-11 devnull r = runemalloc(dir.nr+n+1);
520 b3994ec5 2003-12-11 devnull runemove(r, dir.r, dir.nr);
521 b3994ec5 2003-12-11 devnull free(dir.r);
522 0d0bad2e 2004-11-01 devnull if(dir.nr>0 && r[dir.nr]!='/' && n>0 && arg[0]!='/')
523 0d0bad2e 2004-11-01 devnull r[dir.nr++] = '/';
524 b3994ec5 2003-12-11 devnull runemove(r+dir.nr, arg, n);
525 b3994ec5 2003-12-11 devnull n += dir.nr;
526 b3994ec5 2003-12-11 devnull }else{
527 b3994ec5 2003-12-11 devnull r = runemalloc(n+1);
528 b3994ec5 2003-12-11 devnull runemove(r, arg, n);
529 b3994ec5 2003-12-11 devnull }
530 b3994ec5 2003-12-11 devnull }
531 b3994ec5 2003-12-11 devnull s = runetobyte(r, n);
532 b3994ec5 2003-12-11 devnull free(r);
533 b3994ec5 2003-12-11 devnull if(strlen(s) == 0){
534 b3994ec5 2003-12-11 devnull free(s);
535 b3994ec5 2003-12-11 devnull s = nil;
536 b3994ec5 2003-12-11 devnull }
537 b3994ec5 2003-12-11 devnull return s;
538 b3994ec5 2003-12-11 devnull }
539 b3994ec5 2003-12-11 devnull
540 b3994ec5 2003-12-11 devnull void
541 b3994ec5 2003-12-11 devnull zeroxx(Text *et, Text *t, Text *_1, int _2, int _3, Rune *_4, int _5)
542 b3994ec5 2003-12-11 devnull {
543 b3994ec5 2003-12-11 devnull Window *nw;
544 b3994ec5 2003-12-11 devnull int c, locked;
545 b3994ec5 2003-12-11 devnull
546 b3994ec5 2003-12-11 devnull USED(_1);
547 b3994ec5 2003-12-11 devnull USED(_2);
548 b3994ec5 2003-12-11 devnull USED(_3);
549 b3994ec5 2003-12-11 devnull USED(_4);
550 b3994ec5 2003-12-11 devnull USED(_5);
551 b3994ec5 2003-12-11 devnull
552 b3994ec5 2003-12-11 devnull locked = FALSE;
553 b3994ec5 2003-12-11 devnull if(t!=nil && t->w!=nil && t->w!=et->w){
554 b3994ec5 2003-12-11 devnull locked = TRUE;
555 b3994ec5 2003-12-11 devnull c = 'M';
556 b3994ec5 2003-12-11 devnull if(et->w)
557 b3994ec5 2003-12-11 devnull c = et->w->owner;
558 b3994ec5 2003-12-11 devnull winlock(t->w, c);
559 b3994ec5 2003-12-11 devnull }
560 b3994ec5 2003-12-11 devnull if(t == nil)
561 b3994ec5 2003-12-11 devnull t = et;
562 b3994ec5 2003-12-11 devnull if(t==nil || t->w==nil)
563 b3994ec5 2003-12-11 devnull return;
564 b3994ec5 2003-12-11 devnull t = &t->w->body;
565 b3994ec5 2003-12-11 devnull if(t->w->isdir)
566 b3994ec5 2003-12-11 devnull warning(nil, "%.*S is a directory; Zerox illegal\n", t->file->nname, t->file->name);
567 b3994ec5 2003-12-11 devnull else{
568 b3994ec5 2003-12-11 devnull nw = coladd(t->w->col, nil, t->w, -1);
569 b3994ec5 2003-12-11 devnull /* ugly: fix locks so w->unlock works */
570 b3994ec5 2003-12-11 devnull winlock1(nw, t->w->owner);
571 4a3fb872 2014-04-30 rsc xfidlog(nw, "zerox");
572 b3994ec5 2003-12-11 devnull }
573 b3994ec5 2003-12-11 devnull if(locked)
574 b3994ec5 2003-12-11 devnull winunlock(t->w);
575 b3994ec5 2003-12-11 devnull }
576 b3994ec5 2003-12-11 devnull
577 3d6e5cb5 2017-11-02 rsc typedef struct TextAddr TextAddr;
578 3d6e5cb5 2017-11-02 rsc struct TextAddr {
579 3d6e5cb5 2017-11-02 rsc long lorigin; // line+rune for origin
580 3d6e5cb5 2017-11-02 rsc long rorigin;
581 3d6e5cb5 2017-11-02 rsc long lq0; // line+rune for q0
582 3d6e5cb5 2017-11-02 rsc long rq0;
583 3d6e5cb5 2017-11-02 rsc long lq1; // line+rune for q1
584 3d6e5cb5 2017-11-02 rsc long rq1;
585 3d6e5cb5 2017-11-02 rsc };
586 3d6e5cb5 2017-11-02 rsc
587 b3994ec5 2003-12-11 devnull void
588 b3994ec5 2003-12-11 devnull get(Text *et, Text *t, Text *argt, int flag1, int _0, Rune *arg, int narg)
589 b3994ec5 2003-12-11 devnull {
590 b3994ec5 2003-12-11 devnull char *name;
591 b3994ec5 2003-12-11 devnull Rune *r;
592 b3994ec5 2003-12-11 devnull int i, n, dirty, samename, isdir;
593 3d6e5cb5 2017-11-02 rsc TextAddr *addr, *a;
594 b3994ec5 2003-12-11 devnull Window *w;
595 b3994ec5 2003-12-11 devnull Text *u;
596 b3994ec5 2003-12-11 devnull Dir *d;
597 3d6e5cb5 2017-11-02 rsc long q0, q1;
598 b3994ec5 2003-12-11 devnull
599 b3994ec5 2003-12-11 devnull USED(_0);
600 b3994ec5 2003-12-11 devnull
601 b3994ec5 2003-12-11 devnull if(flag1)
602 b3994ec5 2003-12-11 devnull if(et==nil || et->w==nil)
603 b3994ec5 2003-12-11 devnull return;
604 b3994ec5 2003-12-11 devnull if(!et->w->isdir && (et->w->body.file->b.nc>0 && !winclean(et->w, TRUE)))
605 b3994ec5 2003-12-11 devnull return;
606 b3994ec5 2003-12-11 devnull w = et->w;
607 b3994ec5 2003-12-11 devnull t = &w->body;
608 b3994ec5 2003-12-11 devnull name = getname(t, argt, arg, narg, FALSE);
609 b3994ec5 2003-12-11 devnull if(name == nil){
610 b3994ec5 2003-12-11 devnull warning(nil, "no file name\n");
611 b3994ec5 2003-12-11 devnull return;
612 b3994ec5 2003-12-11 devnull }
613 b3994ec5 2003-12-11 devnull if(t->file->ntext>1){
614 b3994ec5 2003-12-11 devnull d = dirstat(name);
615 b3994ec5 2003-12-11 devnull isdir = (d!=nil && (d->qid.type & QTDIR));
616 b3994ec5 2003-12-11 devnull free(d);
617 038aa022 2004-06-11 devnull if(isdir){
618 b3994ec5 2003-12-11 devnull warning(nil, "%s is a directory; can't read with multiple windows on it\n", name);
619 038aa022 2004-06-11 devnull return;
620 038aa022 2004-06-11 devnull }
621 3d6e5cb5 2017-11-02 rsc }
622 3d6e5cb5 2017-11-02 rsc addr = emalloc((t->file->ntext)*sizeof(TextAddr));
623 3d6e5cb5 2017-11-02 rsc for(i=0; i<t->file->ntext; i++) {
624 3d6e5cb5 2017-11-02 rsc a = &addr[i];
625 3d6e5cb5 2017-11-02 rsc u = t->file->text[i];
626 3d6e5cb5 2017-11-02 rsc a->lorigin = nlcount(u, 0, u->org, &a->rorigin);
627 3d6e5cb5 2017-11-02 rsc a->lq0 = nlcount(u, 0, u->q0, &a->rq0);
628 3d6e5cb5 2017-11-02 rsc a->lq1 = nlcount(u, u->q0, u->q1, &a->rq1);
629 b3994ec5 2003-12-11 devnull }
630 b3994ec5 2003-12-11 devnull r = bytetorune(name, &n);
631 b3994ec5 2003-12-11 devnull for(i=0; i<t->file->ntext; i++){
632 b3994ec5 2003-12-11 devnull u = t->file->text[i];
633 b3994ec5 2003-12-11 devnull /* second and subsequent calls with zero an already empty buffer, but OK */
634 b3994ec5 2003-12-11 devnull textreset(u);
635 b3994ec5 2003-12-11 devnull windirfree(u->w);
636 b3994ec5 2003-12-11 devnull }
637 b3994ec5 2003-12-11 devnull samename = runeeq(r, n, t->file->name, t->file->nname);
638 b3994ec5 2003-12-11 devnull textload(t, 0, name, samename);
639 b3994ec5 2003-12-11 devnull if(samename){
640 b3994ec5 2003-12-11 devnull t->file->mod = FALSE;
641 b3994ec5 2003-12-11 devnull dirty = FALSE;
642 b3994ec5 2003-12-11 devnull }else{
643 b3994ec5 2003-12-11 devnull t->file->mod = TRUE;
644 b3994ec5 2003-12-11 devnull dirty = TRUE;
645 b3994ec5 2003-12-11 devnull }
646 b3994ec5 2003-12-11 devnull for(i=0; i<t->file->ntext; i++)
647 b3994ec5 2003-12-11 devnull t->file->text[i]->w->dirty = dirty;
648 b3994ec5 2003-12-11 devnull free(name);
649 b3994ec5 2003-12-11 devnull free(r);
650 b3994ec5 2003-12-11 devnull winsettag(w);
651 b3994ec5 2003-12-11 devnull t->file->unread = FALSE;
652 b3994ec5 2003-12-11 devnull for(i=0; i<t->file->ntext; i++){
653 b3994ec5 2003-12-11 devnull u = t->file->text[i];
654 b3994ec5 2003-12-11 devnull textsetselect(&u->w->tag, u->w->tag.file->b.nc, u->w->tag.file->b.nc);
655 3d6e5cb5 2017-11-02 rsc if(samename) {
656 3d6e5cb5 2017-11-02 rsc a = &addr[i];
657 3d6e5cb5 2017-11-02 rsc // warning(nil, "%d %d %d %d %d %d\n", a->lorigin, a->rorigin, a->lq0, a->rq0, a->lq1, a->rq1);
658 3d6e5cb5 2017-11-02 rsc q0 = nlcounttopos(u, 0, a->lq0, a->rq0);
659 3d6e5cb5 2017-11-02 rsc q1 = nlcounttopos(u, q0, a->lq1, a->rq1);
660 3d6e5cb5 2017-11-02 rsc textsetselect(u, q0, q1);
661 3d6e5cb5 2017-11-02 rsc q0 = nlcounttopos(u, 0, a->lorigin, a->rorigin);
662 3d6e5cb5 2017-11-02 rsc textsetorigin(u, q0, FALSE);
663 3d6e5cb5 2017-11-02 rsc }
664 b3994ec5 2003-12-11 devnull textscrdraw(u);
665 b3994ec5 2003-12-11 devnull }
666 3d6e5cb5 2017-11-02 rsc free(addr);
667 4a3fb872 2014-04-30 rsc xfidlog(w, "get");
668 b3994ec5 2003-12-11 devnull }
669 b3994ec5 2003-12-11 devnull
670 67dbeee5 2017-10-10 rsc static void
671 67dbeee5 2017-10-10 rsc checksha1(char *name, File *f, Dir *d)
672 67dbeee5 2017-10-10 rsc {
673 67dbeee5 2017-10-10 rsc int fd, n;
674 67dbeee5 2017-10-10 rsc DigestState *h;
675 67dbeee5 2017-10-10 rsc uchar out[20];
676 67dbeee5 2017-10-10 rsc uchar *buf;
677 31977190 2019-04-20 rsc
678 67dbeee5 2017-10-10 rsc fd = open(name, OREAD);
679 67dbeee5 2017-10-10 rsc if(fd < 0)
680 67dbeee5 2017-10-10 rsc return;
681 67dbeee5 2017-10-10 rsc h = sha1(nil, 0, nil, nil);
682 67dbeee5 2017-10-10 rsc buf = emalloc(8192);
683 67dbeee5 2017-10-10 rsc while((n = read(fd, buf, 8192)) > 0)
684 67dbeee5 2017-10-10 rsc sha1(buf, n, nil, h);
685 ff9d331d 2017-10-14 rsc free(buf);
686 67dbeee5 2017-10-10 rsc close(fd);
687 67dbeee5 2017-10-10 rsc sha1(nil, 0, out, h);
688 67dbeee5 2017-10-10 rsc if(memcmp(out, f->sha1, sizeof out) == 0) {
689 67dbeee5 2017-10-10 rsc f->dev = d->dev;
690 67dbeee5 2017-10-10 rsc f->qidpath = d->qid.path;
691 67dbeee5 2017-10-10 rsc f->mtime = d->mtime;
692 43f18737 2019-02-01 rsc }
693 43f18737 2019-02-01 rsc }
694 43f18737 2019-02-01 rsc
695 b3994ec5 2003-12-11 devnull void
696 b3994ec5 2003-12-11 devnull putfile(File *f, int q0, int q1, Rune *namer, int nname)
697 b3994ec5 2003-12-11 devnull {
698 16174277 2019-05-18 rsc uint n, m;
699 b3994ec5 2003-12-11 devnull Rune *r;
700 1d2c3c39 2014-04-19 rsc Biobuf *b;
701 b3994ec5 2003-12-11 devnull char *s, *name;
702 93e2e820 2020-01-24 rsc int i, fd, q, ret, retc;
703 b3994ec5 2003-12-11 devnull Dir *d, *d1;
704 b3994ec5 2003-12-11 devnull Window *w;
705 b3994ec5 2003-12-11 devnull int isapp;
706 67dbeee5 2017-10-10 rsc DigestState *h;
707 b3994ec5 2003-12-11 devnull
708 b3994ec5 2003-12-11 devnull w = f->curtext->w;
709 b3994ec5 2003-12-11 devnull name = runetobyte(namer, nname);
710 b3994ec5 2003-12-11 devnull d = dirstat(name);
711 b3994ec5 2003-12-11 devnull if(d!=nil && runeeq(namer, nname, f->name, f->nname)){
712 67dbeee5 2017-10-10 rsc if(f->dev!=d->dev || f->qidpath!=d->qid.path || f->mtime != d->mtime)
713 67dbeee5 2017-10-10 rsc checksha1(name, f, d);
714 67dbeee5 2017-10-10 rsc if(f->dev!=d->dev || f->qidpath!=d->qid.path || f->mtime != d->mtime) {
715 b3994ec5 2003-12-11 devnull if(f->unread)
716 5a8e63b2 2004-02-29 devnull warning(nil, "%s not written; file already exists\n", name);
717 b3994ec5 2003-12-11 devnull else
718 daea2c7d 2009-09-25 russcox warning(nil, "%s modified%s%s since last read\n\twas %t; now %t\n", name, d->muid[0]?" by ":"", d->muid, f->mtime, d->mtime);
719 daea2c7d 2009-09-25 russcox f->dev = d->dev;
720 daea2c7d 2009-09-25 russcox f->qidpath = d->qid.path;
721 daea2c7d 2009-09-25 russcox f->mtime = d->mtime;
722 b3994ec5 2003-12-11 devnull goto Rescue1;
723 b3994ec5 2003-12-11 devnull }
724 b3994ec5 2003-12-11 devnull }
725 16174277 2019-05-18 rsc
726 b3994ec5 2003-12-11 devnull fd = create(name, OWRITE, 0666);
727 b3994ec5 2003-12-11 devnull if(fd < 0){
728 5a8e63b2 2004-02-29 devnull warning(nil, "can't create file %s: %r\n", name);
729 b3994ec5 2003-12-11 devnull goto Rescue1;
730 b3994ec5 2003-12-11 devnull }
731 833216fe 2014-04-19 rsc // Use bio in order to force the writes to be large and
732 833216fe 2014-04-19 rsc // block-aligned (bio's default is 8K). This is not strictly
733 833216fe 2014-04-19 rsc // necessary; it works around some buggy underlying
734 833216fe 2014-04-19 rsc // file systems that mishandle unaligned writes.
735 833216fe 2014-04-19 rsc // https://codereview.appspot.com/89550043/
736 1d2c3c39 2014-04-19 rsc b = emalloc(sizeof *b);
737 1d2c3c39 2014-04-19 rsc Binit(b, fd, OWRITE);
738 b3994ec5 2003-12-11 devnull r = fbufalloc();
739 b3994ec5 2003-12-11 devnull s = fbufalloc();
740 b3994ec5 2003-12-11 devnull free(d);
741 b3994ec5 2003-12-11 devnull d = dirfstat(fd);
742 67dbeee5 2017-10-10 rsc h = sha1(nil, 0, nil, nil);
743 b3994ec5 2003-12-11 devnull isapp = (d!=nil && d->length>0 && (d->qid.type&QTAPPEND));
744 b3994ec5 2003-12-11 devnull if(isapp){
745 5a8e63b2 2004-02-29 devnull warning(nil, "%s not written; file is append only\n", name);
746 b3994ec5 2003-12-11 devnull goto Rescue2;
747 b3994ec5 2003-12-11 devnull }
748 b3994ec5 2003-12-11 devnull
749 b3994ec5 2003-12-11 devnull for(q=q0; q<q1; q+=n){
750 b3994ec5 2003-12-11 devnull n = q1 - q;
751 b3994ec5 2003-12-11 devnull if(n > BUFSIZE/UTFmax)
752 b3994ec5 2003-12-11 devnull n = BUFSIZE/UTFmax;
753 b3994ec5 2003-12-11 devnull bufread(&f->b, q, r, n);
754 16174277 2019-05-18 rsc m = snprint(s, BUFSIZE+1, "%.*S", n, r);
755 67dbeee5 2017-10-10 rsc sha1((uchar*)s, m, nil, h);
756 1d2c3c39 2014-04-19 rsc if(Bwrite(b, s, m) != m){
757 5a8e63b2 2004-02-29 devnull warning(nil, "can't write file %s: %r\n", name);
758 b3994ec5 2003-12-11 devnull goto Rescue2;
759 b3994ec5 2003-12-11 devnull }
760 b3994ec5 2003-12-11 devnull }
761 1d2c3c39 2014-04-19 rsc if(Bflush(b) < 0) {
762 1d2c3c39 2014-04-19 rsc warning(nil, "can't write file %s: %r\n", name);
763 1d2c3c39 2014-04-19 rsc goto Rescue2;
764 1d2c3c39 2014-04-19 rsc }
765 0b349f6f 2019-12-19 rsc ret = Bterm(b);
766 93e2e820 2020-01-24 rsc retc = close(fd);
767 1d2c3c39 2014-04-19 rsc free(b);
768 1d2c3c39 2014-04-19 rsc b = nil;
769 93e2e820 2020-01-24 rsc if(ret < 0 || retc < 0) {
770 0b349f6f 2019-12-19 rsc warning(nil, "can't write file %s: %r\n", name);
771 0b349f6f 2019-12-19 rsc goto Rescue2; // flush or close failed
772 0b349f6f 2019-12-19 rsc }
773 b3994ec5 2003-12-11 devnull if(runeeq(namer, nname, f->name, f->nname)){
774 b3994ec5 2003-12-11 devnull if(q0!=0 || q1!=f->b.nc){
775 b3994ec5 2003-12-11 devnull f->mod = TRUE;
776 b3994ec5 2003-12-11 devnull w->dirty = TRUE;
777 b3994ec5 2003-12-11 devnull f->unread = TRUE;
778 b3994ec5 2003-12-11 devnull }else{
779 be856b94 2010-03-19 rsc // In case the file is on NFS, reopen the fd
780 be856b94 2010-03-19 rsc // before dirfstat to cause the attribute cache
781 be856b94 2010-03-19 rsc // to be updated (otherwise the mtime in the
782 be856b94 2010-03-19 rsc // dirfstat below will be stale and not match
783 be856b94 2010-03-19 rsc // what NFS sees). The file is already written,
784 be856b94 2010-03-19 rsc // so this should be a no-op when not on NFS.
785 be856b94 2010-03-19 rsc // Opening for OWRITE (but no truncation)
786 be856b94 2010-03-19 rsc // in case we don't have read permission.
787 be856b94 2010-03-19 rsc // (The create above worked, so we probably
788 be856b94 2010-03-19 rsc // still have write permission.)
789 be856b94 2010-03-19 rsc fd = open(name, OWRITE);
790 b3994ec5 2003-12-11 devnull d1 = dirfstat(fd);
791 93e2e820 2020-01-24 rsc close(fd);
792 b3994ec5 2003-12-11 devnull if(d1 != nil){
793 b3994ec5 2003-12-11 devnull free(d);
794 b3994ec5 2003-12-11 devnull d = d1;
795 b3994ec5 2003-12-11 devnull }
796 b3994ec5 2003-12-11 devnull f->qidpath = d->qid.path;
797 b3994ec5 2003-12-11 devnull f->dev = d->dev;
798 b3994ec5 2003-12-11 devnull f->mtime = d->mtime;
799 67dbeee5 2017-10-10 rsc sha1(nil, 0, f->sha1, h);
800 67dbeee5 2017-10-10 rsc h = nil;
801 b3994ec5 2003-12-11 devnull f->mod = FALSE;
802 b3994ec5 2003-12-11 devnull w->dirty = FALSE;
803 b3994ec5 2003-12-11 devnull f->unread = FALSE;
804 b3994ec5 2003-12-11 devnull }
805 b3994ec5 2003-12-11 devnull for(i=0; i<f->ntext; i++){
806 b3994ec5 2003-12-11 devnull f->text[i]->w->putseq = f->seq;
807 b3994ec5 2003-12-11 devnull f->text[i]->w->dirty = w->dirty;
808 b3994ec5 2003-12-11 devnull }
809 b3994ec5 2003-12-11 devnull }
810 b3994ec5 2003-12-11 devnull fbuffree(s);
811 b3994ec5 2003-12-11 devnull fbuffree(r);
812 67dbeee5 2017-10-10 rsc free(h);
813 b3994ec5 2003-12-11 devnull free(d);
814 b3994ec5 2003-12-11 devnull free(namer);
815 b3994ec5 2003-12-11 devnull free(name);
816 b3994ec5 2003-12-11 devnull close(fd);
817 b3994ec5 2003-12-11 devnull winsettag(w);
818 b3994ec5 2003-12-11 devnull return;
819 b3994ec5 2003-12-11 devnull
820 b3994ec5 2003-12-11 devnull Rescue2:
821 1d2c3c39 2014-04-19 rsc if(b != nil) {
822 1d2c3c39 2014-04-19 rsc Bterm(b);
823 1d2c3c39 2014-04-19 rsc free(b);
824 93e2e820 2020-01-24 rsc close(fd);
825 1d2c3c39 2014-04-19 rsc }
826 67dbeee5 2017-10-10 rsc free(h);
827 b3994ec5 2003-12-11 devnull fbuffree(s);
828 b3994ec5 2003-12-11 devnull fbuffree(r);
829 b3994ec5 2003-12-11 devnull /* fall through */
830 b3994ec5 2003-12-11 devnull
831 b3994ec5 2003-12-11 devnull Rescue1:
832 b3994ec5 2003-12-11 devnull free(d);
833 b3994ec5 2003-12-11 devnull free(namer);
834 b3994ec5 2003-12-11 devnull free(name);
835 b3994ec5 2003-12-11 devnull }
836 b3994ec5 2003-12-11 devnull
837 16174277 2019-05-18 rsc static void
838 16174277 2019-05-18 rsc trimspaces(Text *et)
839 16174277 2019-05-18 rsc {
840 16174277 2019-05-18 rsc File *f;
841 16174277 2019-05-18 rsc Rune *r;
842 16174277 2019-05-18 rsc Text *t;
843 16174277 2019-05-18 rsc uint q0, n, delstart;
844 16174277 2019-05-18 rsc int c, i, marked;
845 16174277 2019-05-18 rsc
846 16174277 2019-05-18 rsc t = &et->w->body;
847 16174277 2019-05-18 rsc f = t->file;
848 16174277 2019-05-18 rsc marked = 0;
849 16174277 2019-05-18 rsc
850 16174277 2019-05-18 rsc if(t->w!=nil && et->w!=t->w){
851 16174277 2019-05-18 rsc /* can this happen when t == &et->w->body? */
852 16174277 2019-05-18 rsc c = 'M';
853 16174277 2019-05-18 rsc if(et->w)
854 16174277 2019-05-18 rsc c = et->w->owner;
855 16174277 2019-05-18 rsc winlock(t->w, c);
856 16174277 2019-05-18 rsc }
857 16174277 2019-05-18 rsc
858 16174277 2019-05-18 rsc r = fbufalloc();
859 16174277 2019-05-18 rsc q0 = f->b.nc;
860 16174277 2019-05-18 rsc delstart = q0; /* end of current space run, or 0 if no active run; = q0 to delete spaces before EOF */
861 16174277 2019-05-18 rsc while(q0 > 0) {
862 16174277 2019-05-18 rsc n = RBUFSIZE;
863 16174277 2019-05-18 rsc if(n > q0)
864 16174277 2019-05-18 rsc n = q0;
865 16174277 2019-05-18 rsc q0 -= n;
866 16174277 2019-05-18 rsc bufread(&f->b, q0, r, n);
867 16174277 2019-05-18 rsc for(i=n; ; i--) {
868 16174277 2019-05-18 rsc if(i == 0 || (r[i-1] != ' ' && r[i-1] != '\t')) {
869 16174277 2019-05-18 rsc // Found non-space or start of buffer. Delete active space run.
870 16174277 2019-05-18 rsc if(q0+i < delstart) {
871 16174277 2019-05-18 rsc if(!marked) {
872 16174277 2019-05-18 rsc marked = 1;
873 16174277 2019-05-18 rsc seq++;
874 16174277 2019-05-18 rsc filemark(f);
875 16174277 2019-05-18 rsc }
876 16174277 2019-05-18 rsc textdelete(t, q0+i, delstart, TRUE);
877 16174277 2019-05-18 rsc }
878 16174277 2019-05-18 rsc if(i == 0) {
879 16174277 2019-05-18 rsc /* keep run active into tail of next buffer */
880 16174277 2019-05-18 rsc if(delstart > 0)
881 16174277 2019-05-18 rsc delstart = q0;
882 16174277 2019-05-18 rsc break;
883 16174277 2019-05-18 rsc }
884 16174277 2019-05-18 rsc delstart = 0;
885 16174277 2019-05-18 rsc if(r[i-1] == '\n')
886 16174277 2019-05-18 rsc delstart = q0+i-1; /* delete spaces before this newline */
887 16174277 2019-05-18 rsc }
888 16174277 2019-05-18 rsc }
889 16174277 2019-05-18 rsc }
890 16174277 2019-05-18 rsc fbuffree(r);
891 16174277 2019-05-18 rsc
892 16174277 2019-05-18 rsc if(t->w!=nil && et->w!=t->w)
893 16174277 2019-05-18 rsc winunlock(t->w);
894 16174277 2019-05-18 rsc }
895 16174277 2019-05-18 rsc
896 b3994ec5 2003-12-11 devnull void
897 b3994ec5 2003-12-11 devnull put(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
898 b3994ec5 2003-12-11 devnull {
899 b3994ec5 2003-12-11 devnull int nname;
900 b3994ec5 2003-12-11 devnull Rune *namer;
901 b3994ec5 2003-12-11 devnull Window *w;
902 b3994ec5 2003-12-11 devnull File *f;
903 b3994ec5 2003-12-11 devnull char *name;
904 b3994ec5 2003-12-11 devnull
905 b3994ec5 2003-12-11 devnull USED(_0);
906 b3994ec5 2003-12-11 devnull USED(_1);
907 b3994ec5 2003-12-11 devnull USED(_2);
908 b3994ec5 2003-12-11 devnull
909 b3994ec5 2003-12-11 devnull if(et==nil || et->w==nil || et->w->isdir)
910 b3994ec5 2003-12-11 devnull return;
911 b3994ec5 2003-12-11 devnull w = et->w;
912 b3994ec5 2003-12-11 devnull f = w->body.file;
913 b3994ec5 2003-12-11 devnull name = getname(&w->body, argt, arg, narg, TRUE);
914 b3994ec5 2003-12-11 devnull if(name == nil){
915 5a8e63b2 2004-02-29 devnull warning(nil, "no file name\n");
916 b3994ec5 2003-12-11 devnull return;
917 b3994ec5 2003-12-11 devnull }
918 16174277 2019-05-18 rsc if(w->autoindent)
919 16174277 2019-05-18 rsc trimspaces(et);
920 b3994ec5 2003-12-11 devnull namer = bytetorune(name, &nname);
921 b3994ec5 2003-12-11 devnull putfile(f, 0, f->b.nc, namer, nname);
922 4a3fb872 2014-04-30 rsc xfidlog(w, "put");
923 b3994ec5 2003-12-11 devnull free(name);
924 b3994ec5 2003-12-11 devnull }
925 b3994ec5 2003-12-11 devnull
926 b3994ec5 2003-12-11 devnull void
927 b3994ec5 2003-12-11 devnull dump(Text *_0, Text *_1, Text *argt, int isdump, int _2, Rune *arg, int narg)
928 b3994ec5 2003-12-11 devnull {
929 b3994ec5 2003-12-11 devnull char *name;
930 b3994ec5 2003-12-11 devnull
931 b3994ec5 2003-12-11 devnull USED(_0);
932 b3994ec5 2003-12-11 devnull USED(_1);
933 b3994ec5 2003-12-11 devnull USED(_2);
934 b3994ec5 2003-12-11 devnull
935 b3994ec5 2003-12-11 devnull if(narg)
936 b3994ec5 2003-12-11 devnull name = runetobyte(arg, narg);
937 b3994ec5 2003-12-11 devnull else
938 b3994ec5 2003-12-11 devnull getbytearg(argt, FALSE, TRUE, &name);
939 b3994ec5 2003-12-11 devnull if(isdump)
940 b3994ec5 2003-12-11 devnull rowdump(&row, name);
941 b3994ec5 2003-12-11 devnull else
942 b3994ec5 2003-12-11 devnull rowload(&row, name, FALSE);
943 b3994ec5 2003-12-11 devnull free(name);
944 b3994ec5 2003-12-11 devnull }
945 b3994ec5 2003-12-11 devnull
946 b3994ec5 2003-12-11 devnull void
947 b3994ec5 2003-12-11 devnull cut(Text *et, Text *t, Text *_0, int dosnarf, int docut, Rune *_2, int _3)
948 b3994ec5 2003-12-11 devnull {
949 b3994ec5 2003-12-11 devnull uint q0, q1, n, locked, c;
950 b3994ec5 2003-12-11 devnull Rune *r;
951 b3994ec5 2003-12-11 devnull
952 b3994ec5 2003-12-11 devnull USED(_0);
953 b3994ec5 2003-12-11 devnull USED(_2);
954 b3994ec5 2003-12-11 devnull USED(_3);
955 b3994ec5 2003-12-11 devnull
956 9952c0eb 2007-06-15 devnull /*
957 9952c0eb 2007-06-15 devnull * if not executing a mouse chord (et != t) and snarfing (dosnarf)
958 9952c0eb 2007-06-15 devnull * and executed Cut or Snarf in window tag (et->w != nil),
959 9952c0eb 2007-06-15 devnull * then use the window body selection or the tag selection
960 9952c0eb 2007-06-15 devnull * or do nothing at all.
961 9952c0eb 2007-06-15 devnull */
962 b3994ec5 2003-12-11 devnull if(et!=t && dosnarf && et->w!=nil){
963 b3994ec5 2003-12-11 devnull if(et->w->body.q1>et->w->body.q0){
964 b3994ec5 2003-12-11 devnull t = &et->w->body;
965 b3994ec5 2003-12-11 devnull if(docut)
966 b3994ec5 2003-12-11 devnull filemark(t->file); /* seq has been incremented by execute */
967 b3994ec5 2003-12-11 devnull }else if(et->w->tag.q1>et->w->tag.q0)
968 b3994ec5 2003-12-11 devnull t = &et->w->tag;
969 9952c0eb 2007-06-15 devnull else
970 9952c0eb 2007-06-15 devnull t = nil;
971 b3994ec5 2003-12-11 devnull }
972 9952c0eb 2007-06-15 devnull if(t == nil) /* no selection */
973 b3994ec5 2003-12-11 devnull return;
974 9952c0eb 2007-06-15 devnull
975 b3994ec5 2003-12-11 devnull locked = FALSE;
976 b3994ec5 2003-12-11 devnull if(t->w!=nil && et->w!=t->w){
977 b3994ec5 2003-12-11 devnull locked = TRUE;
978 b3994ec5 2003-12-11 devnull c = 'M';
979 b3994ec5 2003-12-11 devnull if(et->w)
980 b3994ec5 2003-12-11 devnull c = et->w->owner;
981 b3994ec5 2003-12-11 devnull winlock(t->w, c);
982 b3994ec5 2003-12-11 devnull }
983 b3994ec5 2003-12-11 devnull if(t->q0 == t->q1){
984 b3994ec5 2003-12-11 devnull if(locked)
985 b3994ec5 2003-12-11 devnull winunlock(t->w);
986 b3994ec5 2003-12-11 devnull return;
987 b3994ec5 2003-12-11 devnull }
988 b3994ec5 2003-12-11 devnull if(dosnarf){
989 b3994ec5 2003-12-11 devnull q0 = t->q0;
990 b3994ec5 2003-12-11 devnull q1 = t->q1;
991 b3994ec5 2003-12-11 devnull bufdelete(&snarfbuf, 0, snarfbuf.nc);
992 b3994ec5 2003-12-11 devnull r = fbufalloc();
993 b3994ec5 2003-12-11 devnull while(q0 < q1){
994 b3994ec5 2003-12-11 devnull n = q1 - q0;
995 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
996 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
997 b3994ec5 2003-12-11 devnull bufread(&t->file->b, q0, r, n);
998 b3994ec5 2003-12-11 devnull bufinsert(&snarfbuf, snarfbuf.nc, r, n);
999 b3994ec5 2003-12-11 devnull q0 += n;
1000 b3994ec5 2003-12-11 devnull }
1001 b3994ec5 2003-12-11 devnull fbuffree(r);
1002 b3994ec5 2003-12-11 devnull acmeputsnarf();
1003 b3994ec5 2003-12-11 devnull }
1004 b3994ec5 2003-12-11 devnull if(docut){
1005 b3994ec5 2003-12-11 devnull textdelete(t, t->q0, t->q1, TRUE);
1006 b3994ec5 2003-12-11 devnull textsetselect(t, t->q0, t->q0);
1007 b3994ec5 2003-12-11 devnull if(t->w){
1008 b3994ec5 2003-12-11 devnull textscrdraw(t);
1009 b3994ec5 2003-12-11 devnull winsettag(t->w);
1010 b3994ec5 2003-12-11 devnull }
1011 b3994ec5 2003-12-11 devnull }else if(dosnarf) /* Snarf command */
1012 b3994ec5 2003-12-11 devnull argtext = t;
1013 b3994ec5 2003-12-11 devnull if(locked)
1014 b3994ec5 2003-12-11 devnull winunlock(t->w);
1015 b3994ec5 2003-12-11 devnull }
1016 b3994ec5 2003-12-11 devnull
1017 b3994ec5 2003-12-11 devnull void
1018 b3994ec5 2003-12-11 devnull paste(Text *et, Text *t, Text *_0, int selectall, int tobody, Rune *_1, int _2)
1019 b3994ec5 2003-12-11 devnull {
1020 b3994ec5 2003-12-11 devnull int c;
1021 b3994ec5 2003-12-11 devnull uint q, q0, q1, n;
1022 b3994ec5 2003-12-11 devnull Rune *r;
1023 b3994ec5 2003-12-11 devnull
1024 b3994ec5 2003-12-11 devnull USED(_0);
1025 b3994ec5 2003-12-11 devnull USED(_1);
1026 b3994ec5 2003-12-11 devnull USED(_2);
1027 b3994ec5 2003-12-11 devnull
1028 b3994ec5 2003-12-11 devnull /* if(tobody), use body of executing window (Paste or Send command) */
1029 b3994ec5 2003-12-11 devnull if(tobody && et!=nil && et->w!=nil){
1030 b3994ec5 2003-12-11 devnull t = &et->w->body;
1031 b3994ec5 2003-12-11 devnull filemark(t->file); /* seq has been incremented by execute */
1032 b3994ec5 2003-12-11 devnull }
1033 b3994ec5 2003-12-11 devnull if(t == nil)
1034 b3994ec5 2003-12-11 devnull return;
1035 b3994ec5 2003-12-11 devnull
1036 b3994ec5 2003-12-11 devnull acmegetsnarf();
1037 b3994ec5 2003-12-11 devnull if(t==nil || snarfbuf.nc==0)
1038 b3994ec5 2003-12-11 devnull return;
1039 b3994ec5 2003-12-11 devnull if(t->w!=nil && et->w!=t->w){
1040 b3994ec5 2003-12-11 devnull c = 'M';
1041 b3994ec5 2003-12-11 devnull if(et->w)
1042 b3994ec5 2003-12-11 devnull c = et->w->owner;
1043 b3994ec5 2003-12-11 devnull winlock(t->w, c);
1044 b3994ec5 2003-12-11 devnull }
1045 b3994ec5 2003-12-11 devnull cut(t, t, nil, FALSE, TRUE, nil, 0);
1046 b3994ec5 2003-12-11 devnull q = 0;
1047 b3994ec5 2003-12-11 devnull q0 = t->q0;
1048 b3994ec5 2003-12-11 devnull q1 = t->q0+snarfbuf.nc;
1049 b3994ec5 2003-12-11 devnull r = fbufalloc();
1050 b3994ec5 2003-12-11 devnull while(q0 < q1){
1051 b3994ec5 2003-12-11 devnull n = q1 - q0;
1052 b3994ec5 2003-12-11 devnull if(n > RBUFSIZE)
1053 b3994ec5 2003-12-11 devnull n = RBUFSIZE;
1054 b3994ec5 2003-12-11 devnull if(r == nil)
1055 b3994ec5 2003-12-11 devnull r = runemalloc(n);
1056 b3994ec5 2003-12-11 devnull bufread(&snarfbuf, q, r, n);
1057 b3994ec5 2003-12-11 devnull textinsert(t, q0, r, n, TRUE);
1058 b3994ec5 2003-12-11 devnull q += n;
1059 b3994ec5 2003-12-11 devnull q0 += n;
1060 b3994ec5 2003-12-11 devnull }
1061 b3994ec5 2003-12-11 devnull fbuffree(r);
1062 b3994ec5 2003-12-11 devnull if(selectall)
1063 b3994ec5 2003-12-11 devnull textsetselect(t, t->q0, q1);
1064 b3994ec5 2003-12-11 devnull else
1065 b3994ec5 2003-12-11 devnull textsetselect(t, q1, q1);
1066 b3994ec5 2003-12-11 devnull if(t->w){
1067 b3994ec5 2003-12-11 devnull textscrdraw(t);
1068 b3994ec5 2003-12-11 devnull winsettag(t->w);
1069 b3994ec5 2003-12-11 devnull }
1070 b3994ec5 2003-12-11 devnull if(t->w!=nil && et->w!=t->w)
1071 b3994ec5 2003-12-11 devnull winunlock(t->w);
1072 b3994ec5 2003-12-11 devnull }
1073 b3994ec5 2003-12-11 devnull
1074 b3994ec5 2003-12-11 devnull void
1075 b3994ec5 2003-12-11 devnull look(Text *et, Text *t, Text *argt, int _0, int _1, Rune *arg, int narg)
1076 b3994ec5 2003-12-11 devnull {
1077 b3994ec5 2003-12-11 devnull Rune *r;
1078 b3994ec5 2003-12-11 devnull int n;
1079 b3994ec5 2003-12-11 devnull
1080 b3994ec5 2003-12-11 devnull USED(_0);
1081 b3994ec5 2003-12-11 devnull USED(_1);
1082 b3994ec5 2003-12-11 devnull
1083 b3994ec5 2003-12-11 devnull if(et && et->w){
1084 b3994ec5 2003-12-11 devnull t = &et->w->body;
1085 b3994ec5 2003-12-11 devnull if(narg > 0){
1086 b3994ec5 2003-12-11 devnull search(t, arg, narg);
1087 b3994ec5 2003-12-11 devnull return;
1088 b3994ec5 2003-12-11 devnull }
1089 b3994ec5 2003-12-11 devnull getarg(argt, FALSE, FALSE, &r, &n);
1090 b3994ec5 2003-12-11 devnull if(r == nil){
1091 b3994ec5 2003-12-11 devnull n = t->q1-t->q0;
1092 b3994ec5 2003-12-11 devnull r = runemalloc(n);
1093 b3994ec5 2003-12-11 devnull bufread(&t->file->b, t->q0, r, n);
1094 b3994ec5 2003-12-11 devnull }
1095 b3994ec5 2003-12-11 devnull search(t, r, n);
1096 b3994ec5 2003-12-11 devnull free(r);
1097 b3994ec5 2003-12-11 devnull }
1098 b3994ec5 2003-12-11 devnull }
1099 b3994ec5 2003-12-11 devnull
1100 b3994ec5 2003-12-11 devnull static Rune Lnl[] = { '\n', 0 };
1101 b3994ec5 2003-12-11 devnull
1102 b3994ec5 2003-12-11 devnull void
1103 b3994ec5 2003-12-11 devnull sendx(Text *et, Text *t, Text *_0, int _1, int _2, Rune *_3, int _4)
1104 b3994ec5 2003-12-11 devnull {
1105 b3994ec5 2003-12-11 devnull USED(_0);
1106 b3994ec5 2003-12-11 devnull USED(_1);
1107 b3994ec5 2003-12-11 devnull USED(_2);
1108 b3994ec5 2003-12-11 devnull USED(_3);
1109 b3994ec5 2003-12-11 devnull USED(_4);
1110 b3994ec5 2003-12-11 devnull
1111 b3994ec5 2003-12-11 devnull if(et->w==nil)
1112 b3994ec5 2003-12-11 devnull return;
1113 b3994ec5 2003-12-11 devnull t = &et->w->body;
1114 b3994ec5 2003-12-11 devnull if(t->q0 != t->q1)
1115 b3994ec5 2003-12-11 devnull cut(t, t, nil, TRUE, FALSE, nil, 0);
1116 b3994ec5 2003-12-11 devnull textsetselect(t, t->file->b.nc, t->file->b.nc);
1117 b3994ec5 2003-12-11 devnull paste(t, t, nil, TRUE, TRUE, nil, 0);
1118 b3994ec5 2003-12-11 devnull if(textreadc(t, t->file->b.nc-1) != '\n'){
1119 b3994ec5 2003-12-11 devnull textinsert(t, t->file->b.nc, Lnl, 1, TRUE);
1120 b3994ec5 2003-12-11 devnull textsetselect(t, t->file->b.nc, t->file->b.nc);
1121 b3994ec5 2003-12-11 devnull }
1122 76864eb6 2011-08-02 rsc t->iq1 = t->q1;
1123 76864eb6 2011-08-02 rsc textshow(t, t->q1, t->q1, 1);
1124 b3994ec5 2003-12-11 devnull }
1125 b3994ec5 2003-12-11 devnull
1126 b3994ec5 2003-12-11 devnull void
1127 b3994ec5 2003-12-11 devnull edit(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
1128 b3994ec5 2003-12-11 devnull {
1129 b3994ec5 2003-12-11 devnull Rune *r;
1130 b3994ec5 2003-12-11 devnull int len;
1131 b3994ec5 2003-12-11 devnull
1132 b3994ec5 2003-12-11 devnull USED(_0);
1133 b3994ec5 2003-12-11 devnull USED(_1);
1134 b3994ec5 2003-12-11 devnull USED(_2);
1135 b3994ec5 2003-12-11 devnull
1136 b3994ec5 2003-12-11 devnull if(et == nil)
1137 b3994ec5 2003-12-11 devnull return;
1138 b3994ec5 2003-12-11 devnull getarg(argt, FALSE, TRUE, &r, &len);
1139 b3994ec5 2003-12-11 devnull seq++;
1140 b3994ec5 2003-12-11 devnull if(r != nil){
1141 b3994ec5 2003-12-11 devnull editcmd(et, r, len);
1142 b3994ec5 2003-12-11 devnull free(r);
1143 b3994ec5 2003-12-11 devnull }else
1144 b3994ec5 2003-12-11 devnull editcmd(et, arg, narg);
1145 b3994ec5 2003-12-11 devnull }
1146 b3994ec5 2003-12-11 devnull
1147 b3994ec5 2003-12-11 devnull void
1148 b3994ec5 2003-12-11 devnull xexit(Text *et, Text *_0, Text *_1, int _2, int _3, Rune *_4, int _5)
1149 b3994ec5 2003-12-11 devnull {
1150 b3994ec5 2003-12-11 devnull USED(et);
1151 b3994ec5 2003-12-11 devnull USED(_0);
1152 b3994ec5 2003-12-11 devnull USED(_1);
1153 b3994ec5 2003-12-11 devnull USED(_2);
1154 b3994ec5 2003-12-11 devnull USED(_3);
1155 b3994ec5 2003-12-11 devnull USED(_4);
1156 b3994ec5 2003-12-11 devnull USED(_5);
1157 b3994ec5 2003-12-11 devnull
1158 b3994ec5 2003-12-11 devnull if(rowclean(&row)){
1159 b3994ec5 2003-12-11 devnull sendul(cexit, 0);
1160 b3994ec5 2003-12-11 devnull threadexits(nil);
1161 b3994ec5 2003-12-11 devnull }
1162 b3994ec5 2003-12-11 devnull }
1163 b3994ec5 2003-12-11 devnull
1164 b3994ec5 2003-12-11 devnull void
1165 b3994ec5 2003-12-11 devnull putall(Text *et, Text *_0, Text *_1, int _2, int _3, Rune *_4, int _5)
1166 b3994ec5 2003-12-11 devnull {
1167 b3994ec5 2003-12-11 devnull int i, j, e;
1168 b3994ec5 2003-12-11 devnull Window *w;
1169 b3994ec5 2003-12-11 devnull Column *c;
1170 b3994ec5 2003-12-11 devnull char *a;
1171 b3994ec5 2003-12-11 devnull
1172 b3994ec5 2003-12-11 devnull USED(et);
1173 b3994ec5 2003-12-11 devnull USED(_0);
1174 b3994ec5 2003-12-11 devnull USED(_1);
1175 b3994ec5 2003-12-11 devnull USED(_2);
1176 b3994ec5 2003-12-11 devnull USED(_3);
1177 b3994ec5 2003-12-11 devnull USED(_4);
1178 b3994ec5 2003-12-11 devnull USED(_5);
1179 b3994ec5 2003-12-11 devnull
1180 b3994ec5 2003-12-11 devnull for(i=0; i<row.ncol; i++){
1181 b3994ec5 2003-12-11 devnull c = row.col[i];
1182 b3994ec5 2003-12-11 devnull for(j=0; j<c->nw; j++){
1183 b3994ec5 2003-12-11 devnull w = c->w[j];
1184 b3994ec5 2003-12-11 devnull if(w->isscratch || w->isdir || w->body.file->nname==0)
1185 b3994ec5 2003-12-11 devnull continue;
1186 b3994ec5 2003-12-11 devnull if(w->nopen[QWevent] > 0)
1187 b3994ec5 2003-12-11 devnull continue;
1188 b3994ec5 2003-12-11 devnull a = runetobyte(w->body.file->name, w->body.file->nname);
1189 b3994ec5 2003-12-11 devnull e = access(a, 0);
1190 b3994ec5 2003-12-11 devnull if(w->body.file->mod || w->body.ncache)
1191 b3994ec5 2003-12-11 devnull if(e < 0)
1192 b3994ec5 2003-12-11 devnull warning(nil, "no auto-Put of %s: %r\n", a);
1193 b3994ec5 2003-12-11 devnull else{
1194 b3994ec5 2003-12-11 devnull wincommit(w, &w->body);
1195 b3994ec5 2003-12-11 devnull put(&w->body, nil, nil, XXX, XXX, nil, 0);
1196 b3994ec5 2003-12-11 devnull }
1197 b3994ec5 2003-12-11 devnull free(a);
1198 b3994ec5 2003-12-11 devnull }
1199 b3994ec5 2003-12-11 devnull }
1200 b3994ec5 2003-12-11 devnull }
1201 b3994ec5 2003-12-11 devnull
1202 b3994ec5 2003-12-11 devnull
1203 b3994ec5 2003-12-11 devnull void
1204 b3994ec5 2003-12-11 devnull id(Text *et, Text *_0, Text *_1, int _2, int _3, Rune *_4, int _5)
1205 b3994ec5 2003-12-11 devnull {
1206 b3994ec5 2003-12-11 devnull USED(_0);
1207 b3994ec5 2003-12-11 devnull USED(_1);
1208 b3994ec5 2003-12-11 devnull USED(_2);
1209 b3994ec5 2003-12-11 devnull USED(_3);
1210 b3994ec5 2003-12-11 devnull USED(_4);
1211 b3994ec5 2003-12-11 devnull USED(_5);
1212 b3994ec5 2003-12-11 devnull
1213 b3994ec5 2003-12-11 devnull if(et && et->w)
1214 b3994ec5 2003-12-11 devnull warning(nil, "/mnt/acme/%d/\n", et->w->id);
1215 b3994ec5 2003-12-11 devnull }
1216 b3994ec5 2003-12-11 devnull
1217 b3994ec5 2003-12-11 devnull void
1218 b3994ec5 2003-12-11 devnull local(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
1219 b3994ec5 2003-12-11 devnull {
1220 b3994ec5 2003-12-11 devnull char *a, *aa;
1221 b3994ec5 2003-12-11 devnull Runestr dir;
1222 b3994ec5 2003-12-11 devnull
1223 b3994ec5 2003-12-11 devnull USED(_0);
1224 b3994ec5 2003-12-11 devnull USED(_1);
1225 b3994ec5 2003-12-11 devnull USED(_2);
1226 b3994ec5 2003-12-11 devnull
1227 b3994ec5 2003-12-11 devnull aa = getbytearg(argt, TRUE, TRUE, &a);
1228 b3994ec5 2003-12-11 devnull
1229 b3994ec5 2003-12-11 devnull dir = dirname(et, nil, 0);
1230 b3994ec5 2003-12-11 devnull if(dir.nr==1 && dir.r[0]=='.'){ /* sigh */
1231 b3994ec5 2003-12-11 devnull free(dir.r);
1232 b3994ec5 2003-12-11 devnull dir.r = nil;
1233 b3994ec5 2003-12-11 devnull dir.nr = 0;
1234 b3994ec5 2003-12-11 devnull }
1235 b3994ec5 2003-12-11 devnull run(nil, runetobyte(arg, narg), dir.r, dir.nr, FALSE, aa, a, FALSE);
1236 b3994ec5 2003-12-11 devnull }
1237 b3994ec5 2003-12-11 devnull
1238 b3994ec5 2003-12-11 devnull void
1239 b3994ec5 2003-12-11 devnull xkill(Text *_0, Text *_1, Text *argt, int _2, int _3, Rune *arg, int narg)
1240 b3994ec5 2003-12-11 devnull {
1241 b3994ec5 2003-12-11 devnull Rune *a, *cmd, *r;
1242 b3994ec5 2003-12-11 devnull int na;
1243 b3994ec5 2003-12-11 devnull
1244 b3994ec5 2003-12-11 devnull USED(_0);
1245 b3994ec5 2003-12-11 devnull USED(_1);
1246 b3994ec5 2003-12-11 devnull USED(_2);
1247 b3994ec5 2003-12-11 devnull USED(_3);
1248 b3994ec5 2003-12-11 devnull
1249 b3994ec5 2003-12-11 devnull getarg(argt, FALSE, FALSE, &r, &na);
1250 b3994ec5 2003-12-11 devnull if(r)
1251 b3994ec5 2003-12-11 devnull xkill(nil, nil, nil, 0, 0, r, na);
1252 b3994ec5 2003-12-11 devnull /* loop condition: *arg is not a blank */
1253 b3994ec5 2003-12-11 devnull for(;;){
1254 b3994ec5 2003-12-11 devnull a = findbl(arg, narg, &na);
1255 b3994ec5 2003-12-11 devnull if(a == arg)
1256 b3994ec5 2003-12-11 devnull break;
1257 b3994ec5 2003-12-11 devnull cmd = runemalloc(narg-na+1);
1258 b3994ec5 2003-12-11 devnull runemove(cmd, arg, narg-na);
1259 b3994ec5 2003-12-11 devnull sendp(ckill, cmd);
1260 b3994ec5 2003-12-11 devnull arg = skipbl(a, na, &narg);
1261 b3994ec5 2003-12-11 devnull }
1262 b3994ec5 2003-12-11 devnull }
1263 b3994ec5 2003-12-11 devnull
1264 b3994ec5 2003-12-11 devnull static Rune Lfix[] = { 'f', 'i', 'x', 0 };
1265 b3994ec5 2003-12-11 devnull static Rune Lvar[] = { 'v', 'a', 'r', 0 };
1266 b3994ec5 2003-12-11 devnull
1267 b3994ec5 2003-12-11 devnull void
1268 b3994ec5 2003-12-11 devnull fontx(Text *et, Text *t, Text *argt, int _0, int _1, Rune *arg, int narg)
1269 b3994ec5 2003-12-11 devnull {
1270 b3994ec5 2003-12-11 devnull Rune *a, *r, *flag, *file;
1271 b3994ec5 2003-12-11 devnull int na, nf;
1272 b3994ec5 2003-12-11 devnull char *aa;
1273 b3994ec5 2003-12-11 devnull Reffont *newfont;
1274 b3994ec5 2003-12-11 devnull Dirlist *dp;
1275 b3994ec5 2003-12-11 devnull int i, fix;
1276 b3994ec5 2003-12-11 devnull
1277 b3994ec5 2003-12-11 devnull USED(_0);
1278 b3994ec5 2003-12-11 devnull USED(_1);
1279 b3994ec5 2003-12-11 devnull
1280 b3994ec5 2003-12-11 devnull if(et==nil || et->w==nil)
1281 b3994ec5 2003-12-11 devnull return;
1282 b3994ec5 2003-12-11 devnull t = &et->w->body;
1283 b3994ec5 2003-12-11 devnull flag = nil;
1284 b3994ec5 2003-12-11 devnull file = nil;
1285 b3994ec5 2003-12-11 devnull /* loop condition: *arg is not a blank */
1286 b3994ec5 2003-12-11 devnull nf = 0;
1287 b3994ec5 2003-12-11 devnull for(;;){
1288 b3994ec5 2003-12-11 devnull a = findbl(arg, narg, &na);
1289 b3994ec5 2003-12-11 devnull if(a == arg)
1290 b3994ec5 2003-12-11 devnull break;
1291 b3994ec5 2003-12-11 devnull r = runemalloc(narg-na+1);
1292 b3994ec5 2003-12-11 devnull runemove(r, arg, narg-na);
1293 b3994ec5 2003-12-11 devnull if(runeeq(r, narg-na, Lfix, 3) || runeeq(r, narg-na, Lvar, 3)){
1294 b3994ec5 2003-12-11 devnull free(flag);
1295 b3994ec5 2003-12-11 devnull flag = r;
1296 b3994ec5 2003-12-11 devnull }else{
1297 b3994ec5 2003-12-11 devnull free(file);
1298 b3994ec5 2003-12-11 devnull file = r;
1299 b3994ec5 2003-12-11 devnull nf = narg-na;
1300 b3994ec5 2003-12-11 devnull }
1301 b3994ec5 2003-12-11 devnull arg = skipbl(a, na, &narg);
1302 b3994ec5 2003-12-11 devnull }
1303 b3994ec5 2003-12-11 devnull getarg(argt, FALSE, TRUE, &r, &na);
1304 b3994ec5 2003-12-11 devnull if(r)
1305 b3994ec5 2003-12-11 devnull if(runeeq(r, na, Lfix, 3) || runeeq(r, na, Lvar, 3)){
1306 b3994ec5 2003-12-11 devnull free(flag);
1307 b3994ec5 2003-12-11 devnull flag = r;
1308 b3994ec5 2003-12-11 devnull }else{
1309 b3994ec5 2003-12-11 devnull free(file);
1310 b3994ec5 2003-12-11 devnull file = r;
1311 b3994ec5 2003-12-11 devnull nf = na;
1312 b3994ec5 2003-12-11 devnull }
1313 b3994ec5 2003-12-11 devnull fix = 1;
1314 b3994ec5 2003-12-11 devnull if(flag)
1315 b3994ec5 2003-12-11 devnull fix = runeeq(flag, runestrlen(flag), Lfix, 3);
1316 b3994ec5 2003-12-11 devnull else if(file == nil){
1317 b3994ec5 2003-12-11 devnull newfont = rfget(FALSE, FALSE, FALSE, nil);
1318 b3994ec5 2003-12-11 devnull if(newfont)
1319 b3994ec5 2003-12-11 devnull fix = strcmp(newfont->f->name, t->fr.font->name)==0;
1320 b3994ec5 2003-12-11 devnull }
1321 b3994ec5 2003-12-11 devnull if(file){
1322 b3994ec5 2003-12-11 devnull aa = runetobyte(file, nf);
1323 b3994ec5 2003-12-11 devnull newfont = rfget(fix, flag!=nil, FALSE, aa);
1324 b3994ec5 2003-12-11 devnull free(aa);
1325 b3994ec5 2003-12-11 devnull }else
1326 b3994ec5 2003-12-11 devnull newfont = rfget(fix, FALSE, FALSE, nil);
1327 b3994ec5 2003-12-11 devnull if(newfont){
1328 b3994ec5 2003-12-11 devnull draw(screen, t->w->r, textcols[BACK], nil, ZP);
1329 b3994ec5 2003-12-11 devnull rfclose(t->reffont);
1330 b3994ec5 2003-12-11 devnull t->reffont = newfont;
1331 b3994ec5 2003-12-11 devnull t->fr.font = newfont->f;
1332 b3994ec5 2003-12-11 devnull frinittick(&t->fr);
1333 b3994ec5 2003-12-11 devnull if(t->w->isdir){
1334 b3994ec5 2003-12-11 devnull t->all.min.x++; /* force recolumnation; disgusting! */
1335 b3994ec5 2003-12-11 devnull for(i=0; i<t->w->ndl; i++){
1336 b3994ec5 2003-12-11 devnull dp = t->w->dlp[i];
1337 b3994ec5 2003-12-11 devnull aa = runetobyte(dp->r, dp->nr);
1338 b3994ec5 2003-12-11 devnull dp->wid = stringwidth(newfont->f, aa);
1339 b3994ec5 2003-12-11 devnull free(aa);
1340 b3994ec5 2003-12-11 devnull }
1341 b3994ec5 2003-12-11 devnull }
1342 b3994ec5 2003-12-11 devnull /* avoid shrinking of window due to quantization */
1343 b3994ec5 2003-12-11 devnull colgrow(t->w->col, t->w, -1);
1344 b3994ec5 2003-12-11 devnull }
1345 b3994ec5 2003-12-11 devnull free(file);
1346 b3994ec5 2003-12-11 devnull free(flag);
1347 b3994ec5 2003-12-11 devnull }
1348 b3994ec5 2003-12-11 devnull
1349 b3994ec5 2003-12-11 devnull void
1350 b3994ec5 2003-12-11 devnull incl(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
1351 b3994ec5 2003-12-11 devnull {
1352 b3994ec5 2003-12-11 devnull Rune *a, *r;
1353 b3994ec5 2003-12-11 devnull Window *w;
1354 b3994ec5 2003-12-11 devnull int na, n, len;
1355 b3994ec5 2003-12-11 devnull
1356 b3994ec5 2003-12-11 devnull USED(_0);
1357 b3994ec5 2003-12-11 devnull USED(_1);
1358 b3994ec5 2003-12-11 devnull USED(_2);
1359 b3994ec5 2003-12-11 devnull
1360 b3994ec5 2003-12-11 devnull if(et==nil || et->w==nil)
1361 b3994ec5 2003-12-11 devnull return;
1362 b3994ec5 2003-12-11 devnull w = et->w;
1363 b3994ec5 2003-12-11 devnull n = 0;
1364 b3994ec5 2003-12-11 devnull getarg(argt, FALSE, TRUE, &r, &len);
1365 b3994ec5 2003-12-11 devnull if(r){
1366 b3994ec5 2003-12-11 devnull n++;
1367 b3994ec5 2003-12-11 devnull winaddincl(w, r, len);
1368 b3994ec5 2003-12-11 devnull }
1369 b3994ec5 2003-12-11 devnull /* loop condition: *arg is not a blank */
1370 b3994ec5 2003-12-11 devnull for(;;){
1371 b3994ec5 2003-12-11 devnull a = findbl(arg, narg, &na);
1372 b3994ec5 2003-12-11 devnull if(a == arg)
1373 b3994ec5 2003-12-11 devnull break;
1374 b3994ec5 2003-12-11 devnull r = runemalloc(narg-na+1);
1375 b3994ec5 2003-12-11 devnull runemove(r, arg, narg-na);
1376 b3994ec5 2003-12-11 devnull n++;
1377 b3994ec5 2003-12-11 devnull winaddincl(w, r, narg-na);
1378 b3994ec5 2003-12-11 devnull arg = skipbl(a, na, &narg);
1379 b3994ec5 2003-12-11 devnull }
1380 b3994ec5 2003-12-11 devnull if(n==0 && w->nincl){
1381 b3994ec5 2003-12-11 devnull for(n=w->nincl; --n>=0; )
1382 b3994ec5 2003-12-11 devnull warning(nil, "%S ", w->incl[n]);
1383 b3994ec5 2003-12-11 devnull warning(nil, "\n");
1384 5a8e63b2 2004-02-29 devnull }
1385 5a8e63b2 2004-02-29 devnull }
1386 5a8e63b2 2004-02-29 devnull
1387 5a8e63b2 2004-02-29 devnull static Rune LON[] = { 'O', 'N', 0 };
1388 5a8e63b2 2004-02-29 devnull static Rune LOFF[] = { 'O', 'F', 'F', 0 };
1389 5a8e63b2 2004-02-29 devnull static Rune Lon[] = { 'o', 'n', 0 };
1390 5a8e63b2 2004-02-29 devnull
1391 53998c99 2004-09-28 devnull enum {
1392 53998c99 2004-09-28 devnull IGlobal = -2,
1393 53998c99 2004-09-28 devnull IError = -1,
1394 53998c99 2004-09-28 devnull Ion = 0,
1395 cbeb0b26 2006-04-01 devnull Ioff = 1
1396 53998c99 2004-09-28 devnull };
1397 53998c99 2004-09-28 devnull
1398 5a8e63b2 2004-02-29 devnull static int
1399 5a8e63b2 2004-02-29 devnull indentval(Rune *s, int n)
1400 5a8e63b2 2004-02-29 devnull {
1401 5a8e63b2 2004-02-29 devnull if(n < 2)
1402 53998c99 2004-09-28 devnull return IError;
1403 5a8e63b2 2004-02-29 devnull if(runestrncmp(s, LON, n) == 0){
1404 5a8e63b2 2004-02-29 devnull globalautoindent = TRUE;
1405 5a8e63b2 2004-02-29 devnull warning(nil, "Indent ON\n");
1406 53998c99 2004-09-28 devnull return IGlobal;
1407 5a8e63b2 2004-02-29 devnull }
1408 5a8e63b2 2004-02-29 devnull if(runestrncmp(s, LOFF, n) == 0){
1409 5a8e63b2 2004-02-29 devnull globalautoindent = FALSE;
1410 5a8e63b2 2004-02-29 devnull warning(nil, "Indent OFF\n");
1411 53998c99 2004-09-28 devnull return IGlobal;
1412 5a8e63b2 2004-02-29 devnull }
1413 5a8e63b2 2004-02-29 devnull return runestrncmp(s, Lon, n) == 0;
1414 5a8e63b2 2004-02-29 devnull }
1415 5a8e63b2 2004-02-29 devnull
1416 9952c0eb 2007-06-15 devnull static void
1417 9952c0eb 2007-06-15 devnull fixindent(Window *w, void *arg)
1418 9952c0eb 2007-06-15 devnull {
1419 9952c0eb 2007-06-15 devnull USED(arg);
1420 9952c0eb 2007-06-15 devnull w->autoindent = globalautoindent;
1421 9952c0eb 2007-06-15 devnull }
1422 9952c0eb 2007-06-15 devnull
1423 5a8e63b2 2004-02-29 devnull void
1424 5a8e63b2 2004-02-29 devnull indent(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
1425 5a8e63b2 2004-02-29 devnull {
1426 5a8e63b2 2004-02-29 devnull Rune *a, *r;
1427 5a8e63b2 2004-02-29 devnull Window *w;
1428 5a8e63b2 2004-02-29 devnull int na, len, autoindent;
1429 5a8e63b2 2004-02-29 devnull
1430 5a8e63b2 2004-02-29 devnull USED(_0);
1431 5a8e63b2 2004-02-29 devnull USED(_1);
1432 5a8e63b2 2004-02-29 devnull USED(_2);
1433 5a8e63b2 2004-02-29 devnull
1434 53998c99 2004-09-28 devnull w = nil;
1435 53998c99 2004-09-28 devnull if(et!=nil && et->w!=nil)
1436 53998c99 2004-09-28 devnull w = et->w;
1437 53998c99 2004-09-28 devnull autoindent = IError;
1438 5a8e63b2 2004-02-29 devnull getarg(argt, FALSE, TRUE, &r, &len);
1439 5a8e63b2 2004-02-29 devnull if(r!=nil && len>0)
1440 5a8e63b2 2004-02-29 devnull autoindent = indentval(r, len);
1441 5a8e63b2 2004-02-29 devnull else{
1442 5a8e63b2 2004-02-29 devnull a = findbl(arg, narg, &na);
1443 5a8e63b2 2004-02-29 devnull if(a != arg)
1444 5a8e63b2 2004-02-29 devnull autoindent = indentval(arg, narg-na);
1445 b3994ec5 2003-12-11 devnull }
1446 9952c0eb 2007-06-15 devnull if(autoindent == IGlobal)
1447 9952c0eb 2007-06-15 devnull allwindows(fixindent, nil);
1448 9952c0eb 2007-06-15 devnull else if(w != nil && autoindent >= 0)
1449 9952c0eb 2007-06-15 devnull w->autoindent = autoindent;
1450 b3994ec5 2003-12-11 devnull }
1451 b3994ec5 2003-12-11 devnull
1452 b3994ec5 2003-12-11 devnull void
1453 b3994ec5 2003-12-11 devnull tab(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
1454 b3994ec5 2003-12-11 devnull {
1455 b3994ec5 2003-12-11 devnull Rune *a, *r;
1456 b3994ec5 2003-12-11 devnull Window *w;
1457 b3994ec5 2003-12-11 devnull int na, len, tab;
1458 b3994ec5 2003-12-11 devnull char *p;
1459 b3994ec5 2003-12-11 devnull
1460 b3994ec5 2003-12-11 devnull USED(_0);
1461 b3994ec5 2003-12-11 devnull USED(_1);
1462 b3994ec5 2003-12-11 devnull USED(_2);
1463 b3994ec5 2003-12-11 devnull
1464 b3994ec5 2003-12-11 devnull if(et==nil || et->w==nil)
1465 b3994ec5 2003-12-11 devnull return;
1466 b3994ec5 2003-12-11 devnull w = et->w;
1467 b3994ec5 2003-12-11 devnull getarg(argt, FALSE, TRUE, &r, &len);
1468 b3994ec5 2003-12-11 devnull tab = 0;
1469 b3994ec5 2003-12-11 devnull if(r!=nil && len>0){
1470 b3994ec5 2003-12-11 devnull p = runetobyte(r, len);
1471 b3994ec5 2003-12-11 devnull if('0'<=p[0] && p[0]<='9')
1472 b3994ec5 2003-12-11 devnull tab = atoi(p);
1473 b3994ec5 2003-12-11 devnull free(p);
1474 b3994ec5 2003-12-11 devnull }else{
1475 b3994ec5 2003-12-11 devnull a = findbl(arg, narg, &na);
1476 b3994ec5 2003-12-11 devnull if(a != arg){
1477 b3994ec5 2003-12-11 devnull p = runetobyte(arg, narg-na);
1478 b3994ec5 2003-12-11 devnull if('0'<=p[0] && p[0]<='9')
1479 b3994ec5 2003-12-11 devnull tab = atoi(p);
1480 b3994ec5 2003-12-11 devnull free(p);
1481 b3994ec5 2003-12-11 devnull }
1482 b3994ec5 2003-12-11 devnull }
1483 b3994ec5 2003-12-11 devnull if(tab > 0){
1484 b3994ec5 2003-12-11 devnull if(w->body.tabstop != tab){
1485 b3994ec5 2003-12-11 devnull w->body.tabstop = tab;
1486 34b2f0bc 2007-11-29 rsc winresize(w, w->r, FALSE, TRUE);
1487 b3994ec5 2003-12-11 devnull }
1488 b3994ec5 2003-12-11 devnull }else
1489 b3994ec5 2003-12-11 devnull warning(nil, "%.*S: Tab %d\n", w->body.file->nname, w->body.file->name, w->body.tabstop);
1490 b3994ec5 2003-12-11 devnull }
1491 b3994ec5 2003-12-11 devnull
1492 b3994ec5 2003-12-11 devnull void
1493 b3994ec5 2003-12-11 devnull runproc(void *argvp)
1494 b3994ec5 2003-12-11 devnull {
1495 b3994ec5 2003-12-11 devnull /* args: */
1496 b3994ec5 2003-12-11 devnull Window *win;
1497 b3994ec5 2003-12-11 devnull char *s;
1498 b3994ec5 2003-12-11 devnull Rune *rdir;
1499 b3994ec5 2003-12-11 devnull int ndir;
1500 b3994ec5 2003-12-11 devnull int newns;
1501 b3994ec5 2003-12-11 devnull char *argaddr;
1502 b3994ec5 2003-12-11 devnull char *arg;
1503 b3994ec5 2003-12-11 devnull Command *c;
1504 b3994ec5 2003-12-11 devnull Channel *cpid;
1505 b3994ec5 2003-12-11 devnull int iseditcmd;
1506 b3994ec5 2003-12-11 devnull /* end of args */
1507 b3994ec5 2003-12-11 devnull char *e, *t, *name, *filename, *dir, **av, *news;
1508 b3994ec5 2003-12-11 devnull Rune r, **incl;
1509 b3994ec5 2003-12-11 devnull int ac, w, inarg, i, n, fd, nincl, winid;
1510 b3994ec5 2003-12-11 devnull int sfd[3];
1511 b3994ec5 2003-12-11 devnull int pipechar;
1512 b3994ec5 2003-12-11 devnull char buf[512];
1513 bf27f587 2004-05-15 devnull int ret;
1514 cbeb0b26 2006-04-01 devnull /*static void *parg[2]; */
1515 bf27f587 2004-05-15 devnull char *rcarg[4];
1516 b3994ec5 2003-12-11 devnull void **argv;
1517 05636f83 2005-01-04 devnull CFsys *fs;
1518 81c2c5e7 2012-10-21 rsc char *shell;
1519 391363f5 2005-09-26 devnull
1520 391363f5 2005-09-26 devnull threadsetname("runproc");
1521 b3994ec5 2003-12-11 devnull
1522 b3994ec5 2003-12-11 devnull argv = argvp;
1523 b3994ec5 2003-12-11 devnull win = argv[0];
1524 b3994ec5 2003-12-11 devnull s = argv[1];
1525 b3994ec5 2003-12-11 devnull rdir = argv[2];
1526 a4bbf47b 2005-12-21 devnull ndir = (uintptr)argv[3];
1527 a4bbf47b 2005-12-21 devnull newns = (uintptr)argv[4];
1528 b3994ec5 2003-12-11 devnull argaddr = argv[5];
1529 b3994ec5 2003-12-11 devnull arg = argv[6];
1530 b3994ec5 2003-12-11 devnull c = argv[7];
1531 b3994ec5 2003-12-11 devnull cpid = argv[8];
1532 a4bbf47b 2005-12-21 devnull iseditcmd = (uintptr)argv[9];
1533 b3994ec5 2003-12-11 devnull free(argv);
1534 b3994ec5 2003-12-11 devnull
1535 b3994ec5 2003-12-11 devnull t = s;
1536 b3994ec5 2003-12-11 devnull while(*t==' ' || *t=='\n' || *t=='\t')
1537 b3994ec5 2003-12-11 devnull t++;
1538 b3994ec5 2003-12-11 devnull for(e=t; *e; e++)
1539 b3994ec5 2003-12-11 devnull if(*e==' ' || *e=='\n' || *e=='\t' )
1540 b3994ec5 2003-12-11 devnull break;
1541 b3994ec5 2003-12-11 devnull name = emalloc((e-t)+2);
1542 b3994ec5 2003-12-11 devnull memmove(name, t, e-t);
1543 b3994ec5 2003-12-11 devnull name[e-t] = 0;
1544 b3994ec5 2003-12-11 devnull e = utfrrune(name, '/');
1545 b3994ec5 2003-12-11 devnull if(e)
1546 1a8f27c3 2004-05-14 devnull memmove(name, e+1, strlen(e+1)+1); /* strcpy but overlaps */
1547 b3994ec5 2003-12-11 devnull strcat(name, " "); /* add blank here for ease in waittask */
1548 b3994ec5 2003-12-11 devnull c->name = bytetorune(name, &c->nname);
1549 b3994ec5 2003-12-11 devnull free(name);
1550 b3994ec5 2003-12-11 devnull pipechar = 0;
1551 b3994ec5 2003-12-11 devnull if(*t=='<' || *t=='|' || *t=='>')
1552 b3994ec5 2003-12-11 devnull pipechar = *t++;
1553 b3994ec5 2003-12-11 devnull c->iseditcmd = iseditcmd;
1554 b3994ec5 2003-12-11 devnull c->text = s;
1555 b3994ec5 2003-12-11 devnull if(newns){
1556 b3994ec5 2003-12-11 devnull nincl = 0;
1557 b3994ec5 2003-12-11 devnull incl = nil;
1558 b3994ec5 2003-12-11 devnull if(win){
1559 b3994ec5 2003-12-11 devnull filename = smprint("%.*S", win->body.file->nname, win->body.file->name);
1560 b3994ec5 2003-12-11 devnull nincl = win->nincl;
1561 b3994ec5 2003-12-11 devnull if(nincl > 0){
1562 b3994ec5 2003-12-11 devnull incl = emalloc(nincl*sizeof(Rune*));
1563 b3994ec5 2003-12-11 devnull for(i=0; i<nincl; i++){
1564 b3994ec5 2003-12-11 devnull n = runestrlen(win->incl[i]);
1565 b3994ec5 2003-12-11 devnull incl[i] = runemalloc(n+1);
1566 b3994ec5 2003-12-11 devnull runemove(incl[i], win->incl[i], n);
1567 b3994ec5 2003-12-11 devnull }
1568 b3994ec5 2003-12-11 devnull }
1569 b3994ec5 2003-12-11 devnull winid = win->id;
1570 b3994ec5 2003-12-11 devnull }else{
1571 b3994ec5 2003-12-11 devnull filename = nil;
1572 b3994ec5 2003-12-11 devnull winid = 0;
1573 b3994ec5 2003-12-11 devnull if(activewin)
1574 b3994ec5 2003-12-11 devnull winid = activewin->id;
1575 b3994ec5 2003-12-11 devnull }
1576 b3994ec5 2003-12-11 devnull rfork(RFNAMEG|RFENVG|RFFDG|RFNOTEG);
1577 b3994ec5 2003-12-11 devnull sprint(buf, "%d", winid);
1578 b3994ec5 2003-12-11 devnull putenv("winid", buf);
1579 b3994ec5 2003-12-11 devnull
1580 b3994ec5 2003-12-11 devnull if(filename){
1581 b3994ec5 2003-12-11 devnull putenv("%", filename);
1582 2589c5c6 2012-11-26 rsc putenv("samfile", filename);
1583 b3994ec5 2003-12-11 devnull free(filename);
1584 b3994ec5 2003-12-11 devnull }
1585 b3994ec5 2003-12-11 devnull c->md = fsysmount(rdir, ndir, incl, nincl);
1586 b3994ec5 2003-12-11 devnull if(c->md == nil){
1587 b3994ec5 2003-12-11 devnull fprint(2, "child: can't allocate mntdir: %r\n");
1588 b3994ec5 2003-12-11 devnull threadexits("fsysmount");
1589 b3994ec5 2003-12-11 devnull }
1590 b3994ec5 2003-12-11 devnull sprint(buf, "%d", c->md->id);
1591 b3994ec5 2003-12-11 devnull if((fs = nsmount("acme", buf)) == nil){
1592 b3994ec5 2003-12-11 devnull fprint(2, "child: can't mount acme: %r\n");
1593 b3994ec5 2003-12-11 devnull fsysdelid(c->md);
1594 b3994ec5 2003-12-11 devnull c->md = nil;
1595 b3994ec5 2003-12-11 devnull threadexits("nsmount");
1596 b3994ec5 2003-12-11 devnull }
1597 b3994ec5 2003-12-11 devnull if(winid>0 && (pipechar=='|' || pipechar=='>')){
1598 b3994ec5 2003-12-11 devnull sprint(buf, "%d/rdsel", winid);
1599 b3994ec5 2003-12-11 devnull sfd[0] = fsopenfd(fs, buf, OREAD);
1600 b3994ec5 2003-12-11 devnull }else
1601 b3994ec5 2003-12-11 devnull sfd[0] = open("/dev/null", OREAD);
1602 b3994ec5 2003-12-11 devnull if((winid>0 || iseditcmd) && (pipechar=='|' || pipechar=='<')){
1603 b3994ec5 2003-12-11 devnull if(iseditcmd){
1604 b3994ec5 2003-12-11 devnull if(winid > 0)
1605 b3994ec5 2003-12-11 devnull sprint(buf, "%d/editout", winid);
1606 b3994ec5 2003-12-11 devnull else
1607 b3994ec5 2003-12-11 devnull sprint(buf, "editout");
1608 b3994ec5 2003-12-11 devnull }else
1609 b3994ec5 2003-12-11 devnull sprint(buf, "%d/wrsel", winid);
1610 b3994ec5 2003-12-11 devnull sfd[1] = fsopenfd(fs, buf, OWRITE);
1611 b3994ec5 2003-12-11 devnull sfd[2] = fsopenfd(fs, "cons", OWRITE);
1612 b3994ec5 2003-12-11 devnull }else{
1613 b3994ec5 2003-12-11 devnull sfd[1] = fsopenfd(fs, "cons", OWRITE);
1614 b3994ec5 2003-12-11 devnull sfd[2] = sfd[1];
1615 b3994ec5 2003-12-11 devnull }
1616 b3994ec5 2003-12-11 devnull fsunmount(fs);
1617 b3994ec5 2003-12-11 devnull }else{
1618 b3994ec5 2003-12-11 devnull rfork(RFFDG|RFNOTEG);
1619 b3994ec5 2003-12-11 devnull fsysclose();
1620 b3994ec5 2003-12-11 devnull sfd[0] = open("/dev/null", OREAD);
1621 b3994ec5 2003-12-11 devnull sfd[1] = open("/dev/null", OWRITE);
1622 b3994ec5 2003-12-11 devnull sfd[2] = dup(erroutfd, -1);
1623 b3994ec5 2003-12-11 devnull }
1624 b3994ec5 2003-12-11 devnull if(win)
1625 b3994ec5 2003-12-11 devnull winclose(win);
1626 b3994ec5 2003-12-11 devnull
1627 b3994ec5 2003-12-11 devnull if(argaddr)
1628 b3994ec5 2003-12-11 devnull putenv("acmeaddr", argaddr);
1629 81c2c5e7 2012-10-21 rsc if(acmeshell != nil)
1630 81c2c5e7 2012-10-21 rsc goto Hard;
1631 b3994ec5 2003-12-11 devnull if(strlen(t) > sizeof buf-10) /* may need to print into stack */
1632 b3994ec5 2003-12-11 devnull goto Hard;
1633 b3994ec5 2003-12-11 devnull inarg = FALSE;
1634 b3994ec5 2003-12-11 devnull for(e=t; *e; e+=w){
1635 b3994ec5 2003-12-11 devnull w = chartorune(&r, e);
1636 b3994ec5 2003-12-11 devnull if(r==' ' || r=='\t')
1637 b3994ec5 2003-12-11 devnull continue;
1638 b3994ec5 2003-12-11 devnull if(r < ' ')
1639 b3994ec5 2003-12-11 devnull goto Hard;
1640 fea86f06 2013-09-06 rsc if(utfrune("#;&|^$=`'{}()<>[]*?^~`/", r))
1641 b3994ec5 2003-12-11 devnull goto Hard;
1642 b3994ec5 2003-12-11 devnull inarg = TRUE;
1643 b3994ec5 2003-12-11 devnull }
1644 b3994ec5 2003-12-11 devnull if(!inarg)
1645 b3994ec5 2003-12-11 devnull goto Fail;
1646 b3994ec5 2003-12-11 devnull
1647 b3994ec5 2003-12-11 devnull ac = 0;
1648 b3994ec5 2003-12-11 devnull av = nil;
1649 b3994ec5 2003-12-11 devnull inarg = FALSE;
1650 b3994ec5 2003-12-11 devnull for(e=t; *e; e+=w){
1651 b3994ec5 2003-12-11 devnull w = chartorune(&r, e);
1652 b3994ec5 2003-12-11 devnull if(r==' ' || r=='\t'){
1653 b3994ec5 2003-12-11 devnull inarg = FALSE;
1654 b3994ec5 2003-12-11 devnull *e = 0;
1655 b3994ec5 2003-12-11 devnull continue;
1656 b3994ec5 2003-12-11 devnull }
1657 b3994ec5 2003-12-11 devnull if(!inarg){
1658 b3994ec5 2003-12-11 devnull inarg = TRUE;
1659 b3994ec5 2003-12-11 devnull av = realloc(av, (ac+1)*sizeof(char**));
1660 b3994ec5 2003-12-11 devnull av[ac++] = e;
1661 b3994ec5 2003-12-11 devnull }
1662 b3994ec5 2003-12-11 devnull }
1663 b3994ec5 2003-12-11 devnull av = realloc(av, (ac+2)*sizeof(char**));
1664 b3994ec5 2003-12-11 devnull av[ac++] = arg;
1665 b3994ec5 2003-12-11 devnull av[ac] = nil;
1666 b3994ec5 2003-12-11 devnull c->av = av;
1667 bf27f587 2004-05-15 devnull
1668 9ca6e21f 2012-10-22 rsc dir = nil;
1669 9ca6e21f 2012-10-22 rsc if(rdir != nil)
1670 bf27f587 2004-05-15 devnull dir = runetobyte(rdir, ndir);
1671 9ca6e21f 2012-10-22 rsc ret = threadspawnd(sfd, av[0], av, dir);
1672 9ca6e21f 2012-10-22 rsc free(dir);
1673 bf27f587 2004-05-15 devnull if(ret >= 0){
1674 bf27f587 2004-05-15 devnull if(cpid)
1675 bf27f587 2004-05-15 devnull sendul(cpid, ret);
1676 bf27f587 2004-05-15 devnull threadexits("");
1677 bf27f587 2004-05-15 devnull }
1678 b3994ec5 2003-12-11 devnull /* libthread uses execvp so no need to do this */
1679 b3994ec5 2003-12-11 devnull #if 0
1680 b3994ec5 2003-12-11 devnull e = av[0];
1681 b3994ec5 2003-12-11 devnull if(e[0]=='/' || (e[0]=='.' && e[1]=='/'))
1682 b3994ec5 2003-12-11 devnull goto Fail;
1683 b3994ec5 2003-12-11 devnull if(cputype){
1684 b3994ec5 2003-12-11 devnull sprint(buf, "%s/%s", cputype, av[0]);
1685 b3994ec5 2003-12-11 devnull procexec(cpid, sfd, buf, av);
1686 b3994ec5 2003-12-11 devnull }
1687 b3994ec5 2003-12-11 devnull sprint(buf, "/bin/%s", av[0]);
1688 b3994ec5 2003-12-11 devnull procexec(cpid, sfd, buf, av);
1689 b3994ec5 2003-12-11 devnull #endif
1690 b3994ec5 2003-12-11 devnull goto Fail;
1691 b3994ec5 2003-12-11 devnull
1692 b3994ec5 2003-12-11 devnull Hard:
1693 b3994ec5 2003-12-11 devnull /*
1694 b3994ec5 2003-12-11 devnull * ugly: set path = (. $cputype /bin)
1695 b3994ec5 2003-12-11 devnull * should honor $path if unusual.
1696 b3994ec5 2003-12-11 devnull */
1697 b3994ec5 2003-12-11 devnull if(cputype){
1698 b3994ec5 2003-12-11 devnull n = 0;
1699 b3994ec5 2003-12-11 devnull memmove(buf+n, ".", 2);
1700 b3994ec5 2003-12-11 devnull n += 2;
1701 b3994ec5 2003-12-11 devnull i = strlen(cputype)+1;
1702 b3994ec5 2003-12-11 devnull memmove(buf+n, cputype, i);
1703 b3994ec5 2003-12-11 devnull n += i;
1704 b3994ec5 2003-12-11 devnull memmove(buf+n, "/bin", 5);
1705 b3994ec5 2003-12-11 devnull n += 5;
1706 b3994ec5 2003-12-11 devnull fd = create("/env/path", OWRITE, 0666);
1707 b3994ec5 2003-12-11 devnull write(fd, buf, n);
1708 b3994ec5 2003-12-11 devnull close(fd);
1709 b3994ec5 2003-12-11 devnull }
1710 b3994ec5 2003-12-11 devnull
1711 b3994ec5 2003-12-11 devnull if(arg){
1712 b3994ec5 2003-12-11 devnull news = emalloc(strlen(t) + 1 + 1 + strlen(arg) + 1 + 1);
1713 b3994ec5 2003-12-11 devnull if(news){
1714 b3994ec5 2003-12-11 devnull sprint(news, "%s '%s'", t, arg); /* BUG: what if quote in arg? */
1715 b3994ec5 2003-12-11 devnull free(s);
1716 b3994ec5 2003-12-11 devnull t = news;
1717 b3994ec5 2003-12-11 devnull c->text = news;
1718 b3994ec5 2003-12-11 devnull }
1719 b3994ec5 2003-12-11 devnull }
1720 9ca6e21f 2012-10-22 rsc dir = nil;
1721 9ca6e21f 2012-10-22 rsc if(rdir != nil)
1722 bf27f587 2004-05-15 devnull dir = runetobyte(rdir, ndir);
1723 81c2c5e7 2012-10-21 rsc shell = acmeshell;
1724 81c2c5e7 2012-10-21 rsc if(shell == nil)
1725 81c2c5e7 2012-10-21 rsc shell = "rc";
1726 81c2c5e7 2012-10-21 rsc rcarg[0] = shell;
1727 bf27f587 2004-05-15 devnull rcarg[1] = "-c";
1728 bf27f587 2004-05-15 devnull rcarg[2] = t;
1729 bf27f587 2004-05-15 devnull rcarg[3] = nil;
1730 9ca6e21f 2012-10-22 rsc ret = threadspawnd(sfd, rcarg[0], rcarg, dir);
1731 9ca6e21f 2012-10-22 rsc free(dir);
1732 bf27f587 2004-05-15 devnull if(ret >= 0){
1733 bf27f587 2004-05-15 devnull if(cpid)
1734 bf27f587 2004-05-15 devnull sendul(cpid, ret);
1735 012a8a02 2004-10-22 devnull threadexits(nil);
1736 bf27f587 2004-05-15 devnull }
1737 81c2c5e7 2012-10-21 rsc warning(nil, "exec %s: %r\n", shell);
1738 b3994ec5 2003-12-11 devnull
1739 b3994ec5 2003-12-11 devnull Fail:
1740 5a8e63b2 2004-02-29 devnull /* threadexec hasn't happened, so send a zero */
1741 b3994ec5 2003-12-11 devnull close(sfd[0]);
1742 b3994ec5 2003-12-11 devnull close(sfd[1]);
1743 b3994ec5 2003-12-11 devnull if(sfd[2] != sfd[1])
1744 b3994ec5 2003-12-11 devnull close(sfd[2]);
1745 b3994ec5 2003-12-11 devnull sendul(cpid, 0);
1746 b3994ec5 2003-12-11 devnull threadexits(nil);
1747 b3994ec5 2003-12-11 devnull }
1748 b3994ec5 2003-12-11 devnull
1749 b3994ec5 2003-12-11 devnull void
1750 b3994ec5 2003-12-11 devnull runwaittask(void *v)
1751 b3994ec5 2003-12-11 devnull {
1752 b3994ec5 2003-12-11 devnull Command *c;
1753 b3994ec5 2003-12-11 devnull Channel *cpid;
1754 b3994ec5 2003-12-11 devnull void **a;
1755 b3994ec5 2003-12-11 devnull
1756 b3994ec5 2003-12-11 devnull threadsetname("runwaittask");
1757 b3994ec5 2003-12-11 devnull a = v;
1758 b3994ec5 2003-12-11 devnull c = a[0];
1759 b3994ec5 2003-12-11 devnull cpid = a[1];
1760 b3994ec5 2003-12-11 devnull free(a);
1761 b3994ec5 2003-12-11 devnull do
1762 b3994ec5 2003-12-11 devnull c->pid = recvul(cpid);
1763 b3994ec5 2003-12-11 devnull while(c->pid == ~0);
1764 b3994ec5 2003-12-11 devnull free(c->av);
1765 b3994ec5 2003-12-11 devnull if(c->pid != 0) /* successful exec */
1766 b3994ec5 2003-12-11 devnull sendp(ccommand, c);
1767 b3994ec5 2003-12-11 devnull else{
1768 b3994ec5 2003-12-11 devnull if(c->iseditcmd)
1769 b3994ec5 2003-12-11 devnull sendul(cedit, 0);
1770 b3994ec5 2003-12-11 devnull free(c->name);
1771 b3994ec5 2003-12-11 devnull free(c->text);
1772 b3994ec5 2003-12-11 devnull free(c);
1773 b3994ec5 2003-12-11 devnull }
1774 b3994ec5 2003-12-11 devnull chanfree(cpid);
1775 b3994ec5 2003-12-11 devnull }
1776 b3994ec5 2003-12-11 devnull
1777 b3994ec5 2003-12-11 devnull void
1778 b3994ec5 2003-12-11 devnull run(Window *win, char *s, Rune *rdir, int ndir, int newns, char *argaddr, char *xarg, int iseditcmd)
1779 b3994ec5 2003-12-11 devnull {
1780 b3994ec5 2003-12-11 devnull void **arg;
1781 b3994ec5 2003-12-11 devnull Command *c;
1782 b3994ec5 2003-12-11 devnull Channel *cpid;
1783 b3994ec5 2003-12-11 devnull
1784 b3994ec5 2003-12-11 devnull if(s == nil)
1785 b3994ec5 2003-12-11 devnull return;
1786 b3994ec5 2003-12-11 devnull
1787 b3994ec5 2003-12-11 devnull arg = emalloc(10*sizeof(void*));
1788 b3994ec5 2003-12-11 devnull c = emalloc(sizeof *c);
1789 b3994ec5 2003-12-11 devnull cpid = chancreate(sizeof(ulong), 0);
1790 334cb1e9 2004-12-27 devnull chansetname(cpid, "cpid %s", s);
1791 b3994ec5 2003-12-11 devnull arg[0] = win;
1792 b3994ec5 2003-12-11 devnull arg[1] = s;
1793 b3994ec5 2003-12-11 devnull arg[2] = rdir;
1794 a4bbf47b 2005-12-21 devnull arg[3] = (void*)(uintptr)ndir;
1795 a4bbf47b 2005-12-21 devnull arg[4] = (void*)(uintptr)newns;
1796 b3994ec5 2003-12-11 devnull arg[5] = argaddr;
1797 b3994ec5 2003-12-11 devnull arg[6] = xarg;
1798 b3994ec5 2003-12-11 devnull arg[7] = c;
1799 b3994ec5 2003-12-11 devnull arg[8] = cpid;
1800 a4bbf47b 2005-12-21 devnull arg[9] = (void*)(uintptr)iseditcmd;
1801 5a8e63b2 2004-02-29 devnull threadcreate(runproc, arg, STACK);
1802 b3994ec5 2003-12-11 devnull /* mustn't block here because must be ready to answer mount() call in run() */
1803 b3994ec5 2003-12-11 devnull arg = emalloc(2*sizeof(void*));
1804 b3994ec5 2003-12-11 devnull arg[0] = c;
1805 b3994ec5 2003-12-11 devnull arg[1] = cpid;
1806 b3994ec5 2003-12-11 devnull threadcreate(runwaittask, arg, STACK);
1807 b3994ec5 2003-12-11 devnull }