Blame


1 76193d7c 2003-09-30 devnull #include "sam.h"
2 76193d7c 2003-09-30 devnull
3 76193d7c 2003-09-30 devnull Rune genbuf[BLOCKSIZE];
4 76193d7c 2003-09-30 devnull int io;
5 76193d7c 2003-09-30 devnull int panicking;
6 76193d7c 2003-09-30 devnull int rescuing;
7 76193d7c 2003-09-30 devnull String genstr;
8 76193d7c 2003-09-30 devnull String rhs;
9 76193d7c 2003-09-30 devnull String curwd;
10 76193d7c 2003-09-30 devnull String cmdstr;
11 76193d7c 2003-09-30 devnull Rune empty[] = { 0 };
12 76193d7c 2003-09-30 devnull char *genc;
13 76193d7c 2003-09-30 devnull File *curfile;
14 76193d7c 2003-09-30 devnull File *flist;
15 76193d7c 2003-09-30 devnull File *cmd;
16 76193d7c 2003-09-30 devnull jmp_buf mainloop;
17 76193d7c 2003-09-30 devnull List tempfile;
18 76193d7c 2003-09-30 devnull int quitok = TRUE;
19 76193d7c 2003-09-30 devnull int downloaded;
20 76193d7c 2003-09-30 devnull int dflag;
21 76193d7c 2003-09-30 devnull int Rflag;
22 76193d7c 2003-09-30 devnull char *machine;
23 76193d7c 2003-09-30 devnull char *home;
24 76193d7c 2003-09-30 devnull int bpipeok;
25 76193d7c 2003-09-30 devnull int termlocked;
26 76193d7c 2003-09-30 devnull char *samterm = SAMTERM;
27 76193d7c 2003-09-30 devnull char *rsamname = RSAM;
28 76193d7c 2003-09-30 devnull File *lastfile;
29 76193d7c 2003-09-30 devnull Disk *disk;
30 76193d7c 2003-09-30 devnull long seq;
31 76193d7c 2003-09-30 devnull
32 be36ff68 2004-04-29 devnull char *winsize;
33 be36ff68 2004-04-29 devnull
34 76193d7c 2003-09-30 devnull Rune baddir[] = { '<', 'b', 'a', 'd', 'd', 'i', 'r', '>', '\n'};
35 76193d7c 2003-09-30 devnull
36 76193d7c 2003-09-30 devnull void usage(void);
37 76193d7c 2003-09-30 devnull
38 ffcafb8c 2003-10-11 devnull extern int notify(void(*)(void*,char*));
39 ffcafb8c 2003-10-11 devnull
40 ffcafb8c 2003-10-11 devnull int
41 f7b74c17 2004-12-28 devnull main(int volatile argc, char **volatile argv)
42 76193d7c 2003-09-30 devnull {
43 f7b74c17 2004-12-28 devnull int volatile i;
44 76193d7c 2003-09-30 devnull String *t;
45 76193d7c 2003-09-30 devnull char **ap, **arg;
46 76193d7c 2003-09-30 devnull
47 76193d7c 2003-09-30 devnull arg = argv++;
48 76193d7c 2003-09-30 devnull ap = argv;
49 76193d7c 2003-09-30 devnull while(argc>1 && argv[0] && argv[0][0]=='-'){
50 76193d7c 2003-09-30 devnull switch(argv[0][1]){
51 76193d7c 2003-09-30 devnull case 'd':
52 76193d7c 2003-09-30 devnull dflag++;
53 76193d7c 2003-09-30 devnull break;
54 76193d7c 2003-09-30 devnull
55 76193d7c 2003-09-30 devnull case 'r':
56 76193d7c 2003-09-30 devnull --argc, argv++;
57 76193d7c 2003-09-30 devnull if(argc == 1)
58 76193d7c 2003-09-30 devnull usage();
59 76193d7c 2003-09-30 devnull machine = *argv;
60 76193d7c 2003-09-30 devnull break;
61 76193d7c 2003-09-30 devnull
62 76193d7c 2003-09-30 devnull case 'R':
63 76193d7c 2003-09-30 devnull Rflag++;
64 76193d7c 2003-09-30 devnull break;
65 76193d7c 2003-09-30 devnull
66 76193d7c 2003-09-30 devnull case 't':
67 76193d7c 2003-09-30 devnull --argc, argv++;
68 76193d7c 2003-09-30 devnull if(argc == 1)
69 76193d7c 2003-09-30 devnull usage();
70 76193d7c 2003-09-30 devnull samterm = *argv;
71 76193d7c 2003-09-30 devnull break;
72 76193d7c 2003-09-30 devnull
73 76193d7c 2003-09-30 devnull case 's':
74 76193d7c 2003-09-30 devnull --argc, argv++;
75 76193d7c 2003-09-30 devnull if(argc == 1)
76 76193d7c 2003-09-30 devnull usage();
77 76193d7c 2003-09-30 devnull rsamname = *argv;
78 76193d7c 2003-09-30 devnull break;
79 76193d7c 2003-09-30 devnull
80 76193d7c 2003-09-30 devnull case 'x': /* x11 option - strip the x */
81 76193d7c 2003-09-30 devnull strcpy(*argv+1, *argv+2);
82 76193d7c 2003-09-30 devnull *ap++ = *argv++;
83 76193d7c 2003-09-30 devnull *ap++ = *argv;
84 76193d7c 2003-09-30 devnull argc--;
85 76193d7c 2003-09-30 devnull break;
86 be36ff68 2004-04-29 devnull
87 be36ff68 2004-04-29 devnull case 'W':
88 be36ff68 2004-04-29 devnull --argc, argv++;
89 be36ff68 2004-04-29 devnull break;
90 76193d7c 2003-09-30 devnull
91 76193d7c 2003-09-30 devnull default:
92 76193d7c 2003-09-30 devnull dprint("sam: unknown flag %c\n", argv[0][1]);
93 76193d7c 2003-09-30 devnull exits("usage");
94 76193d7c 2003-09-30 devnull }
95 76193d7c 2003-09-30 devnull --argc, argv++;
96 76193d7c 2003-09-30 devnull }
97 76193d7c 2003-09-30 devnull Strinit(&cmdstr);
98 76193d7c 2003-09-30 devnull Strinit0(&lastpat);
99 76193d7c 2003-09-30 devnull Strinit0(&lastregexp);
100 76193d7c 2003-09-30 devnull Strinit0(&genstr);
101 76193d7c 2003-09-30 devnull Strinit0(&rhs);
102 76193d7c 2003-09-30 devnull Strinit0(&curwd);
103 76193d7c 2003-09-30 devnull tempfile.listptr = emalloc(1); /* so it can be freed later */
104 76193d7c 2003-09-30 devnull Strinit0(&plan9cmd);
105 76193d7c 2003-09-30 devnull home = getenv(HOME);
106 76193d7c 2003-09-30 devnull disk = diskinit();
107 76193d7c 2003-09-30 devnull if(home == 0)
108 76193d7c 2003-09-30 devnull home = "/";
109 76193d7c 2003-09-30 devnull if(!dflag)
110 8538a660 2004-05-14 devnull startup(machine, Rflag, arg, ap, argv);
111 76193d7c 2003-09-30 devnull notify(notifyf);
112 76193d7c 2003-09-30 devnull getcurwd();
113 76193d7c 2003-09-30 devnull if(argc>1){
114 76193d7c 2003-09-30 devnull for(i=0; i<argc-1; i++){
115 76193d7c 2003-09-30 devnull if(!setjmp(mainloop)){
116 76193d7c 2003-09-30 devnull t = tmpcstr(argv[i]);
117 76193d7c 2003-09-30 devnull Straddc(t, '\0');
118 76193d7c 2003-09-30 devnull Strduplstr(&genstr, t);
119 76193d7c 2003-09-30 devnull freetmpstr(t);
120 76193d7c 2003-09-30 devnull fixname(&genstr);
121 76193d7c 2003-09-30 devnull logsetname(newfile(), &genstr);
122 76193d7c 2003-09-30 devnull }
123 76193d7c 2003-09-30 devnull }
124 76193d7c 2003-09-30 devnull }else if(!downloaded)
125 76193d7c 2003-09-30 devnull newfile();
126 76193d7c 2003-09-30 devnull seq++;
127 76193d7c 2003-09-30 devnull if(file.nused)
128 76193d7c 2003-09-30 devnull current(file.filepptr[0]);
129 76193d7c 2003-09-30 devnull setjmp(mainloop);
130 76193d7c 2003-09-30 devnull cmdloop();
131 76193d7c 2003-09-30 devnull trytoquit(); /* if we already q'ed, quitok will be TRUE */
132 76193d7c 2003-09-30 devnull exits(0);
133 ffcafb8c 2003-10-11 devnull return 0;
134 76193d7c 2003-09-30 devnull }
135 76193d7c 2003-09-30 devnull
136 76193d7c 2003-09-30 devnull void
137 76193d7c 2003-09-30 devnull usage(void)
138 76193d7c 2003-09-30 devnull {
139 76193d7c 2003-09-30 devnull dprint("usage: sam [-d] [-t samterm] [-s sam name] -r machine\n");
140 76193d7c 2003-09-30 devnull exits("usage");
141 76193d7c 2003-09-30 devnull }
142 76193d7c 2003-09-30 devnull
143 76193d7c 2003-09-30 devnull void
144 76193d7c 2003-09-30 devnull rescue(void)
145 76193d7c 2003-09-30 devnull {
146 76193d7c 2003-09-30 devnull int i, nblank = 0;
147 76193d7c 2003-09-30 devnull File *f;
148 76193d7c 2003-09-30 devnull char *c;
149 76193d7c 2003-09-30 devnull char buf[256];
150 f7012583 2003-11-25 devnull char *root;
151 76193d7c 2003-09-30 devnull
152 76193d7c 2003-09-30 devnull if(rescuing++)
153 76193d7c 2003-09-30 devnull return;
154 76193d7c 2003-09-30 devnull io = -1;
155 76193d7c 2003-09-30 devnull for(i=0; i<file.nused; i++){
156 76193d7c 2003-09-30 devnull f = file.filepptr[i];
157 522b0689 2003-09-30 devnull if(f==cmd || f->b.nc==0 || !fileisdirty(f))
158 76193d7c 2003-09-30 devnull continue;
159 76193d7c 2003-09-30 devnull if(io == -1){
160 76193d7c 2003-09-30 devnull sprint(buf, "%s/sam.save", home);
161 76193d7c 2003-09-30 devnull io = create(buf, 1, 0777);
162 76193d7c 2003-09-30 devnull if(io<0)
163 76193d7c 2003-09-30 devnull return;
164 76193d7c 2003-09-30 devnull }
165 76193d7c 2003-09-30 devnull if(f->name.s[0]){
166 76193d7c 2003-09-30 devnull c = Strtoc(&f->name);
167 76193d7c 2003-09-30 devnull strncpy(buf, c, sizeof buf-1);
168 76193d7c 2003-09-30 devnull buf[sizeof buf-1] = 0;
169 76193d7c 2003-09-30 devnull free(c);
170 76193d7c 2003-09-30 devnull }else
171 76193d7c 2003-09-30 devnull sprint(buf, "nameless.%d", nblank++);
172 f7012583 2003-11-25 devnull root = getenv("PLAN9");
173 f7012583 2003-11-25 devnull if(root == nil)
174 f7012583 2003-11-25 devnull root = "/usr/local/plan9";
175 f7012583 2003-11-25 devnull fprint(io, "#!/bin/sh\n%s/bin/samsave '%s' $* <<'---%s'\n", root, buf, buf);
176 522b0689 2003-09-30 devnull addr.r.p1 = 0, addr.r.p2 = f->b.nc;
177 76193d7c 2003-09-30 devnull writeio(f);
178 76193d7c 2003-09-30 devnull fprint(io, "\n---%s\n", (char *)buf);
179 76193d7c 2003-09-30 devnull }
180 76193d7c 2003-09-30 devnull }
181 76193d7c 2003-09-30 devnull
182 76193d7c 2003-09-30 devnull void
183 76193d7c 2003-09-30 devnull panic(char *s)
184 76193d7c 2003-09-30 devnull {
185 76193d7c 2003-09-30 devnull int wasd;
186 76193d7c 2003-09-30 devnull
187 76193d7c 2003-09-30 devnull if(!panicking++ && !setjmp(mainloop)){
188 76193d7c 2003-09-30 devnull wasd = downloaded;
189 76193d7c 2003-09-30 devnull downloaded = 0;
190 76193d7c 2003-09-30 devnull dprint("sam: panic: %s: %r\n", s);
191 76193d7c 2003-09-30 devnull if(wasd)
192 76193d7c 2003-09-30 devnull fprint(2, "sam: panic: %s: %r\n", s);
193 76193d7c 2003-09-30 devnull rescue();
194 76193d7c 2003-09-30 devnull abort();
195 76193d7c 2003-09-30 devnull }
196 76193d7c 2003-09-30 devnull }
197 76193d7c 2003-09-30 devnull
198 76193d7c 2003-09-30 devnull void
199 76193d7c 2003-09-30 devnull hiccough(char *s)
200 76193d7c 2003-09-30 devnull {
201 76193d7c 2003-09-30 devnull File *f;
202 76193d7c 2003-09-30 devnull int i;
203 76193d7c 2003-09-30 devnull
204 76193d7c 2003-09-30 devnull if(rescuing)
205 76193d7c 2003-09-30 devnull exits("rescue");
206 76193d7c 2003-09-30 devnull if(s)
207 76193d7c 2003-09-30 devnull dprint("%s\n", s);
208 76193d7c 2003-09-30 devnull resetcmd();
209 76193d7c 2003-09-30 devnull resetxec();
210 76193d7c 2003-09-30 devnull resetsys();
211 76193d7c 2003-09-30 devnull if(io > 0)
212 76193d7c 2003-09-30 devnull close(io);
213 76193d7c 2003-09-30 devnull
214 76193d7c 2003-09-30 devnull /*
215 76193d7c 2003-09-30 devnull * back out any logged changes & restore old sequences
216 76193d7c 2003-09-30 devnull */
217 76193d7c 2003-09-30 devnull for(i=0; i<file.nused; i++){
218 76193d7c 2003-09-30 devnull f = file.filepptr[i];
219 76193d7c 2003-09-30 devnull if(f==cmd)
220 76193d7c 2003-09-30 devnull continue;
221 76193d7c 2003-09-30 devnull if(f->seq==seq){
222 76193d7c 2003-09-30 devnull bufdelete(&f->epsilon, 0, f->epsilon.nc);
223 76193d7c 2003-09-30 devnull f->seq = f->prevseq;
224 76193d7c 2003-09-30 devnull f->dot.r = f->prevdot;
225 76193d7c 2003-09-30 devnull f->mark = f->prevmark;
226 76193d7c 2003-09-30 devnull state(f, f->prevmod ? Dirty: Clean);
227 76193d7c 2003-09-30 devnull }
228 76193d7c 2003-09-30 devnull }
229 76193d7c 2003-09-30 devnull
230 76193d7c 2003-09-30 devnull update();
231 76193d7c 2003-09-30 devnull if (curfile) {
232 76193d7c 2003-09-30 devnull if (curfile->unread)
233 76193d7c 2003-09-30 devnull curfile->unread = FALSE;
234 76193d7c 2003-09-30 devnull else if (downloaded)
235 76193d7c 2003-09-30 devnull outTs(Hcurrent, curfile->tag);
236 76193d7c 2003-09-30 devnull }
237 76193d7c 2003-09-30 devnull longjmp(mainloop, 1);
238 76193d7c 2003-09-30 devnull }
239 76193d7c 2003-09-30 devnull
240 76193d7c 2003-09-30 devnull void
241 76193d7c 2003-09-30 devnull intr(void)
242 76193d7c 2003-09-30 devnull {
243 76193d7c 2003-09-30 devnull error(Eintr);
244 76193d7c 2003-09-30 devnull }
245 76193d7c 2003-09-30 devnull
246 76193d7c 2003-09-30 devnull void
247 76193d7c 2003-09-30 devnull trytoclose(File *f)
248 76193d7c 2003-09-30 devnull {
249 76193d7c 2003-09-30 devnull char *t;
250 76193d7c 2003-09-30 devnull char buf[256];
251 76193d7c 2003-09-30 devnull
252 76193d7c 2003-09-30 devnull if(f == cmd) /* possible? */
253 76193d7c 2003-09-30 devnull return;
254 76193d7c 2003-09-30 devnull if(f->deleted)
255 76193d7c 2003-09-30 devnull return;
256 76193d7c 2003-09-30 devnull if(fileisdirty(f) && !f->closeok){
257 76193d7c 2003-09-30 devnull f->closeok = TRUE;
258 76193d7c 2003-09-30 devnull if(f->name.s[0]){
259 76193d7c 2003-09-30 devnull t = Strtoc(&f->name);
260 76193d7c 2003-09-30 devnull strncpy(buf, t, sizeof buf-1);
261 76193d7c 2003-09-30 devnull free(t);
262 76193d7c 2003-09-30 devnull }else
263 76193d7c 2003-09-30 devnull strcpy(buf, "nameless file");
264 76193d7c 2003-09-30 devnull error_s(Emodified, buf);
265 76193d7c 2003-09-30 devnull }
266 76193d7c 2003-09-30 devnull f->deleted = TRUE;
267 76193d7c 2003-09-30 devnull }
268 76193d7c 2003-09-30 devnull
269 76193d7c 2003-09-30 devnull void
270 76193d7c 2003-09-30 devnull trytoquit(void)
271 76193d7c 2003-09-30 devnull {
272 76193d7c 2003-09-30 devnull int c;
273 76193d7c 2003-09-30 devnull File *f;
274 76193d7c 2003-09-30 devnull
275 76193d7c 2003-09-30 devnull if(!quitok){
276 76193d7c 2003-09-30 devnull for(c = 0; c<file.nused; c++){
277 76193d7c 2003-09-30 devnull f = file.filepptr[c];
278 76193d7c 2003-09-30 devnull if(f!=cmd && fileisdirty(f)){
279 76193d7c 2003-09-30 devnull quitok = TRUE;
280 76193d7c 2003-09-30 devnull eof = FALSE;
281 76193d7c 2003-09-30 devnull error(Echanges);
282 76193d7c 2003-09-30 devnull }
283 76193d7c 2003-09-30 devnull }
284 76193d7c 2003-09-30 devnull }
285 76193d7c 2003-09-30 devnull }
286 76193d7c 2003-09-30 devnull
287 76193d7c 2003-09-30 devnull void
288 76193d7c 2003-09-30 devnull load(File *f)
289 76193d7c 2003-09-30 devnull {
290 76193d7c 2003-09-30 devnull Address saveaddr;
291 76193d7c 2003-09-30 devnull
292 76193d7c 2003-09-30 devnull Strduplstr(&genstr, &f->name);
293 76193d7c 2003-09-30 devnull filename(f);
294 76193d7c 2003-09-30 devnull if(f->name.s[0]){
295 76193d7c 2003-09-30 devnull saveaddr = addr;
296 76193d7c 2003-09-30 devnull edit(f, 'I');
297 76193d7c 2003-09-30 devnull addr = saveaddr;
298 76193d7c 2003-09-30 devnull }else{
299 76193d7c 2003-09-30 devnull f->unread = 0;
300 76193d7c 2003-09-30 devnull f->cleanseq = f->seq;
301 76193d7c 2003-09-30 devnull }
302 76193d7c 2003-09-30 devnull
303 76193d7c 2003-09-30 devnull fileupdate(f, TRUE, TRUE);
304 76193d7c 2003-09-30 devnull }
305 76193d7c 2003-09-30 devnull
306 76193d7c 2003-09-30 devnull void
307 76193d7c 2003-09-30 devnull cmdupdate(void)
308 76193d7c 2003-09-30 devnull {
309 76193d7c 2003-09-30 devnull if(cmd && cmd->seq!=0){
310 76193d7c 2003-09-30 devnull fileupdate(cmd, FALSE, downloaded);
311 522b0689 2003-09-30 devnull cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->b.nc;
312 76193d7c 2003-09-30 devnull telldot(cmd);
313 76193d7c 2003-09-30 devnull }
314 76193d7c 2003-09-30 devnull }
315 76193d7c 2003-09-30 devnull
316 76193d7c 2003-09-30 devnull void
317 76193d7c 2003-09-30 devnull delete(File *f)
318 76193d7c 2003-09-30 devnull {
319 76193d7c 2003-09-30 devnull if(downloaded && f->rasp)
320 76193d7c 2003-09-30 devnull outTs(Hclose, f->tag);
321 76193d7c 2003-09-30 devnull delfile(f);
322 76193d7c 2003-09-30 devnull if(f == curfile)
323 76193d7c 2003-09-30 devnull current(0);
324 76193d7c 2003-09-30 devnull }
325 76193d7c 2003-09-30 devnull
326 76193d7c 2003-09-30 devnull void
327 76193d7c 2003-09-30 devnull update(void)
328 76193d7c 2003-09-30 devnull {
329 76193d7c 2003-09-30 devnull int i, anymod;
330 76193d7c 2003-09-30 devnull File *f;
331 76193d7c 2003-09-30 devnull
332 76193d7c 2003-09-30 devnull settempfile();
333 76193d7c 2003-09-30 devnull for(anymod = i=0; i<tempfile.nused; i++){
334 76193d7c 2003-09-30 devnull f = tempfile.filepptr[i];
335 76193d7c 2003-09-30 devnull if(f==cmd) /* cmd gets done in main() */
336 76193d7c 2003-09-30 devnull continue;
337 76193d7c 2003-09-30 devnull if(f->deleted) {
338 76193d7c 2003-09-30 devnull delete(f);
339 76193d7c 2003-09-30 devnull continue;
340 76193d7c 2003-09-30 devnull }
341 76193d7c 2003-09-30 devnull if(f->seq==seq && fileupdate(f, FALSE, downloaded))
342 76193d7c 2003-09-30 devnull anymod++;
343 76193d7c 2003-09-30 devnull if(f->rasp)
344 76193d7c 2003-09-30 devnull telldot(f);
345 76193d7c 2003-09-30 devnull }
346 76193d7c 2003-09-30 devnull if(anymod)
347 76193d7c 2003-09-30 devnull seq++;
348 76193d7c 2003-09-30 devnull }
349 76193d7c 2003-09-30 devnull
350 76193d7c 2003-09-30 devnull File *
351 76193d7c 2003-09-30 devnull current(File *f)
352 76193d7c 2003-09-30 devnull {
353 76193d7c 2003-09-30 devnull return curfile = f;
354 76193d7c 2003-09-30 devnull }
355 76193d7c 2003-09-30 devnull
356 76193d7c 2003-09-30 devnull void
357 76193d7c 2003-09-30 devnull edit(File *f, int cmd)
358 76193d7c 2003-09-30 devnull {
359 76193d7c 2003-09-30 devnull int empty = TRUE;
360 76193d7c 2003-09-30 devnull Posn p;
361 76193d7c 2003-09-30 devnull int nulls;
362 76193d7c 2003-09-30 devnull
363 76193d7c 2003-09-30 devnull if(cmd == 'r')
364 76193d7c 2003-09-30 devnull logdelete(f, addr.r.p1, addr.r.p2);
365 76193d7c 2003-09-30 devnull if(cmd=='e' || cmd=='I'){
366 522b0689 2003-09-30 devnull logdelete(f, (Posn)0, f->b.nc);
367 522b0689 2003-09-30 devnull addr.r.p2 = f->b.nc;
368 522b0689 2003-09-30 devnull }else if(f->b.nc!=0 || (f->name.s[0] && Strcmp(&genstr, &f->name)!=0))
369 76193d7c 2003-09-30 devnull empty = FALSE;
370 76193d7c 2003-09-30 devnull if((io = open(genc, OREAD))<0) {
371 76193d7c 2003-09-30 devnull if (curfile && curfile->unread)
372 76193d7c 2003-09-30 devnull curfile->unread = FALSE;
373 76193d7c 2003-09-30 devnull error_r(Eopen, genc);
374 76193d7c 2003-09-30 devnull }
375 76193d7c 2003-09-30 devnull p = readio(f, &nulls, empty, TRUE);
376 76193d7c 2003-09-30 devnull closeio((cmd=='e' || cmd=='I')? -1 : p);
377 76193d7c 2003-09-30 devnull if(cmd == 'r')
378 76193d7c 2003-09-30 devnull f->ndot.r.p1 = addr.r.p2, f->ndot.r.p2 = addr.r.p2+p;
379 76193d7c 2003-09-30 devnull else
380 76193d7c 2003-09-30 devnull f->ndot.r.p1 = f->ndot.r.p2 = 0;
381 76193d7c 2003-09-30 devnull f->closeok = empty;
382 76193d7c 2003-09-30 devnull if (quitok)
383 76193d7c 2003-09-30 devnull quitok = empty;
384 76193d7c 2003-09-30 devnull else
385 76193d7c 2003-09-30 devnull quitok = FALSE;
386 76193d7c 2003-09-30 devnull state(f, empty && !nulls? Clean : Dirty);
387 76193d7c 2003-09-30 devnull if(empty && !nulls)
388 76193d7c 2003-09-30 devnull f->cleanseq = f->seq;
389 76193d7c 2003-09-30 devnull if(cmd == 'e')
390 76193d7c 2003-09-30 devnull filename(f);
391 76193d7c 2003-09-30 devnull }
392 76193d7c 2003-09-30 devnull
393 76193d7c 2003-09-30 devnull int
394 76193d7c 2003-09-30 devnull getname(File *f, String *s, int save)
395 76193d7c 2003-09-30 devnull {
396 76193d7c 2003-09-30 devnull int c, i;
397 76193d7c 2003-09-30 devnull
398 76193d7c 2003-09-30 devnull Strzero(&genstr);
399 76193d7c 2003-09-30 devnull if(genc){
400 76193d7c 2003-09-30 devnull free(genc);
401 76193d7c 2003-09-30 devnull genc = 0;
402 76193d7c 2003-09-30 devnull }
403 76193d7c 2003-09-30 devnull if(s==0 || (c = s->s[0])==0){ /* no name provided */
404 76193d7c 2003-09-30 devnull if(f)
405 76193d7c 2003-09-30 devnull Strduplstr(&genstr, &f->name);
406 76193d7c 2003-09-30 devnull goto Return;
407 76193d7c 2003-09-30 devnull }
408 76193d7c 2003-09-30 devnull if(c!=' ' && c!='\t')
409 76193d7c 2003-09-30 devnull error(Eblank);
410 76193d7c 2003-09-30 devnull for(i=0; (c=s->s[i])==' ' || c=='\t'; i++)
411 76193d7c 2003-09-30 devnull ;
412 76193d7c 2003-09-30 devnull while(s->s[i] > ' ')
413 76193d7c 2003-09-30 devnull Straddc(&genstr, s->s[i++]);
414 76193d7c 2003-09-30 devnull if(s->s[i])
415 76193d7c 2003-09-30 devnull error(Enewline);
416 76193d7c 2003-09-30 devnull fixname(&genstr);
417 76193d7c 2003-09-30 devnull if(f && (save || f->name.s[0]==0)){
418 76193d7c 2003-09-30 devnull logsetname(f, &genstr);
419 76193d7c 2003-09-30 devnull if(Strcmp(&f->name, &genstr)){
420 76193d7c 2003-09-30 devnull quitok = f->closeok = FALSE;
421 76193d7c 2003-09-30 devnull f->qidpath = 0;
422 76193d7c 2003-09-30 devnull f->mtime = 0;
423 76193d7c 2003-09-30 devnull state(f, Dirty); /* if it's 'e', fix later */
424 76193d7c 2003-09-30 devnull }
425 76193d7c 2003-09-30 devnull }
426 76193d7c 2003-09-30 devnull Return:
427 76193d7c 2003-09-30 devnull genc = Strtoc(&genstr);
428 76193d7c 2003-09-30 devnull i = genstr.n;
429 76193d7c 2003-09-30 devnull if(i && genstr.s[i-1]==0)
430 76193d7c 2003-09-30 devnull i--;
431 76193d7c 2003-09-30 devnull return i; /* strlen(name) */
432 76193d7c 2003-09-30 devnull }
433 76193d7c 2003-09-30 devnull
434 76193d7c 2003-09-30 devnull void
435 76193d7c 2003-09-30 devnull filename(File *f)
436 76193d7c 2003-09-30 devnull {
437 76193d7c 2003-09-30 devnull if(genc)
438 76193d7c 2003-09-30 devnull free(genc);
439 76193d7c 2003-09-30 devnull genc = Strtoc(&genstr);
440 76193d7c 2003-09-30 devnull dprint("%c%c%c %s\n", " '"[f->mod],
441 76193d7c 2003-09-30 devnull "-+"[f->rasp!=0], " ."[f==curfile], genc);
442 76193d7c 2003-09-30 devnull }
443 76193d7c 2003-09-30 devnull
444 76193d7c 2003-09-30 devnull void
445 76193d7c 2003-09-30 devnull undostep(File *f, int isundo)
446 76193d7c 2003-09-30 devnull {
447 76193d7c 2003-09-30 devnull uint p1, p2;
448 76193d7c 2003-09-30 devnull int mod;
449 76193d7c 2003-09-30 devnull
450 76193d7c 2003-09-30 devnull mod = f->mod;
451 76193d7c 2003-09-30 devnull fileundo(f, isundo, 1, &p1, &p2, TRUE);
452 76193d7c 2003-09-30 devnull f->ndot = f->dot;
453 76193d7c 2003-09-30 devnull if(f->mod){
454 76193d7c 2003-09-30 devnull f->closeok = 0;
455 76193d7c 2003-09-30 devnull quitok = 0;
456 76193d7c 2003-09-30 devnull }else
457 76193d7c 2003-09-30 devnull f->closeok = 1;
458 76193d7c 2003-09-30 devnull
459 76193d7c 2003-09-30 devnull if(f->mod != mod){
460 76193d7c 2003-09-30 devnull f->mod = mod;
461 76193d7c 2003-09-30 devnull if(mod)
462 76193d7c 2003-09-30 devnull mod = Clean;
463 76193d7c 2003-09-30 devnull else
464 76193d7c 2003-09-30 devnull mod = Dirty;
465 76193d7c 2003-09-30 devnull state(f, mod);
466 76193d7c 2003-09-30 devnull }
467 76193d7c 2003-09-30 devnull }
468 76193d7c 2003-09-30 devnull
469 76193d7c 2003-09-30 devnull int
470 76193d7c 2003-09-30 devnull undo(int isundo)
471 76193d7c 2003-09-30 devnull {
472 76193d7c 2003-09-30 devnull File *f;
473 76193d7c 2003-09-30 devnull int i;
474 76193d7c 2003-09-30 devnull Mod max;
475 76193d7c 2003-09-30 devnull
476 76193d7c 2003-09-30 devnull max = undoseq(curfile, isundo);
477 76193d7c 2003-09-30 devnull if(max == 0)
478 76193d7c 2003-09-30 devnull return 0;
479 76193d7c 2003-09-30 devnull settempfile();
480 76193d7c 2003-09-30 devnull for(i = 0; i<tempfile.nused; i++){
481 76193d7c 2003-09-30 devnull f = tempfile.filepptr[i];
482 76193d7c 2003-09-30 devnull if(f!=cmd && undoseq(f, isundo)==max)
483 76193d7c 2003-09-30 devnull undostep(f, isundo);
484 76193d7c 2003-09-30 devnull }
485 76193d7c 2003-09-30 devnull return 1;
486 76193d7c 2003-09-30 devnull }
487 76193d7c 2003-09-30 devnull
488 76193d7c 2003-09-30 devnull int
489 76193d7c 2003-09-30 devnull readcmd(String *s)
490 76193d7c 2003-09-30 devnull {
491 76193d7c 2003-09-30 devnull int retcode;
492 76193d7c 2003-09-30 devnull
493 76193d7c 2003-09-30 devnull if(flist != 0)
494 76193d7c 2003-09-30 devnull fileclose(flist);
495 76193d7c 2003-09-30 devnull flist = fileopen();
496 76193d7c 2003-09-30 devnull
497 522b0689 2003-09-30 devnull addr.r.p1 = 0, addr.r.p2 = flist->b.nc;
498 76193d7c 2003-09-30 devnull retcode = plan9(flist, '<', s, FALSE);
499 76193d7c 2003-09-30 devnull fileupdate(flist, FALSE, FALSE);
500 76193d7c 2003-09-30 devnull flist->seq = 0;
501 522b0689 2003-09-30 devnull if (flist->b.nc > BLOCKSIZE)
502 76193d7c 2003-09-30 devnull error(Etoolong);
503 76193d7c 2003-09-30 devnull Strzero(&genstr);
504 522b0689 2003-09-30 devnull Strinsure(&genstr, flist->b.nc);
505 522b0689 2003-09-30 devnull bufread(&flist->b, (Posn)0, genbuf, flist->b.nc);
506 522b0689 2003-09-30 devnull memmove(genstr.s, genbuf, flist->b.nc*RUNESIZE);
507 522b0689 2003-09-30 devnull genstr.n = flist->b.nc;
508 76193d7c 2003-09-30 devnull Straddc(&genstr, '\0');
509 76193d7c 2003-09-30 devnull return retcode;
510 76193d7c 2003-09-30 devnull }
511 76193d7c 2003-09-30 devnull
512 76193d7c 2003-09-30 devnull void
513 76193d7c 2003-09-30 devnull getcurwd(void)
514 76193d7c 2003-09-30 devnull {
515 76193d7c 2003-09-30 devnull String *t;
516 76193d7c 2003-09-30 devnull char buf[256];
517 76193d7c 2003-09-30 devnull
518 76193d7c 2003-09-30 devnull buf[0] = 0;
519 76193d7c 2003-09-30 devnull getwd(buf, sizeof(buf));
520 76193d7c 2003-09-30 devnull t = tmpcstr(buf);
521 76193d7c 2003-09-30 devnull Strduplstr(&curwd, t);
522 76193d7c 2003-09-30 devnull freetmpstr(t);
523 76193d7c 2003-09-30 devnull if(curwd.n == 0)
524 76193d7c 2003-09-30 devnull warn(Wpwd);
525 76193d7c 2003-09-30 devnull else if(curwd.s[curwd.n-1] != '/')
526 76193d7c 2003-09-30 devnull Straddc(&curwd, '/');
527 76193d7c 2003-09-30 devnull }
528 76193d7c 2003-09-30 devnull
529 76193d7c 2003-09-30 devnull void
530 76193d7c 2003-09-30 devnull cd(String *str)
531 76193d7c 2003-09-30 devnull {
532 76193d7c 2003-09-30 devnull int i, fd;
533 76193d7c 2003-09-30 devnull char *s;
534 76193d7c 2003-09-30 devnull File *f;
535 76193d7c 2003-09-30 devnull String owd;
536 76193d7c 2003-09-30 devnull
537 76193d7c 2003-09-30 devnull getcurwd();
538 76193d7c 2003-09-30 devnull if(getname((File *)0, str, FALSE))
539 76193d7c 2003-09-30 devnull s = genc;
540 76193d7c 2003-09-30 devnull else
541 76193d7c 2003-09-30 devnull s = home;
542 76193d7c 2003-09-30 devnull if(chdir(s))
543 76193d7c 2003-09-30 devnull syserror("chdir");
544 76193d7c 2003-09-30 devnull fd = open("/dev/wdir", OWRITE);
545 76193d7c 2003-09-30 devnull if(fd > 0)
546 76193d7c 2003-09-30 devnull write(fd, s, strlen(s));
547 76193d7c 2003-09-30 devnull dprint("!\n");
548 76193d7c 2003-09-30 devnull Strinit(&owd);
549 76193d7c 2003-09-30 devnull Strduplstr(&owd, &curwd);
550 76193d7c 2003-09-30 devnull getcurwd();
551 76193d7c 2003-09-30 devnull settempfile();
552 76193d7c 2003-09-30 devnull for(i=0; i<tempfile.nused; i++){
553 76193d7c 2003-09-30 devnull f = tempfile.filepptr[i];
554 76193d7c 2003-09-30 devnull if(f!=cmd && f->name.s[0]!='/' && f->name.s[0]!=0){
555 76193d7c 2003-09-30 devnull Strinsert(&f->name, &owd, (Posn)0);
556 76193d7c 2003-09-30 devnull fixname(&f->name);
557 76193d7c 2003-09-30 devnull sortname(f);
558 76193d7c 2003-09-30 devnull }else if(f != cmd && Strispre(&curwd, &f->name)){
559 76193d7c 2003-09-30 devnull fixname(&f->name);
560 76193d7c 2003-09-30 devnull sortname(f);
561 76193d7c 2003-09-30 devnull }
562 76193d7c 2003-09-30 devnull }
563 76193d7c 2003-09-30 devnull Strclose(&owd);
564 76193d7c 2003-09-30 devnull }
565 76193d7c 2003-09-30 devnull
566 76193d7c 2003-09-30 devnull int
567 76193d7c 2003-09-30 devnull loadflist(String *s)
568 76193d7c 2003-09-30 devnull {
569 76193d7c 2003-09-30 devnull int c, i;
570 76193d7c 2003-09-30 devnull
571 76193d7c 2003-09-30 devnull c = s->s[0];
572 76193d7c 2003-09-30 devnull for(i = 0; s->s[i]==' ' || s->s[i]=='\t'; i++)
573 76193d7c 2003-09-30 devnull ;
574 76193d7c 2003-09-30 devnull if((c==' ' || c=='\t') && s->s[i]!='\n'){
575 76193d7c 2003-09-30 devnull if(s->s[i]=='<'){
576 76193d7c 2003-09-30 devnull Strdelete(s, 0L, (long)i+1);
577 76193d7c 2003-09-30 devnull readcmd(s);
578 76193d7c 2003-09-30 devnull }else{
579 76193d7c 2003-09-30 devnull Strzero(&genstr);
580 76193d7c 2003-09-30 devnull while((c = s->s[i++]) && c!='\n')
581 76193d7c 2003-09-30 devnull Straddc(&genstr, c);
582 76193d7c 2003-09-30 devnull Straddc(&genstr, '\0');
583 76193d7c 2003-09-30 devnull }
584 76193d7c 2003-09-30 devnull }else{
585 76193d7c 2003-09-30 devnull if(c != '\n')
586 76193d7c 2003-09-30 devnull error(Eblank);
587 76193d7c 2003-09-30 devnull Strdupl(&genstr, empty);
588 76193d7c 2003-09-30 devnull }
589 76193d7c 2003-09-30 devnull if(genc)
590 76193d7c 2003-09-30 devnull free(genc);
591 76193d7c 2003-09-30 devnull genc = Strtoc(&genstr);
592 76193d7c 2003-09-30 devnull return genstr.s[0];
593 76193d7c 2003-09-30 devnull }
594 76193d7c 2003-09-30 devnull
595 76193d7c 2003-09-30 devnull File *
596 76193d7c 2003-09-30 devnull readflist(int readall, int delete)
597 76193d7c 2003-09-30 devnull {
598 76193d7c 2003-09-30 devnull Posn i;
599 76193d7c 2003-09-30 devnull int c;
600 76193d7c 2003-09-30 devnull File *f;
601 76193d7c 2003-09-30 devnull String t;
602 76193d7c 2003-09-30 devnull
603 76193d7c 2003-09-30 devnull Strinit(&t);
604 76193d7c 2003-09-30 devnull for(i=0,f=0; f==0 || readall || delete; i++){ /* ++ skips blank */
605 76193d7c 2003-09-30 devnull Strdelete(&genstr, (Posn)0, i);
606 76193d7c 2003-09-30 devnull for(i=0; (c = genstr.s[i])==' ' || c=='\t' || c=='\n'; i++)
607 76193d7c 2003-09-30 devnull ;
608 76193d7c 2003-09-30 devnull if(i >= genstr.n)
609 76193d7c 2003-09-30 devnull break;
610 76193d7c 2003-09-30 devnull Strdelete(&genstr, (Posn)0, i);
611 76193d7c 2003-09-30 devnull for(i=0; (c=genstr.s[i]) && c!=' ' && c!='\t' && c!='\n'; i++)
612 76193d7c 2003-09-30 devnull ;
613 76193d7c 2003-09-30 devnull
614 76193d7c 2003-09-30 devnull if(i == 0)
615 76193d7c 2003-09-30 devnull break;
616 76193d7c 2003-09-30 devnull genstr.s[i] = 0;
617 76193d7c 2003-09-30 devnull Strduplstr(&t, tmprstr(genstr.s, i+1));
618 76193d7c 2003-09-30 devnull fixname(&t);
619 76193d7c 2003-09-30 devnull f = lookfile(&t);
620 76193d7c 2003-09-30 devnull if(delete){
621 76193d7c 2003-09-30 devnull if(f == 0)
622 76193d7c 2003-09-30 devnull warn_S(Wfile, &t);
623 76193d7c 2003-09-30 devnull else
624 76193d7c 2003-09-30 devnull trytoclose(f);
625 76193d7c 2003-09-30 devnull }else if(f==0 && readall)
626 76193d7c 2003-09-30 devnull logsetname(f = newfile(), &t);
627 76193d7c 2003-09-30 devnull }
628 76193d7c 2003-09-30 devnull Strclose(&t);
629 76193d7c 2003-09-30 devnull return f;
630 76193d7c 2003-09-30 devnull }
631 76193d7c 2003-09-30 devnull
632 76193d7c 2003-09-30 devnull File *
633 76193d7c 2003-09-30 devnull tofile(String *s)
634 76193d7c 2003-09-30 devnull {
635 76193d7c 2003-09-30 devnull File *f;
636 76193d7c 2003-09-30 devnull
637 76193d7c 2003-09-30 devnull if(s->s[0] != ' ')
638 76193d7c 2003-09-30 devnull error(Eblank);
639 76193d7c 2003-09-30 devnull if(loadflist(s) == 0){
640 76193d7c 2003-09-30 devnull f = lookfile(&genstr); /* empty string ==> nameless file */
641 76193d7c 2003-09-30 devnull if(f == 0)
642 76193d7c 2003-09-30 devnull error_s(Emenu, genc);
643 76193d7c 2003-09-30 devnull }else if((f=readflist(FALSE, FALSE)) == 0)
644 76193d7c 2003-09-30 devnull error_s(Emenu, genc);
645 76193d7c 2003-09-30 devnull return current(f);
646 76193d7c 2003-09-30 devnull }
647 76193d7c 2003-09-30 devnull
648 76193d7c 2003-09-30 devnull File *
649 76193d7c 2003-09-30 devnull getfile(String *s)
650 76193d7c 2003-09-30 devnull {
651 76193d7c 2003-09-30 devnull File *f;
652 76193d7c 2003-09-30 devnull
653 76193d7c 2003-09-30 devnull if(loadflist(s) == 0)
654 76193d7c 2003-09-30 devnull logsetname(f = newfile(), &genstr);
655 76193d7c 2003-09-30 devnull else if((f=readflist(TRUE, FALSE)) == 0)
656 76193d7c 2003-09-30 devnull error(Eblank);
657 76193d7c 2003-09-30 devnull return current(f);
658 76193d7c 2003-09-30 devnull }
659 76193d7c 2003-09-30 devnull
660 76193d7c 2003-09-30 devnull void
661 76193d7c 2003-09-30 devnull closefiles(File *f, String *s)
662 76193d7c 2003-09-30 devnull {
663 76193d7c 2003-09-30 devnull if(s->s[0] == 0){
664 76193d7c 2003-09-30 devnull if(f == 0)
665 76193d7c 2003-09-30 devnull error(Enofile);
666 76193d7c 2003-09-30 devnull trytoclose(f);
667 76193d7c 2003-09-30 devnull return;
668 76193d7c 2003-09-30 devnull }
669 76193d7c 2003-09-30 devnull if(s->s[0] != ' ')
670 76193d7c 2003-09-30 devnull error(Eblank);
671 76193d7c 2003-09-30 devnull if(loadflist(s) == 0)
672 76193d7c 2003-09-30 devnull error(Enewline);
673 76193d7c 2003-09-30 devnull readflist(FALSE, TRUE);
674 76193d7c 2003-09-30 devnull }
675 76193d7c 2003-09-30 devnull
676 76193d7c 2003-09-30 devnull void
677 76193d7c 2003-09-30 devnull copy(File *f, Address addr2)
678 76193d7c 2003-09-30 devnull {
679 76193d7c 2003-09-30 devnull Posn p;
680 76193d7c 2003-09-30 devnull int ni;
681 76193d7c 2003-09-30 devnull for(p=addr.r.p1; p<addr.r.p2; p+=ni){
682 76193d7c 2003-09-30 devnull ni = addr.r.p2-p;
683 76193d7c 2003-09-30 devnull if(ni > BLOCKSIZE)
684 76193d7c 2003-09-30 devnull ni = BLOCKSIZE;
685 522b0689 2003-09-30 devnull bufread(&f->b, p, genbuf, ni);
686 76193d7c 2003-09-30 devnull loginsert(addr2.f, addr2.r.p2, tmprstr(genbuf, ni)->s, ni);
687 76193d7c 2003-09-30 devnull }
688 76193d7c 2003-09-30 devnull addr2.f->ndot.r.p2 = addr2.r.p2+(f->dot.r.p2-f->dot.r.p1);
689 76193d7c 2003-09-30 devnull addr2.f->ndot.r.p1 = addr2.r.p2;
690 76193d7c 2003-09-30 devnull }
691 76193d7c 2003-09-30 devnull
692 76193d7c 2003-09-30 devnull void
693 76193d7c 2003-09-30 devnull move(File *f, Address addr2)
694 76193d7c 2003-09-30 devnull {
695 76193d7c 2003-09-30 devnull if(addr.r.p2 <= addr2.r.p2){
696 76193d7c 2003-09-30 devnull logdelete(f, addr.r.p1, addr.r.p2);
697 76193d7c 2003-09-30 devnull copy(f, addr2);
698 76193d7c 2003-09-30 devnull }else if(addr.r.p1 >= addr2.r.p2){
699 76193d7c 2003-09-30 devnull copy(f, addr2);
700 76193d7c 2003-09-30 devnull logdelete(f, addr.r.p1, addr.r.p2);
701 76193d7c 2003-09-30 devnull }else
702 76193d7c 2003-09-30 devnull error(Eoverlap);
703 76193d7c 2003-09-30 devnull }
704 76193d7c 2003-09-30 devnull
705 76193d7c 2003-09-30 devnull Posn
706 76193d7c 2003-09-30 devnull nlcount(File *f, Posn p0, Posn p1)
707 76193d7c 2003-09-30 devnull {
708 76193d7c 2003-09-30 devnull Posn nl = 0;
709 76193d7c 2003-09-30 devnull
710 76193d7c 2003-09-30 devnull while(p0 < p1)
711 76193d7c 2003-09-30 devnull if(filereadc(f, p0++)=='\n')
712 76193d7c 2003-09-30 devnull nl++;
713 76193d7c 2003-09-30 devnull return nl;
714 76193d7c 2003-09-30 devnull }
715 76193d7c 2003-09-30 devnull
716 76193d7c 2003-09-30 devnull void
717 76193d7c 2003-09-30 devnull printposn(File *f, int charsonly)
718 76193d7c 2003-09-30 devnull {
719 76193d7c 2003-09-30 devnull Posn l1, l2;
720 76193d7c 2003-09-30 devnull
721 76193d7c 2003-09-30 devnull if(!charsonly){
722 76193d7c 2003-09-30 devnull l1 = 1+nlcount(f, (Posn)0, addr.r.p1);
723 76193d7c 2003-09-30 devnull l2 = l1+nlcount(f, addr.r.p1, addr.r.p2);
724 76193d7c 2003-09-30 devnull /* check if addr ends with '\n' */
725 76193d7c 2003-09-30 devnull if(addr.r.p2>0 && addr.r.p2>addr.r.p1 && filereadc(f, addr.r.p2-1)=='\n')
726 76193d7c 2003-09-30 devnull --l2;
727 76193d7c 2003-09-30 devnull dprint("%lud", l1);
728 76193d7c 2003-09-30 devnull if(l2 != l1)
729 76193d7c 2003-09-30 devnull dprint(",%lud", l2);
730 76193d7c 2003-09-30 devnull dprint("; ");
731 76193d7c 2003-09-30 devnull }
732 76193d7c 2003-09-30 devnull dprint("#%lud", addr.r.p1);
733 76193d7c 2003-09-30 devnull if(addr.r.p2 != addr.r.p1)
734 76193d7c 2003-09-30 devnull dprint(",#%lud", addr.r.p2);
735 76193d7c 2003-09-30 devnull dprint("\n");
736 76193d7c 2003-09-30 devnull }
737 76193d7c 2003-09-30 devnull
738 76193d7c 2003-09-30 devnull void
739 76193d7c 2003-09-30 devnull settempfile(void)
740 76193d7c 2003-09-30 devnull {
741 76193d7c 2003-09-30 devnull if(tempfile.nalloc < file.nused){
742 76193d7c 2003-09-30 devnull free(tempfile.listptr);
743 76193d7c 2003-09-30 devnull tempfile.listptr = emalloc(sizeof(*tempfile.filepptr)*file.nused);
744 76193d7c 2003-09-30 devnull tempfile.nalloc = file.nused;
745 76193d7c 2003-09-30 devnull }
746 76193d7c 2003-09-30 devnull tempfile.nused = file.nused;
747 76193d7c 2003-09-30 devnull memmove(&tempfile.filepptr[0], &file.filepptr[0], file.nused*sizeof(File*));
748 76193d7c 2003-09-30 devnull }